diff --git a/xos/Makefile.service b/xos/Makefile.service
new file mode 100755
index 0000000..9fb96f4
--- /dev/null
+++ b/xos/Makefile.service
@@ -0,0 +1,18 @@
+# Replace the line below with the location of xosgen
+PREFIX=.
+XOSGEN=$(PREFIX)/tool/xosgen
+
+DJANGO_TARGET=$(PREFIX)/targets/service.xtarget
+XPROTOS_TMP := $(shell mktemp)
+
+xprotos = $(wildcard *.xproto)
+
+all: models.py
+
+models.py: $(xprotos)
+	$(XOSGEN) --attic attic --target $(DJANGO_TARGET) --output $@ $<
+
+.PHONY: all
+	
+clean:
+	rm -f models.py
diff --git a/xos/_DS_Store b/xos/_DS_Store
new file mode 100755
index 0000000..119fa17
--- /dev/null
+++ b/xos/_DS_Store
Binary files differ
diff --git a/xos/__init__.py b/xos/__init__.py
new file mode 100755
index 0000000..d4e8062
--- /dev/null
+++ b/xos/__init__.py
@@ -0,0 +1,16 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
diff --git a/xos/admin.py b/xos/admin.py
new file mode 100755
index 0000000..098b1ab
--- /dev/null
+++ b/xos/admin.py
@@ -0,0 +1,55 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# admin.py - vNaaSworkService Django Admin
+
+from core.admin import ReadOnlyAwareAdmin
+from core.admin import XOSBaseAdmin
+from django.contrib import admin
+from django import forms
+
+
+class XOSvNaaSBandwithProfileAdmin(XOSBaseAdmin):
+    verbose_name = "Bandwidth Profile"
+    list_display = ('cbs','ebs','cir','eir','name')
+
+    fields = ('cbs', 'ebs', 'cir', 'eir', 'name')
+
+class XOSvNaaSUNIAdmin(XOSBaseAdmin):
+    verbose_name = "User Network Interface"
+    list_display = ('tenant', 'vlanIds', 'cpe_id', 'latlng', 'name')
+    fields = ('tenant','vlanIds', 'cpe_id', 'latlng', 'name')
+
+class XOSvNaaSEnterpriseLocationAdmin(XOSBaseAdmin):
+    verbose_name = "Enterprise Location"
+    list_display = ('name', 'cord_site_ip', 'cord_site_port', 'cord_site_username', 'cord_site_password', 'cord_site_type')
+    fields = ('name', 'cord_site_ip', 'cord_site_port', 'cord_site_username', 'cord_site_password', 'cord_site_type')
+
+class XOSvNaaSOnosModelAdmin(XOSBaseAdmin):
+    verbose_name = "Open Network Operating System"
+    list_display = ('name', 'onos_ip', 'onos_port', 'onos_username', 'onos_password', 'onos_type')
+    fields = ('name', 'onos_ip', 'onos_port', 'onos_username', 'onos_password', 'onos_type')
+
+class XOSvNaaSELineAdmin(XOSBaseAdmin):
+    verbose_name = "Ethernet Virtual Private Line"
+    list_display = ('name', 'connect_point_1_id', 'connect_point_2_id', 'vlanids', 'cord_site_name', 'bwp')
+    fields = ('name', 'connect_point_1_id', 'connect_point_2_id', 'vlanids', 'cord_site_name', 'bwp')
+
+admin.site.register(XOSvNaaSBandwithProfile, XOSvNaaSBandwithProfileAdmin)
+admin.site.register(XOSvNaaSUNI, XOSvNaaSUNIAdmin)
+admin.site.register(XOSvNaaSEnterpriseLocation, XOSvNaaSEnterpriseLocationAdmin)
+admin.site.register(XOSvNaaSOnosModel, XOSvNaaSOnosModelAdmin)
+admin.site.register(XOSvNaaSELine, XOSvNaaSELineAdmin)
\ No newline at end of file
diff --git a/xos/attic/bandwidthprofile_model.py b/xos/attic/bandwidthprofile_model.py
new file mode 100755
index 0000000..db74626
--- /dev/null
+++ b/xos/attic/bandwidthprofile_model.py
@@ -0,0 +1,17 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+def __unicode__(self):  return u'%s' % (self.name)
diff --git a/xos/attic/eline_model.py b/xos/attic/eline_model.py
new file mode 100755
index 0000000..db74626
--- /dev/null
+++ b/xos/attic/eline_model.py
@@ -0,0 +1,17 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+def __unicode__(self):  return u'%s' % (self.name)
diff --git a/xos/attic/enterprisetenant_model.py b/xos/attic/enterprisetenant_model.py
new file mode 100755
index 0000000..db74626
--- /dev/null
+++ b/xos/attic/enterprisetenant_model.py
@@ -0,0 +1,17 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+def __unicode__(self):  return u'%s' % (self.name)
diff --git a/xos/attic/header.py b/xos/attic/header.py
new file mode 100755
index 0000000..449bd6b
--- /dev/null
+++ b/xos/attic/header.py
@@ -0,0 +1,27 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from django.db import models
+from django.db.models import *
+from core.models import Service
+from core.models import XOSBase
+from core.models import Site
+
+VNAAS_KIND = "vnaas"
+SERVICE_NAME = 'vnaas'
+SERVICE_NAME_ELINE_VERBOSE = 'E-Line Service'
+SERVICE_NAME_ELAN_VERBOSE = 'E-LAN Service'
+SERVICE_NAME_ETREE_VERBOSE = 'E-Tree Service'
+
diff --git a/xos/attic/transportnetowrk_model.py b/xos/attic/transportnetowrk_model.py
new file mode 100755
index 0000000..941aea2
--- /dev/null
+++ b/xos/attic/transportnetowrk_model.py
@@ -0,0 +1,16 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+def __unicode__(self):  return u'%s' % (self.name)
diff --git a/xos/attic/usernetworkinterface_model.py b/xos/attic/usernetworkinterface_model.py
new file mode 100755
index 0000000..e48251c
--- /dev/null
+++ b/xos/attic/usernetworkinterface_model.py
@@ -0,0 +1,36 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+def __unicode__(self):  return u'%s' % (self.name)
+
+def save(self, *args, **kwargs):
+
+    if self.latlng:
+        try:
+            latlng_value = getattr(self, 'latlng').strip()
+            if (latlng_value.startswith('[') and latlng_value.endswith(']') and latlng_value.index(',') > 0):
+                lat = latlng_value[1: latlng_value.index(',')].strip()
+                lng = latlng_value[latlng_value.index(',') + 1: len(latlng_value) - 1].strip()
+
+                # If lat and lng are not floats, the code below should result in an error.
+                lat_validation = float(lat)
+                lng_validation = float(lng)
+            else:
+                raise ValueError("The lat/lng value is not formatted correctly.")
+        except:
+            raise ValueError("The lat/lng value is not formatted correctly.")
+
+    super(UserNetworkInterface, self).save(*args, **kwargs)
diff --git a/xos/gui/.tmp/app.config.js b/xos/gui/.tmp/app.config.js
new file mode 100755
index 0000000..64a2ea1
--- /dev/null
+++ b/xos/gui/.tmp/app.config.js
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('vnaasgui')
+  .constant('AppConfig', {
+    apiEndpoint: '/xos/api',
+    websocketClient: '/',
+  });
diff --git a/xos/gui/.tmp/index.html b/xos/gui/.tmp/index.html
new file mode 100755
index 0000000..10ec110
--- /dev/null
+++ b/xos/gui/.tmp/index.html
@@ -0,0 +1,37 @@
+
+<!--
+Copyright 2017-present Open Networking Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+
+<!DOCTYPE html>
+<html lang="en" ng-app="vnaasgui">
+<head>
+  <meta charset="UTF-8">
+  <title>vNaaS GUI</title>
+  <link href="/xos/loader.css" rel="stylesheet">
+  <link href="/xos/app.css" rel="stylesheet">
+  <link href="./app/style/style.css" rel="stylesheet">
+</head>
+<body>
+  <div ui-view></div>
+  <script src="/xos/vendor.js"></script>
+  <script src="/xos/app.js"></script>
+  <script src="/xos/loader.js"></script>
+  <script src="/xos/app.config.js"></script>
+  <script src="/xos/style.config.js"></script>
+  <script src="/mapconstants.js"></script>
+<script type="text/javascript" src="index.js"></script></body>
+</html>
\ No newline at end of file
diff --git a/xos/gui/.tmp/index.js b/xos/gui/.tmp/index.js
new file mode 100755
index 0000000..667fbd8
--- /dev/null
+++ b/xos/gui/.tmp/index.js
@@ -0,0 +1,63551 @@
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId])
+/******/ 			return installedModules[moduleId].exports;
+/******/
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// identity function for calling harmory imports with the correct context
+/******/ 	__webpack_require__.i = function(value) { return value; };
+/******/
+/******/ 	// define getter function for harmory exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		Object.defineProperty(exports, name, {
+/******/ 			configurable: false,
+/******/ 			enumerable: true,
+/******/ 			get: getter
+/******/ 		});
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 16);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ function(module, exports, __webpack_require__) {
+
+__webpack_require__(10);
+module.exports = angular;
+
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+__webpack_require__(8);
+module.exports = 'ngCookies';
+
+
+/***/ },
+/* 2 */
+/***/ function(module, exports, __webpack_require__) {
+
+__webpack_require__(9);
+module.exports = 'ngResource';
+
+
+/***/ },
+/* 3 */
+/***/ function(module, exports, __webpack_require__) {
+
+/*!
+ * State-based routing for AngularJS
+ * @version v1.0.0-beta.1
+ * @link https://ui-router.github.io
+ * @license MIT License, http://www.opensource.org/licenses/MIT
+ */
+(function webpackUniversalModuleDefinition(root, factory) {
+	if(true)
+		module.exports = factory();
+	else if(typeof define === 'function' && define.amd)
+		define("angular-ui-router", [], factory);
+	else if(typeof exports === 'object')
+		exports["angular-ui-router"] = factory();
+	else
+		root["angular-ui-router"] = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId])
+/******/ 			return installedModules[moduleId].exports;
+/******/
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			exports: {},
+/******/ 			id: moduleId,
+/******/ 			loaded: false
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.loaded = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/**
+	 * Main entry point for angular 1.x build
+	 * @module ng1
+	 */
+	/** for typedoc */
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	__export(__webpack_require__(1));
+	__export(__webpack_require__(53));
+	__export(__webpack_require__(55));
+	__webpack_require__(58);
+	__webpack_require__(59);
+	__webpack_require__(60);
+	__webpack_require__(61);
+	Object.defineProperty(exports, "__esModule", { value: true });
+	exports.default = "ui.router";
+
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/** @module common */ /** */
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	__export(__webpack_require__(2));
+	__export(__webpack_require__(46));
+	__export(__webpack_require__(47));
+	__export(__webpack_require__(48));
+	__export(__webpack_require__(49));
+	__export(__webpack_require__(50));
+	__export(__webpack_require__(51));
+	__export(__webpack_require__(52));
+	__export(__webpack_require__(44));
+	var router_1 = __webpack_require__(26);
+	exports.UIRouter = router_1.UIRouter;
+
+
+/***/ },
+/* 2 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	/** @module common */ /** for typedoc */
+	__export(__webpack_require__(3));
+	__export(__webpack_require__(6));
+	__export(__webpack_require__(7));
+	__export(__webpack_require__(5));
+	__export(__webpack_require__(4));
+	__export(__webpack_require__(8));
+	__export(__webpack_require__(9));
+	__export(__webpack_require__(12));
+
+
+/***/ },
+/* 3 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/**
+	 * Random utility functions used in the UI-Router code
+	 *
+	 * @preferred @module common
+	 */ /** for typedoc */
+	"use strict";
+	var predicates_1 = __webpack_require__(4);
+	var hof_1 = __webpack_require__(5);
+	var coreservices_1 = __webpack_require__(6);
+	var w = typeof window === 'undefined' ? {} : window;
+	var angular = w.angular || {};
+	exports.fromJson = angular.fromJson || JSON.parse.bind(JSON);
+	exports.toJson = angular.toJson || JSON.stringify.bind(JSON);
+	exports.copy = angular.copy || _copy;
+	exports.forEach = angular.forEach || _forEach;
+	exports.extend = angular.extend || _extend;
+	exports.equals = angular.equals || _equals;
+	exports.identity = function (x) { return x; };
+	exports.noop = function () { return undefined; };
+	exports.abstractKey = 'abstract';
+	/**
+	 * Binds and copies functions onto an object
+	 *
+	 * Takes functions from the 'from' object, binds those functions to the _this object, and puts the bound functions
+	 * on the 'to' object.
+	 *
+	 * This example creates an new class instance whose functions are prebound to the new'd object.
+	 * @example
+	 * ```
+	 *
+	 * class Foo {
+	 *   constructor(data) {
+	 *     // Binds all functions from Foo.prototype to 'this',
+	 *     // then copies them to 'this'
+	 *     bindFunctions(Foo.prototype, this, this);
+	 *     this.data = data;
+	 *   }
+	 *
+	 *   log() {
+	 *     console.log(this.data);
+	 *   }
+	 * }
+	 *
+	 * let myFoo = new Foo([1,2,3]);
+	 * var logit = myFoo.log;
+	 * logit(); // logs [1, 2, 3] from the myFoo 'this' instance
+	 * ```
+	 *
+	 * This example creates a bound version of a service function, and copies it to another object
+	 * @example
+	 * ```
+	 *
+	 * var SomeService = {
+	 *   this.data = [3, 4, 5];
+	 *   this.log = function() {
+	 *     console.log(this.data);
+	 *   }
+	 * }
+	 *
+	 * // Constructor fn
+	 * function OtherThing() {
+	 *   // Binds all functions from SomeService to SomeService,
+	 *   // then copies them to 'this'
+	 *   bindFunctions(SomeService, this, SomeService);
+	 * }
+	 *
+	 * let myOtherThing = new OtherThing();
+	 * myOtherThing.log(); // logs [3, 4, 5] from SomeService's 'this'
+	 * ```
+	 *
+	 * @param from The object which contains the functions to be bound
+	 * @param to The object which will receive the bound functions
+	 * @param bindTo The object which the functions will be bound to
+	 * @param fnNames The function names which will be bound (Defaults to all the functions found on the 'from' object)
+	 */
+	function bindFunctions(from, to, bindTo, fnNames) {
+	    if (fnNames === void 0) { fnNames = Object.keys(from); }
+	    return fnNames.filter(function (name) { return typeof from[name] === 'function'; })
+	        .forEach(function (name) { return to[name] = from[name].bind(bindTo); });
+	}
+	exports.bindFunctions = bindFunctions;
+	/**
+	 * prototypal inheritance helper.
+	 * Creates a new object which has `parent` object as its prototype, and then copies the properties from `extra` onto it
+	 */
+	exports.inherit = function (parent, extra) {
+	    return exports.extend(new (exports.extend(function () { }, { prototype: parent }))(), extra);
+	};
+	/**
+	 * Given an arguments object, converts the arguments at index idx and above to an array.
+	 * This is similar to es6 rest parameters.
+	 *
+	 * Optionally, the argument at index idx may itself already be an array.
+	 *
+	 * For example,
+	 * given either:
+	 *        arguments = [ obj, "foo", "bar" ]
+	 * or:
+	 *        arguments = [ obj, ["foo", "bar"] ]
+	 * then:
+	 *        restArgs(arguments, 1) == ["foo", "bar"]
+	 *
+	 * This allows functions like pick() to be implemented such that it allows either a bunch
+	 * of string arguments (like es6 rest parameters), or a single array of strings:
+	 *
+	 * given:
+	 *        var obj = { foo: 1, bar: 2, baz: 3 };
+	 * then:
+	 *        pick(obj, "foo", "bar");   // returns { foo: 1, bar: 2 }
+	 *        pick(obj, ["foo", "bar"]); // returns { foo: 1, bar: 2 }
+	 */
+	var restArgs = function (args, idx) {
+	    if (idx === void 0) { idx = 0; }
+	    return Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(args, idx));
+	};
+	/** Given an array, returns true if the object is found in the array, (using indexOf) */
+	exports.inArray = function (array, obj) { return array.indexOf(obj) !== -1; };
+	/** Given an array, and an item, if the item is found in the array, it removes it (in-place).  The same array is returned */
+	exports.removeFrom = hof_1.curry(function (array, obj) {
+	    var idx = array.indexOf(obj);
+	    if (idx >= 0)
+	        array.splice(idx, 1);
+	    return array;
+	});
+	/**
+	 * Applies a set of defaults to an options object.  The options object is filtered
+	 * to only those properties of the objects in the defaultsList.
+	 * Earlier objects in the defaultsList take precedence when applying defaults.
+	 */
+	function defaults(opts) {
+	    if (opts === void 0) { opts = {}; }
+	    var defaultsList = [];
+	    for (var _i = 1; _i < arguments.length; _i++) {
+	        defaultsList[_i - 1] = arguments[_i];
+	    }
+	    var defaults = merge.apply(null, [{}].concat(defaultsList));
+	    return exports.extend({}, defaults, pick(opts || {}, Object.keys(defaults)));
+	}
+	exports.defaults = defaults;
+	/**
+	 * Merges properties from the list of objects to the destination object.
+	 * If a property already exists in the destination object, then it is not overwritten.
+	 */
+	function merge(dst) {
+	    var objs = [];
+	    for (var _i = 1; _i < arguments.length; _i++) {
+	        objs[_i - 1] = arguments[_i];
+	    }
+	    exports.forEach(objs, function (obj) {
+	        exports.forEach(obj, function (value, key) {
+	            if (!dst.hasOwnProperty(key))
+	                dst[key] = value;
+	        });
+	    });
+	    return dst;
+	}
+	exports.merge = merge;
+	/** Reduce function that merges each element of the list into a single object, using extend */
+	exports.mergeR = function (memo, item) { return exports.extend(memo, item); };
+	/**
+	 * Finds the common ancestor path between two states.
+	 *
+	 * @param {Object} first The first state.
+	 * @param {Object} second The second state.
+	 * @return {Array} Returns an array of state names in descending order, not including the root.
+	 */
+	function ancestors(first, second) {
+	    var path = [];
+	    for (var n in first.path) {
+	        if (first.path[n] !== second.path[n])
+	            break;
+	        path.push(first.path[n]);
+	    }
+	    return path;
+	}
+	exports.ancestors = ancestors;
+	/**
+	 * Performs a non-strict comparison of the subset of two objects, defined by a list of keys.
+	 *
+	 * @param {Object} a The first object.
+	 * @param {Object} b The second object.
+	 * @param {Array} keys The list of keys within each object to compare. If the list is empty or not specified,
+	 *                     it defaults to the list of keys in `a`.
+	 * @return {Boolean} Returns `true` if the keys match, otherwise `false`.
+	 */
+	function equalForKeys(a, b, keys) {
+	    if (keys === void 0) { keys = Object.keys(a); }
+	    for (var i = 0; i < keys.length; i++) {
+	        var k = keys[i];
+	        if (a[k] != b[k])
+	            return false; // Not '===', values aren't necessarily normalized
+	    }
+	    return true;
+	}
+	exports.equalForKeys = equalForKeys;
+	function pickOmitImpl(predicate, obj) {
+	    var objCopy = {}, keys = restArgs(arguments, 2);
+	    for (var key in obj) {
+	        if (predicate(keys, key))
+	            objCopy[key] = obj[key];
+	    }
+	    return objCopy;
+	}
+	/** Return a copy of the object only containing the whitelisted properties. */
+	function pick(obj) { return pickOmitImpl.apply(null, [exports.inArray].concat(restArgs(arguments))); }
+	exports.pick = pick;
+	/** Return a copy of the object omitting the blacklisted properties. */
+	function omit(obj) { return pickOmitImpl.apply(null, [hof_1.not(exports.inArray)].concat(restArgs(arguments))); }
+	exports.omit = omit;
+	/**
+	 * Maps an array, or object to a property (by name)
+	 */
+	function pluck(collection, propName) {
+	    return map(collection, hof_1.prop(propName));
+	}
+	exports.pluck = pluck;
+	/** Filters an Array or an Object's properties based on a predicate */
+	function filter(collection, callback) {
+	    var arr = predicates_1.isArray(collection), result = arr ? [] : {};
+	    var accept = arr ? function (x) { return result.push(x); } : function (x, key) { return result[key] = x; };
+	    exports.forEach(collection, function (item, i) {
+	        if (callback(item, i))
+	            accept(item, i);
+	    });
+	    return result;
+	}
+	exports.filter = filter;
+	/** Finds an object from an array, or a property of an object, that matches a predicate */
+	function find(collection, callback) {
+	    var result;
+	    exports.forEach(collection, function (item, i) {
+	        if (result)
+	            return;
+	        if (callback(item, i))
+	            result = item;
+	    });
+	    return result;
+	}
+	exports.find = find;
+	/** Given an object, returns a new object, where each property is transformed by the callback function */
+	exports.mapObj = map;
+	/** Maps an array or object properties using a callback function */
+	function map(collection, callback) {
+	    var result = predicates_1.isArray(collection) ? [] : {};
+	    exports.forEach(collection, function (item, i) { return result[i] = callback(item, i); });
+	    return result;
+	}
+	exports.map = map;
+	/**
+	 * Given an object, return its enumerable property values
+	 *
+	 * @example
+	 * ```
+	 *
+	 * let foo = { a: 1, b: 2, c: 3 }
+	 * let vals = values(foo); // [ 1, 2, 3 ]
+	 * ```
+	 */
+	exports.values = function (obj) { return Object.keys(obj).map(function (key) { return obj[key]; }); };
+	/**
+	 * Reduce function that returns true if all of the values are truthy.
+	 *
+	 * @example
+	 * ```
+	 *
+	 * let vals = [ 1, true, {}, "hello world"];
+	 * vals.reduce(allTrueR, true); // true
+	 *
+	 * vals.push(0);
+	 * vals.reduce(allTrueR, true); // false
+	 * ```
+	 */
+	exports.allTrueR = function (memo, elem) { return memo && elem; };
+	/**
+	 * Reduce function that returns true if any of the values are truthy.
+	 *
+	 *  * @example
+	 * ```
+	 *
+	 * let vals = [ 0, null, undefined ];
+	 * vals.reduce(anyTrueR, true); // false
+	 *
+	 * vals.push("hello world");
+	 * vals.reduce(anyTrueR, true); // true
+	 * ```
+	 */
+	exports.anyTrueR = function (memo, elem) { return memo || elem; };
+	/**
+	 * Reduce function which un-nests a single level of arrays
+	 * @example
+	 * ```
+	 *
+	 * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
+	 * input.reduce(unnestR, []) // [ "a", "b", "c", "d", [ "double, "nested" ] ]
+	 * ```
+	 */
+	exports.unnestR = function (memo, elem) { return memo.concat(elem); };
+	/**
+	 * Reduce function which recursively un-nests all arrays
+	 *
+	 * @example
+	 * ```
+	 *
+	 * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
+	 * input.reduce(unnestR, []) // [ "a", "b", "c", "d", "double, "nested" ]
+	 * ```
+	 */
+	exports.flattenR = function (memo, elem) { return predicates_1.isArray(elem) ? memo.concat(elem.reduce(exports.flattenR, [])) : pushR(memo, elem); };
+	/** Reduce function that pushes an object to an array, then returns the array.  Mostly just for [[flattenR]] */
+	function pushR(arr, obj) { arr.push(obj); return arr; }
+	exports.pushR = pushR;
+	/** Reduce function that filters out duplicates */
+	exports.uniqR = function (acc, token) { return exports.inArray(acc, token) ? acc : pushR(acc, token); };
+	/**
+	 * Return a new array with a single level of arrays unnested.
+	 *
+	 * @example
+	 * ```
+	 *
+	 * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
+	 * unnest(input) // [ "a", "b", "c", "d", [ "double, "nested" ] ]
+	 * ```
+	 */
+	exports.unnest = function (arr) { return arr.reduce(exports.unnestR, []); };
+	/**
+	 * Return a completely flattened version of an array.
+	 *
+	 * @example
+	 * ```
+	 *
+	 * let input = [ [ "a", "b" ], [ "c", "d" ], [ [ "double", "nested" ] ] ];
+	 * flatten(input) // [ "a", "b", "c", "d", "double, "nested" ]
+	 * ```
+	 */
+	exports.flatten = function (arr) { return arr.reduce(exports.flattenR, []); };
+	/**
+	 * Given a .filter Predicate, builds a .filter Predicate which throws an error if any elements do not pass.
+	 * @example
+	 * ```
+	 *
+	 * let isNumber = (obj) => typeof(obj) === 'number';
+	 * let allNumbers = [ 1, 2, 3, 4, 5 ];
+	 * allNumbers.filter(assertPredicate(isNumber)); //OK
+	 *
+	 * let oneString = [ 1, 2, 3, 4, "5" ];
+	 * oneString.filter(assertPredicate(isNumber, "Not all numbers")); // throws Error(""Not all numbers"");
+	 * ```
+	 */
+	function assertPredicate(predicate, errMsg) {
+	    if (errMsg === void 0) { errMsg = "assert failure"; }
+	    return function (obj) {
+	        if (!predicate(obj)) {
+	            throw new Error(predicates_1.isFunction(errMsg) ? errMsg(obj) : errMsg);
+	        }
+	        return true;
+	    };
+	}
+	exports.assertPredicate = assertPredicate;
+	/**
+	 * Like _.pairs: Given an object, returns an array of key/value pairs
+	 *
+	 * @example
+	 * ```
+	 *
+	 * pairs({ foo: "FOO", bar: "BAR }) // [ [ "foo", "FOO" ], [ "bar": "BAR" ] ]
+	 * ```
+	 */
+	exports.pairs = function (object) { return Object.keys(object).map(function (key) { return [key, object[key]]; }); };
+	/**
+	 * Given two or more parallel arrays, returns an array of tuples where
+	 * each tuple is composed of [ a[i], b[i], ... z[i] ]
+	 *
+	 * @example
+	 * ```
+	 *
+	 * let foo = [ 0, 2, 4, 6 ];
+	 * let bar = [ 1, 3, 5, 7 ];
+	 * let baz = [ 10, 30, 50, 70 ];
+	 * arrayTuples(foo, bar);       // [ [0, 1], [2, 3], [4, 5], [6, 7] ]
+	 * arrayTuples(foo, bar, baz);  // [ [0, 1, 10], [2, 3, 30], [4, 5, 50], [6, 7, 70] ]
+	 * ```
+	 */
+	function arrayTuples() {
+	    var arrayArgs = [];
+	    for (var _i = 0; _i < arguments.length; _i++) {
+	        arrayArgs[_i - 0] = arguments[_i];
+	    }
+	    if (arrayArgs.length === 0)
+	        return [];
+	    var length = arrayArgs.reduce(function (min, arr) { return Math.min(arr.length, min); }, 9007199254740991); // aka 2^53 − 1 aka Number.MAX_SAFE_INTEGER
+	    return Array.apply(null, Array(length)).map(function (ignored, idx) { return arrayArgs.map(function (arr) { return arr[idx]; }); });
+	}
+	exports.arrayTuples = arrayTuples;
+	/**
+	 * Reduce function which builds an object from an array of [key, value] pairs.
+	 *
+	 * Each iteration sets the key/val pair on the memo object, then returns the memo for the next iteration.
+	 *
+	 * Each keyValueTuple should be an array with values [ key: string, value: any ]
+	 *
+	 * @example
+	 * ```
+	 *
+	 * var pairs = [ ["fookey", "fooval"], ["barkey", "barval"] ]
+	 *
+	 * var pairsToObj = pairs.reduce((memo, pair) => applyPairs(memo, pair), {})
+	 * // pairsToObj == { fookey: "fooval", barkey: "barval" }
+	 *
+	 * // Or, more simply:
+	 * var pairsToObj = pairs.reduce(applyPairs, {})
+	 * // pairsToObj == { fookey: "fooval", barkey: "barval" }
+	 * ```
+	 */
+	function applyPairs(memo, keyValTuple) {
+	    var key, value;
+	    if (predicates_1.isArray(keyValTuple))
+	        key = keyValTuple[0], value = keyValTuple[1];
+	    if (!predicates_1.isString(key))
+	        throw new Error("invalid parameters to applyPairs");
+	    memo[key] = value;
+	    return memo;
+	}
+	exports.applyPairs = applyPairs;
+	/** Get the last element of an array */
+	function tail(arr) {
+	    return arr.length && arr[arr.length - 1] || undefined;
+	}
+	exports.tail = tail;
+	/**
+	 * shallow copy from src to dest
+	 *
+	 * note: This is a shallow copy, while angular.copy is a deep copy.
+	 * ui-router uses `copy` only to make copies of state parameters.
+	 */
+	function _copy(src, dest) {
+	    if (dest)
+	        Object.keys(dest).forEach(function (key) { return delete dest[key]; });
+	    if (!dest)
+	        dest = {};
+	    return exports.extend(dest, src);
+	}
+	function _forEach(obj, cb, _this) {
+	    if (predicates_1.isArray(obj))
+	        return obj.forEach(cb, _this);
+	    Object.keys(obj).forEach(function (key) { return cb(obj[key], key); });
+	}
+	function _copyProps(to, from) { Object.keys(from).forEach(function (key) { return to[key] = from[key]; }); return to; }
+	function _extend(toObj, rest) {
+	    return restArgs(arguments, 1).filter(exports.identity).reduce(_copyProps, toObj);
+	}
+	function _equals(o1, o2) {
+	    if (o1 === o2)
+	        return true;
+	    if (o1 === null || o2 === null)
+	        return false;
+	    if (o1 !== o1 && o2 !== o2)
+	        return true; // NaN === NaN
+	    var t1 = typeof o1, t2 = typeof o2;
+	    if (t1 !== t2 || t1 !== 'object')
+	        return false;
+	    var tup = [o1, o2];
+	    if (hof_1.all(predicates_1.isArray)(tup))
+	        return _arraysEq(o1, o2);
+	    if (hof_1.all(predicates_1.isDate)(tup))
+	        return o1.getTime() === o2.getTime();
+	    if (hof_1.all(predicates_1.isRegExp)(tup))
+	        return o1.toString() === o2.toString();
+	    if (hof_1.all(predicates_1.isFunction)(tup))
+	        return true; // meh
+	    var predicates = [predicates_1.isFunction, predicates_1.isArray, predicates_1.isDate, predicates_1.isRegExp];
+	    if (predicates.map(hof_1.any).reduce(function (b, fn) { return b || !!fn(tup); }, false))
+	        return false;
+	    var key, keys = {};
+	    for (key in o1) {
+	        if (!_equals(o1[key], o2[key]))
+	            return false;
+	        keys[key] = true;
+	    }
+	    for (key in o2) {
+	        if (!keys[key])
+	            return false;
+	    }
+	    return true;
+	}
+	function _arraysEq(a1, a2) {
+	    if (a1.length !== a2.length)
+	        return false;
+	    return arrayTuples(a1, a2).reduce(function (b, t) { return b && _equals(t[0], t[1]); }, true);
+	}
+	// issue #2676
+	exports.silenceUncaughtInPromise = function (promise) {
+	    return promise.catch(function (e) { return 0; }) && promise;
+	};
+	exports.silentRejection = function (error) {
+	    return exports.silenceUncaughtInPromise(coreservices_1.services.$q.reject(error));
+	};
+
+
+/***/ },
+/* 4 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** Predicates @module common_predicates */ /** */
+	var hof_1 = __webpack_require__(5);
+	var toStr = Object.prototype.toString;
+	var tis = function (t) { return function (x) { return typeof (x) === t; }; };
+	exports.isUndefined = tis('undefined');
+	exports.isDefined = hof_1.not(exports.isUndefined);
+	exports.isNull = function (o) { return o === null; };
+	exports.isFunction = tis('function');
+	exports.isNumber = tis('number');
+	exports.isString = tis('string');
+	exports.isObject = function (x) { return x !== null && typeof x === 'object'; };
+	exports.isArray = Array.isArray;
+	exports.isDate = (function (x) { return toStr.call(x) === '[object Date]'; });
+	exports.isRegExp = (function (x) { return toStr.call(x) === '[object RegExp]'; });
+	/**
+	 * Predicate which checks if a value is injectable
+	 *
+	 * A value is "injectable" if it is a function, or if it is an ng1 array-notation-style array
+	 * where all the elements in the array are Strings, except the last one, which is a Function
+	 */
+	function isInjectable(val) {
+	    if (exports.isArray(val) && val.length) {
+	        var head = val.slice(0, -1), tail = val.slice(-1);
+	        return !(head.filter(hof_1.not(exports.isString)).length || tail.filter(hof_1.not(exports.isFunction)).length);
+	    }
+	    return exports.isFunction(val);
+	}
+	exports.isInjectable = isInjectable;
+	/**
+	 * Predicate which checks if a value looks like a Promise
+	 *
+	 * It is probably a Promise if it's an object, and it has a `then` property which is a Function
+	 */
+	exports.isPromise = hof_1.and(exports.isObject, hof_1.pipe(hof_1.prop('then'), exports.isFunction));
+
+
+/***/ },
+/* 5 */
+/***/ function(module, exports) {
+
+	/**
+	 * Higher order functions
+	 *
+	 * @module common_hof
+	 */ /** */
+	"use strict";
+	/**
+	 * Returns a new function for [Partial Application](https://en.wikipedia.org/wiki/Partial_application) of the original function.
+	 *
+	 * Given a function with N parameters, returns a new function that supports partial application.
+	 * The new function accepts anywhere from 1 to N parameters.  When that function is called with M parameters,
+	 * where M is less than N, it returns a new function that accepts the remaining parameters.  It continues to
+	 * accept more parameters until all N parameters have been supplied.
+	 *
+	 *
+	 * This contrived example uses a partially applied function as an predicate, which returns true
+	 * if an object is found in both arrays.
+	 * @example
+	 * ```
+	 * // returns true if an object is in both of the two arrays
+	 * function inBoth(array1, array2, object) {
+	 *   return array1.indexOf(object) !== -1 &&
+	 *          array2.indexOf(object) !== 1;
+	 * }
+	 * let obj1, obj2, obj3, obj4, obj5, obj6, obj7
+	 * let foos = [obj1, obj3]
+	 * let bars = [obj3, obj4, obj5]
+	 *
+	 * // A curried "copy" of inBoth
+	 * let curriedInBoth = curry(inBoth);
+	 * // Partially apply both the array1 and array2
+	 * let inFoosAndBars = curriedInBoth(foos, bars);
+	 *
+	 * // Supply the final argument; since all arguments are
+	 * // supplied, the original inBoth function is then called.
+	 * let obj1InBoth = inFoosAndBars(obj1); // false
+	 *
+	 * // Use the inFoosAndBars as a predicate.
+	 * // Filter, on each iteration, supplies the final argument
+	 * let allObjs = [ obj1, obj2, obj3, obj4, obj5, obj6, obj7 ];
+	 * let foundInBoth = allObjs.filter(inFoosAndBars); // [ obj3 ]
+	 *
+	 * ```
+	 *
+	 * Stolen from: http://stackoverflow.com/questions/4394747/javascript-curry-function
+	 *
+	 * @param fn
+	 * @returns {*|function(): (*|any)}
+	 */
+	function curry(fn) {
+	    var initial_args = [].slice.apply(arguments, [1]);
+	    var func_args_length = fn.length;
+	    function curried(args) {
+	        if (args.length >= func_args_length)
+	            return fn.apply(null, args);
+	        return function () {
+	            return curried(args.concat([].slice.apply(arguments)));
+	        };
+	    }
+	    return curried(initial_args);
+	}
+	exports.curry = curry;
+	/**
+	 * Given a varargs list of functions, returns a function that composes the argument functions, right-to-left
+	 * given: f(x), g(x), h(x)
+	 * let composed = compose(f,g,h)
+	 * then, composed is: f(g(h(x)))
+	 */
+	function compose() {
+	    var args = arguments;
+	    var start = args.length - 1;
+	    return function () {
+	        var i = start, result = args[start].apply(this, arguments);
+	        while (i--)
+	            result = args[i].call(this, result);
+	        return result;
+	    };
+	}
+	exports.compose = compose;
+	/**
+	 * Given a varargs list of functions, returns a function that is composes the argument functions, left-to-right
+	 * given: f(x), g(x), h(x)
+	 * let piped = pipe(f,g,h);
+	 * then, piped is: h(g(f(x)))
+	 */
+	function pipe() {
+	    var funcs = [];
+	    for (var _i = 0; _i < arguments.length; _i++) {
+	        funcs[_i - 0] = arguments[_i];
+	    }
+	    return compose.apply(null, [].slice.call(arguments).reverse());
+	}
+	exports.pipe = pipe;
+	/**
+	 * Given a property name, returns a function that returns that property from an object
+	 * let obj = { foo: 1, name: "blarg" };
+	 * let getName = prop("name");
+	 * getName(obj) === "blarg"
+	 */
+	exports.prop = function (name) { return function (obj) { return obj && obj[name]; }; };
+	/**
+	 * Given a property name and a value, returns a function that returns a boolean based on whether
+	 * the passed object has a property that matches the value
+	 * let obj = { foo: 1, name: "blarg" };
+	 * let getName = propEq("name", "blarg");
+	 * getName(obj) === true
+	 */
+	exports.propEq = curry(function (name, val, obj) { return obj && obj[name] === val; });
+	/**
+	 * Given a dotted property name, returns a function that returns a nested property from an object, or undefined
+	 * let obj = { id: 1, nestedObj: { foo: 1, name: "blarg" }, };
+	 * let getName = prop("nestedObj.name");
+	 * getName(obj) === "blarg"
+	 * let propNotFound = prop("this.property.doesnt.exist");
+	 * propNotFound(obj) === undefined
+	 */
+	exports.parse = function (name) { return pipe.apply(null, name.split(".").map(exports.prop)); };
+	/**
+	 * Given a function that returns a truthy or falsey value, returns a
+	 * function that returns the opposite (falsey or truthy) value given the same inputs
+	 */
+	exports.not = function (fn) { return function () {
+	    var args = [];
+	    for (var _i = 0; _i < arguments.length; _i++) {
+	        args[_i - 0] = arguments[_i];
+	    }
+	    return !fn.apply(null, args);
+	}; };
+	/**
+	 * Given two functions that return truthy or falsey values, returns a function that returns truthy
+	 * if both functions return truthy for the given arguments
+	 */
+	function and(fn1, fn2) {
+	    return function () {
+	        var args = [];
+	        for (var _i = 0; _i < arguments.length; _i++) {
+	            args[_i - 0] = arguments[_i];
+	        }
+	        return fn1.apply(null, args) && fn2.apply(null, args);
+	    };
+	}
+	exports.and = and;
+	/**
+	 * Given two functions that return truthy or falsey values, returns a function that returns truthy
+	 * if at least one of the functions returns truthy for the given arguments
+	 */
+	function or(fn1, fn2) {
+	    return function () {
+	        var args = [];
+	        for (var _i = 0; _i < arguments.length; _i++) {
+	            args[_i - 0] = arguments[_i];
+	        }
+	        return fn1.apply(null, args) || fn2.apply(null, args);
+	    };
+	}
+	exports.or = or;
+	/**
+	 * Check if all the elements of an array match a predicate function
+	 *
+	 * @param fn1 a predicate function `fn1`
+	 * @returns a function which takes an array and returns true if `fn1` is true for all elements of the array
+	 */
+	exports.all = function (fn1) { return function (arr) { return arr.reduce(function (b, x) { return b && !!fn1(x); }, true); }; };
+	exports.any = function (fn1) { return function (arr) { return arr.reduce(function (b, x) { return b || !!fn1(x); }, false); }; };
+	exports.none = exports.not(exports.any);
+	/** Given a class, returns a Predicate function that returns true if the object is of that class */
+	exports.is = function (ctor) { return function (obj) { return (obj != null && obj.constructor === ctor || obj instanceof ctor); }; };
+	/** Given a value, returns a Predicate function that returns true if another value is === equal to the original value */
+	exports.eq = function (val) { return function (other) { return val === other; }; };
+	/** Given a value, returns a function which returns the value */
+	exports.val = function (v) { return function () { return v; }; };
+	function invoke(fnName, args) {
+	    return function (obj) { return obj[fnName].apply(obj, args); };
+	}
+	exports.invoke = invoke;
+	/**
+	 * Sorta like Pattern Matching (a functional programming conditional construct)
+	 *
+	 * See http://c2.com/cgi/wiki?PatternMatching
+	 *
+	 * This is a conditional construct which allows a series of predicates and output functions
+	 * to be checked and then applied.  Each predicate receives the input.  If the predicate
+	 * returns truthy, then its matching output function (mapping function) is provided with
+	 * the input and, then the result is returned.
+	 *
+	 * Each combination (2-tuple) of predicate + output function should be placed in an array
+	 * of size 2: [ predicate, mapFn ]
+	 *
+	 * These 2-tuples should be put in an outer array.
+	 *
+	 * @example
+	 * ```
+	 *
+	 * // Here's a 2-tuple where the first element is the isString predicate
+	 * // and the second element is a function that returns a description of the input
+	 * let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ];
+	 *
+	 * // Second tuple: predicate "isNumber", mapfn returns a description
+	 * let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ];
+	 *
+	 * let third = [ (input) => input === null,  (input) => `Oh, null...` ];
+	 *
+	 * let fourth = [ (input) => input === undefined,  (input) => `notdefined` ];
+	 *
+	 * let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]);
+	 *
+	 * console.log(descriptionOf(undefined)); // 'notdefined'
+	 * console.log(descriptionOf(55)); // '(55) That's a number!'
+	 * console.log(descriptionOf("foo")); // 'Here's your string foo'
+	 * ```
+	 *
+	 * @param struct A 2D array.  Each element of the array should be an array, a 2-tuple,
+	 * with a Predicate and a mapping/output function
+	 * @returns {function(any): *}
+	 */
+	function pattern(struct) {
+	    return function (x) {
+	        for (var i = 0; i < struct.length; i++) {
+	            if (struct[i][0](x))
+	                return struct[i][1](x);
+	        }
+	    };
+	}
+	exports.pattern = pattern;
+
+
+/***/ },
+/* 6 */
+/***/ function(module, exports) {
+
+	/**
+	 * This module is a stub for core services such as Dependency Injection or Browser Location.
+	 * Core services may be implemented by a specific framework, such as ng1 or ng2, or be pure javascript.
+	 *
+	 * @module common
+	 */
+	"use strict";
+	/** for typedoc */
+	//import {IQService} from "angular";
+	//import {IInjectorService} from "angular";
+	var notImplemented = function (fnname) { return function () {
+	    throw new Error(fnname + "(): No coreservices implementation for UI-Router is loaded. You should include one of: ['angular1.js']");
+	}; };
+	var services = {
+	    $q: undefined,
+	    $injector: undefined,
+	    location: {},
+	    locationConfig: {},
+	    template: {}
+	};
+	exports.services = services;
+	["replace", "url", "path", "search", "hash", "onChange"]
+	    .forEach(function (key) { return services.location[key] = notImplemented(key); });
+	["port", "protocol", "host", "baseHref", "html5Mode", "hashPrefix"]
+	    .forEach(function (key) { return services.locationConfig[key] = notImplemented(key); });
+
+
+/***/ },
+/* 7 */
+/***/ function(module, exports) {
+
+	"use strict";
+	/** @module common */
+	/**
+	 * Matches state names using glob-like patterns.
+	 *
+	 * See: [[StateService.includes]]
+	 */
+	var Glob = (function () {
+	    function Glob(text) {
+	        this.text = text;
+	        this.glob = text.split('.');
+	    }
+	    Glob.prototype.matches = function (name) {
+	        var segments = name.split('.');
+	        // match single stars
+	        for (var i = 0, l = this.glob.length; i < l; i++) {
+	            if (this.glob[i] === '*')
+	                segments[i] = '*';
+	        }
+	        // match greedy starts
+	        if (this.glob[0] === '**') {
+	            segments = segments.slice(segments.indexOf(this.glob[1]));
+	            segments.unshift('**');
+	        }
+	        // match greedy ends
+	        if (this.glob[this.glob.length - 1] === '**') {
+	            segments.splice(segments.indexOf(this.glob[this.glob.length - 2]) + 1, Number.MAX_VALUE);
+	            segments.push('**');
+	        }
+	        if (this.glob.length != segments.length)
+	            return false;
+	        return segments.join('') === this.glob.join('');
+	    };
+	    Glob.is = function (text) {
+	        return text.indexOf('*') > -1;
+	    };
+	    Glob.fromString = function (text) {
+	        if (!this.is(text))
+	            return null;
+	        return new Glob(text);
+	    };
+	    return Glob;
+	}());
+	exports.Glob = Glob;
+
+
+/***/ },
+/* 8 */
+/***/ function(module, exports) {
+
+	/** @module common */ /** for typedoc */
+	"use strict";
+	var Queue = (function () {
+	    function Queue(_items, _limit) {
+	        if (_items === void 0) { _items = []; }
+	        if (_limit === void 0) { _limit = null; }
+	        this._items = _items;
+	        this._limit = _limit;
+	    }
+	    Queue.prototype.enqueue = function (item) {
+	        var items = this._items;
+	        items.push(item);
+	        if (this._limit && items.length > this._limit)
+	            items.shift();
+	        return item;
+	    };
+	    Queue.prototype.dequeue = function () {
+	        if (this.size())
+	            return this._items.splice(0, 1)[0];
+	    };
+	    Queue.prototype.clear = function () {
+	        var current = this._items;
+	        this._items = [];
+	        return current;
+	    };
+	    Queue.prototype.size = function () {
+	        return this._items.length;
+	    };
+	    Queue.prototype.remove = function (item) {
+	        var idx = this._items.indexOf(item);
+	        return idx > -1 && this._items.splice(idx, 1)[0];
+	    };
+	    Queue.prototype.peekTail = function () {
+	        return this._items[this._items.length - 1];
+	    };
+	    Queue.prototype.peekHead = function () {
+	        if (this.size())
+	            return this._items[0];
+	    };
+	    return Queue;
+	}());
+	exports.Queue = Queue;
+
+
+/***/ },
+/* 9 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/** @module common_strings */ /** */
+	"use strict";
+	var predicates_1 = __webpack_require__(4);
+	var rejectFactory_1 = __webpack_require__(10);
+	var common_1 = __webpack_require__(3);
+	var hof_1 = __webpack_require__(5);
+	var transition_1 = __webpack_require__(11);
+	var resolvable_1 = __webpack_require__(19);
+	/**
+	 * Returns a string shortened to a maximum length
+	 *
+	 * If the string is already less than the `max` length, return the string.
+	 * Else return the string, shortened to `max - 3` and append three dots ("...").
+	 *
+	 * @param max the maximum length of the string to return
+	 * @param str the input string
+	 */
+	function maxLength(max, str) {
+	    if (str.length <= max)
+	        return str;
+	    return str.substr(0, max - 3) + "...";
+	}
+	exports.maxLength = maxLength;
+	/**
+	 * Returns a string, with spaces added to the end, up to a desired str length
+	 *
+	 * If the string is already longer than the desired length, return the string.
+	 * Else returns the string, with extra spaces on the end, such that it reaches `length` characters.
+	 *
+	 * @param length the desired length of the string to return
+	 * @param str the input string
+	 */
+	function padString(length, str) {
+	    while (str.length < length)
+	        str += " ";
+	    return str;
+	}
+	exports.padString = padString;
+	function kebobString(camelCase) {
+	    return camelCase
+	        .replace(/^([A-Z])/, function ($1) { return $1.toLowerCase(); }) // replace first char
+	        .replace(/([A-Z])/g, function ($1) { return "-" + $1.toLowerCase(); }); // replace rest
+	}
+	exports.kebobString = kebobString;
+	function _toJson(obj) {
+	    return JSON.stringify(obj);
+	}
+	function _fromJson(json) {
+	    return predicates_1.isString(json) ? JSON.parse(json) : json;
+	}
+	function promiseToString(p) {
+	    return "Promise(" + JSON.stringify(p) + ")";
+	}
+	function functionToString(fn) {
+	    var fnStr = fnToString(fn);
+	    var namedFunctionMatch = fnStr.match(/^(function [^ ]+\([^)]*\))/);
+	    return namedFunctionMatch ? namedFunctionMatch[1] : fnStr;
+	}
+	exports.functionToString = functionToString;
+	function fnToString(fn) {
+	    var _fn = predicates_1.isArray(fn) ? fn.slice(-1)[0] : fn;
+	    return _fn && _fn.toString() || "undefined";
+	}
+	exports.fnToString = fnToString;
+	var stringifyPatternFn = null;
+	var stringifyPattern = function (value) {
+	    var isTransitionRejectionPromise = rejectFactory_1.Rejection.isTransitionRejectionPromise;
+	    stringifyPatternFn = stringifyPatternFn || hof_1.pattern([
+	        [hof_1.not(predicates_1.isDefined), hof_1.val("undefined")],
+	        [predicates_1.isNull, hof_1.val("null")],
+	        [predicates_1.isPromise, hof_1.val("[Promise]")],
+	        [isTransitionRejectionPromise, function (x) { return x._transitionRejection.toString(); }],
+	        [hof_1.is(rejectFactory_1.Rejection), hof_1.invoke("toString")],
+	        [hof_1.is(transition_1.Transition), hof_1.invoke("toString")],
+	        [hof_1.is(resolvable_1.Resolvable), hof_1.invoke("toString")],
+	        [predicates_1.isInjectable, functionToString],
+	        [hof_1.val(true), common_1.identity]
+	    ]);
+	    return stringifyPatternFn(value);
+	};
+	function stringify(o) {
+	    var seen = [];
+	    function format(val) {
+	        if (predicates_1.isObject(val)) {
+	            if (seen.indexOf(val) !== -1)
+	                return '[circular ref]';
+	            seen.push(val);
+	        }
+	        return stringifyPattern(val);
+	    }
+	    return JSON.stringify(o, function (key, val) { return format(val); }).replace(/\\"/g, '"');
+	}
+	exports.stringify = stringify;
+	/** Returns a function that splits a string on a character or substring */
+	exports.beforeAfterSubstr = function (char) { return function (str) {
+	    if (!str)
+	        return ["", ""];
+	    var idx = str.indexOf(char);
+	    if (idx === -1)
+	        return [str, ""];
+	    return [str.substr(0, idx), str.substr(idx + 1)];
+	}; };
+
+
+/***/ },
+/* 10 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/** @module transition */ /** for typedoc */
+	"use strict";
+	var common_1 = __webpack_require__(3);
+	var strings_1 = __webpack_require__(9);
+	(function (RejectType) {
+	    RejectType[RejectType["SUPERSEDED"] = 2] = "SUPERSEDED";
+	    RejectType[RejectType["ABORTED"] = 3] = "ABORTED";
+	    RejectType[RejectType["INVALID"] = 4] = "INVALID";
+	    RejectType[RejectType["IGNORED"] = 5] = "IGNORED";
+	    RejectType[RejectType["ERROR"] = 6] = "ERROR";
+	})(exports.RejectType || (exports.RejectType = {}));
+	var RejectType = exports.RejectType;
+	var Rejection = (function () {
+	    function Rejection(type, message, detail) {
+	        this.type = type;
+	        this.message = message;
+	        this.detail = detail;
+	    }
+	    Rejection.prototype.toString = function () {
+	        var detailString = function (d) { return d && d.toString !== Object.prototype.toString ? d.toString() : strings_1.stringify(d); };
+	        var type = this.type, message = this.message, detail = detailString(this.detail);
+	        return "TransitionRejection(type: " + type + ", message: " + message + ", detail: " + detail + ")";
+	    };
+	    Rejection.prototype.toPromise = function () {
+	        return common_1.extend(common_1.silentRejection(this), { _transitionRejection: this });
+	    };
+	    /** Returns true if the obj is a rejected promise created from the `asPromise` factory */
+	    Rejection.isTransitionRejectionPromise = function (obj) {
+	        return obj && (typeof obj.then === 'function') && obj._transitionRejection instanceof Rejection;
+	    };
+	    /** Returns a TransitionRejection due to transition superseded */
+	    Rejection.superseded = function (detail, options) {
+	        var message = "The transition has been superseded by a different transition (see detail).";
+	        var rejection = new Rejection(RejectType.SUPERSEDED, message, detail);
+	        if (options && options.redirected) {
+	            rejection.redirected = true;
+	        }
+	        return rejection;
+	    };
+	    /** Returns a TransitionRejection due to redirected transition */
+	    Rejection.redirected = function (detail) {
+	        return Rejection.superseded(detail, { redirected: true });
+	    };
+	    /** Returns a TransitionRejection due to invalid transition */
+	    Rejection.invalid = function (detail) {
+	        var message = "This transition is invalid (see detail)";
+	        return new Rejection(RejectType.INVALID, message, detail);
+	    };
+	    /** Returns a TransitionRejection due to ignored transition */
+	    Rejection.ignored = function (detail) {
+	        var message = "The transition was ignored.";
+	        return new Rejection(RejectType.IGNORED, message, detail);
+	    };
+	    /** Returns a TransitionRejection due to aborted transition */
+	    Rejection.aborted = function (detail) {
+	        // TODO think about how to encapsulate an Error() object
+	        var message = "The transition has been aborted.";
+	        return new Rejection(RejectType.ABORTED, message, detail);
+	    };
+	    /** Returns a TransitionRejection due to aborted transition */
+	    Rejection.errored = function (detail) {
+	        // TODO think about how to encapsulate an Error() object
+	        var message = "The transition errored.";
+	        return new Rejection(RejectType.ERROR, message, detail);
+	    };
+	    return Rejection;
+	}());
+	exports.Rejection = Rejection;
+
+
+/***/ },
+/* 11 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module transition */ /** for typedoc */
+	var trace_1 = __webpack_require__(12);
+	var coreservices_1 = __webpack_require__(6);
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var hof_1 = __webpack_require__(5);
+	var transitionHook_1 = __webpack_require__(13);
+	var hookRegistry_1 = __webpack_require__(15);
+	var hookBuilder_1 = __webpack_require__(16);
+	var node_1 = __webpack_require__(21);
+	var pathFactory_1 = __webpack_require__(20);
+	var targetState_1 = __webpack_require__(14);
+	var param_1 = __webpack_require__(22);
+	var resolvable_1 = __webpack_require__(19);
+	var rejectFactory_1 = __webpack_require__(10);
+	var resolveContext_1 = __webpack_require__(17);
+	var router_1 = __webpack_require__(26);
+	var transitionCount = 0;
+	var stateSelf = hof_1.prop("self");
+	/**
+	 * Represents a transition between two states.
+	 *
+	 * When navigating to a state, we are transitioning **from** the current state **to** the new state.
+	 *
+	 * This object contains all contextual information about the to/from states, parameters, resolves.
+	 * It has information about all states being entered and exited as a result of the transition.
+	 */
+	var Transition = (function () {
+	    /**
+	     * Creates a new Transition object.
+	     *
+	     * If the target state is not valid, an error is thrown.
+	     *
+	     * @param fromPath The path of [[PathNode]]s from which the transition is leaving.  The last node in the `fromPath`
+	     *        encapsulates the "from state".
+	     * @param targetState The target state and parameters being transitioned to (also, the transition options)
+	     * @param router The [[UIRouter]] instance
+	     */
+	    function Transition(fromPath, targetState, router) {
+	        var _this = this;
+	        /** @hidden */
+	        this._deferred = coreservices_1.services.$q.defer();
+	        /**
+	         * This promise is resolved or rejected based on the outcome of the Transition.
+	         *
+	         * When the transition is successful, the promise is resolved
+	         * When the transition is unsuccessful, the promise is rejected with the [[TransitionRejection]] or javascript error
+	         */
+	        this.promise = this._deferred.promise;
+	        this.treeChanges = function () { return _this._treeChanges; };
+	        this.isActive = function () { return _this === _this._options.current(); };
+	        this.router = router;
+	        if (!targetState.valid()) {
+	            throw new Error(targetState.error());
+	        }
+	        // Makes the Transition instance a hook registry (onStart, etc)
+	        hookRegistry_1.HookRegistry.mixin(new hookRegistry_1.HookRegistry(), this);
+	        // current() is assumed to come from targetState.options, but provide a naive implementation otherwise.
+	        this._options = common_1.extend({ current: hof_1.val(this) }, targetState.options());
+	        this.$id = transitionCount++;
+	        var toPath = pathFactory_1.PathFactory.buildToPath(fromPath, targetState);
+	        this._treeChanges = pathFactory_1.PathFactory.treeChanges(fromPath, toPath, this._options.reloadState);
+	        var enteringStates = this._treeChanges.entering.map(function (node) { return node.state; });
+	        pathFactory_1.PathFactory.applyViewConfigs(router.transitionService.$view, this._treeChanges.to, enteringStates);
+	        var rootResolvables = [
+	            new resolvable_1.Resolvable(router_1.UIRouter, function () { return router; }, [], undefined, router),
+	            new resolvable_1.Resolvable(Transition, function () { return _this; }, [], undefined, this),
+	            new resolvable_1.Resolvable('$transition$', function () { return _this; }, [], undefined, this),
+	            new resolvable_1.Resolvable('$stateParams', function () { return _this.params(); }, [], undefined, this.params())
+	        ];
+	        var rootNode = this._treeChanges.to[0];
+	        var context = new resolveContext_1.ResolveContext(this._treeChanges.to);
+	        context.addResolvables(rootResolvables, rootNode.state);
+	    }
+	    /** @inheritdoc */
+	    Transition.prototype.onBefore = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    Transition.prototype.onStart = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    Transition.prototype.onExit = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    Transition.prototype.onRetain = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    Transition.prototype.onEnter = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    Transition.prototype.onFinish = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    Transition.prototype.onSuccess = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    Transition.prototype.onError = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    Transition.prototype.$from = function () {
+	        return common_1.tail(this._treeChanges.from).state;
+	    };
+	    Transition.prototype.$to = function () {
+	        return common_1.tail(this._treeChanges.to).state;
+	    };
+	    /**
+	     * Returns the "from state"
+	     *
+	     * @returns The state object for the Transition's "from state".
+	     */
+	    Transition.prototype.from = function () {
+	        return this.$from().self;
+	    };
+	    /**
+	     * Returns the "to state"
+	     *
+	     * @returns The state object for the Transition's target state ("to state").
+	     */
+	    Transition.prototype.to = function () {
+	        return this.$to().self;
+	    };
+	    /**
+	     * Determines whether two transitions are equivalent.
+	     */
+	    Transition.prototype.is = function (compare) {
+	        if (compare instanceof Transition) {
+	            // TODO: Also compare parameters
+	            return this.is({ to: compare.$to().name, from: compare.$from().name });
+	        }
+	        return !((compare.to && !hookRegistry_1.matchState(this.$to(), compare.to)) ||
+	            (compare.from && !hookRegistry_1.matchState(this.$from(), compare.from)));
+	    };
+	    /**
+	     * Gets transition parameter values
+	     *
+	     * @param pathname Pick which treeChanges path to get parameters for:
+	     *   (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`)
+	     * @returns transition parameter values for the desired path.
+	     */
+	    Transition.prototype.params = function (pathname) {
+	        if (pathname === void 0) { pathname = "to"; }
+	        return this._treeChanges[pathname].map(hof_1.prop("paramValues")).reduce(common_1.mergeR, {});
+	    };
+	    /**
+	     * Creates a [[UIInjector]] Dependency Injector
+	     *
+	     * Returns a Dependency Injector for the Transition's target state (to state).
+	     * The injector provides resolve values which the target state has access to.
+	     *
+	     * The `UIInjector` can also provide values from the native root/global injector (ng1/ng2).
+	     *
+	     * If a `state` is provided, the injector that is returned will be limited to resolve values that the provided state has access to.
+	     *
+	     * @param state Limits the resolves provided to only the resolves the provided state has access to.
+	     * @returns a [[UIInjector]]
+	     */
+	    Transition.prototype.injector = function (state) {
+	        var path = this.treeChanges().to;
+	        if (state)
+	            path = pathFactory_1.PathFactory.subPath(path, function (node) { return node.state === state || node.state.name === state; });
+	        return new resolveContext_1.ResolveContext(path).injector();
+	    };
+	    /**
+	     * Gets all available resolve tokens (keys)
+	     *
+	     * This method can be used in conjunction with [[getResolve]] to inspect the resolve values
+	     * available to the Transition.
+	     *
+	     * The returned tokens include those defined on [[StateDeclaration.resolve]] blocks, for the states
+	     * in the Transition's [[TreeChanges.to]] path.
+	     *
+	     * @returns an array of resolve tokens (keys)
+	     */
+	    Transition.prototype.getResolveTokens = function () {
+	        return new resolveContext_1.ResolveContext(this._treeChanges.to).getTokens();
+	    };
+	    /**
+	     * Gets resolved values
+	     *
+	     * This method can be used in conjunction with [[getResolveTokens]] to inspect what resolve values
+	     * are available to the Transition.
+	     *
+	     * Given a token, returns the resolved data for that token.
+	     * Given an array of tokens, returns an array of resolved data for those tokens.
+	     *
+	     * If a resolvable hasn't yet been fetched, returns `undefined` for that token
+	     * If a resolvable doesn't exist for the token, throws an error.
+	     *
+	     * @param token the token (or array of tokens)
+	     *
+	     * @returns an array of resolve tokens (keys)
+	     */
+	    Transition.prototype.getResolveValue = function (token) {
+	        var resolveContext = new resolveContext_1.ResolveContext(this._treeChanges.to);
+	        var getData = function (token) {
+	            var resolvable = resolveContext.getResolvable(token);
+	            if (resolvable === undefined) {
+	                throw new Error("Dependency Injection token not found: ${stringify(token)}");
+	            }
+	            return resolvable.data;
+	        };
+	        if (predicates_1.isArray(token)) {
+	            return token.map(getData);
+	        }
+	        return getData(token);
+	    };
+	    /**
+	     * Dynamically adds a new [[Resolvable]] (`resolve`) to this transition.
+	     *
+	     * @param resolvable an [[Resolvable]] object
+	     * @param state the state in the "to path" which should receive the new resolve (otherwise, the root state)
+	     */
+	    Transition.prototype.addResolvable = function (resolvable, state) {
+	        if (state === void 0) { state = ""; }
+	        var stateName = (typeof state === "string") ? state : state.name;
+	        var topath = this._treeChanges.to;
+	        var targetNode = common_1.find(topath, function (node) { return node.state.name === stateName; });
+	        var resolveContext = new resolveContext_1.ResolveContext(topath);
+	        resolveContext.addResolvables([resolvable], targetNode.state);
+	    };
+	    /**
+	     * Gets the previous transition, from which this transition was redirected.
+	     *
+	     * @returns The previous Transition, or null if this Transition is not the result of a redirection
+	     */
+	    Transition.prototype.previous = function () {
+	        return this._options.previous || null;
+	    };
+	    /**
+	     * Get the transition options
+	     *
+	     * @returns the options for this Transition.
+	     */
+	    Transition.prototype.options = function () {
+	        return this._options;
+	    };
+	    /**
+	     * Gets the states being entered.
+	     *
+	     * @returns an array of states that will be entered during this transition.
+	     */
+	    Transition.prototype.entering = function () {
+	        return common_1.map(this._treeChanges.entering, hof_1.prop('state')).map(stateSelf);
+	    };
+	    /**
+	     * Gets the states being exited.
+	     *
+	     * @returns an array of states that will be exited during this transition.
+	     */
+	    Transition.prototype.exiting = function () {
+	        return common_1.map(this._treeChanges.exiting, hof_1.prop('state')).map(stateSelf).reverse();
+	    };
+	    /**
+	     * Gets the states being retained.
+	     *
+	     * @returns an array of states that are already entered from a previous Transition, that will not be
+	     *    exited during this Transition
+	     */
+	    Transition.prototype.retained = function () {
+	        return common_1.map(this._treeChanges.retained, hof_1.prop('state')).map(stateSelf);
+	    };
+	    /**
+	     * Get the [[ViewConfig]]s associated with this Transition
+	     *
+	     * Each state can define one or more views (template/controller), which are encapsulated as `ViewConfig` objects.
+	     * This method fetches the `ViewConfigs` for a given path in the Transition (e.g., "to" or "entering").
+	     *
+	     * @param pathname the name of the path to fetch views for:
+	     *   (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`)
+	     * @param state If provided, only returns the `ViewConfig`s for a single state in the path
+	     *
+	     * @returns a list of ViewConfig objects for the given path.
+	     */
+	    Transition.prototype.views = function (pathname, state) {
+	        if (pathname === void 0) { pathname = "entering"; }
+	        var path = this._treeChanges[pathname];
+	        path = !state ? path : path.filter(hof_1.propEq('state', state));
+	        return path.map(hof_1.prop("views")).filter(common_1.identity).reduce(common_1.unnestR, []);
+	    };
+	    /**
+	     * Creates a new transition that is a redirection of the current one.
+	     *
+	     * This transition can be returned from a [[TransitionService]] hook to
+	     * redirect a transition to a new state and/or set of parameters.
+	     *
+	     * @returns Returns a new [[Transition]] instance.
+	     */
+	    Transition.prototype.redirect = function (targetState) {
+	        var newOptions = common_1.extend({}, this.options(), targetState.options(), { previous: this });
+	        targetState = new targetState_1.TargetState(targetState.identifier(), targetState.$state(), targetState.params(), newOptions);
+	        var newTransition = this.router.transitionService.create(this._treeChanges.from, targetState);
+	        var originalEnteringNodes = this.treeChanges().entering;
+	        var redirectEnteringNodes = newTransition.treeChanges().entering;
+	        // --- Re-use resolve data from original transition ---
+	        // When redirecting from a parent state to a child state where the parent parameter values haven't changed
+	        // (because of the redirect), the resolves fetched by the original transition are still valid in the
+	        // redirected transition.
+	        //
+	        // This allows you to define a redirect on a parent state which depends on an async resolve value.
+	        // You can wait for the resolve, then redirect to a child state based on the result.
+	        // The redirected transition does not have to re-fetch the resolve.
+	        // ---------------------------------------------------------
+	        var nodeIsReloading = function (reloadState) { return function (node) {
+	            return reloadState && node.state.includes[reloadState.name];
+	        }; };
+	        // Find any "entering" nodes in the redirect path that match the original path and aren't being reloaded
+	        var matchingEnteringNodes = node_1.PathNode.matching(redirectEnteringNodes, originalEnteringNodes)
+	            .filter(hof_1.not(nodeIsReloading(targetState.options().reloadState)));
+	        // Use the existing (possibly pre-resolved) resolvables for the matching entering nodes.
+	        matchingEnteringNodes.forEach(function (node, idx) {
+	            node.resolvables = originalEnteringNodes[idx].resolvables;
+	        });
+	        return newTransition;
+	    };
+	    /** @hidden If a transition doesn't exit/enter any states, returns any [[Param]] whose value changed */
+	    Transition.prototype._changedParams = function () {
+	        var _a = this._treeChanges, to = _a.to, from = _a.from;
+	        if (this._options.reload || common_1.tail(to).state !== common_1.tail(from).state)
+	            return undefined;
+	        var nodeSchemas = to.map(function (node) { return node.paramSchema; });
+	        var _b = [to, from].map(function (path) { return path.map(function (x) { return x.paramValues; }); }), toValues = _b[0], fromValues = _b[1];
+	        var tuples = common_1.arrayTuples(nodeSchemas, toValues, fromValues);
+	        return tuples.map(function (_a) {
+	            var schema = _a[0], toVals = _a[1], fromVals = _a[2];
+	            return param_1.Param.changed(schema, toVals, fromVals);
+	        }).reduce(common_1.unnestR, []);
+	    };
+	    /**
+	     * Returns true if the transition is dynamic.
+	     *
+	     * A transition is dynamic if no states are entered nor exited, but at least one dynamic parameter has changed.
+	     *
+	     * @returns true if the Transition is dynamic
+	     */
+	    Transition.prototype.dynamic = function () {
+	        var changes = this._changedParams();
+	        return !changes ? false : changes.map(function (x) { return x.dynamic; }).reduce(common_1.anyTrueR, false);
+	    };
+	    /**
+	     * Returns true if the transition is ignored.
+	     *
+	     * A transition is ignored if no states are entered nor exited, and no parameter values have changed.
+	     *
+	     * @returns true if the Transition is ignored.
+	     */
+	    Transition.prototype.ignored = function () {
+	        var changes = this._changedParams();
+	        return !changes ? false : changes.length === 0;
+	    };
+	    /**
+	     * @hidden
+	     */
+	    Transition.prototype.hookBuilder = function () {
+	        return new hookBuilder_1.HookBuilder(this.router.transitionService, this, {
+	            transition: this,
+	            current: this._options.current
+	        });
+	    };
+	    /**
+	     * Runs the transition
+	     *
+	     * This method is generally called from the [[StateService.transitionTo]]
+	     *
+	     * @returns a promise for a successful transition.
+	     */
+	    Transition.prototype.run = function () {
+	        var _this = this;
+	        var runSynchronousHooks = transitionHook_1.TransitionHook.runSynchronousHooks;
+	        var hookBuilder = this.hookBuilder();
+	        var globals = this.router.globals;
+	        globals.transitionHistory.enqueue(this);
+	        var syncResult = runSynchronousHooks(hookBuilder.getOnBeforeHooks());
+	        if (rejectFactory_1.Rejection.isTransitionRejectionPromise(syncResult)) {
+	            syncResult.catch(function () { return 0; }); // issue #2676
+	            var rejectReason = syncResult._transitionRejection;
+	            this._deferred.reject(rejectReason);
+	            return this.promise;
+	        }
+	        if (!this.valid()) {
+	            var error = new Error(this.error());
+	            this._deferred.reject(error);
+	            return this.promise;
+	        }
+	        if (this.ignored()) {
+	            trace_1.trace.traceTransitionIgnored(this);
+	            this._deferred.reject(rejectFactory_1.Rejection.ignored());
+	            return this.promise;
+	        }
+	        // When the chain is complete, then resolve or reject the deferred
+	        var transitionSuccess = function () {
+	            trace_1.trace.traceSuccess(_this.$to(), _this);
+	            _this.success = true;
+	            _this._deferred.resolve(_this.to());
+	            runSynchronousHooks(hookBuilder.getOnSuccessHooks(), true);
+	        };
+	        var transitionError = function (error) {
+	            trace_1.trace.traceError(error, _this);
+	            _this.success = false;
+	            _this._deferred.reject(error);
+	            runSynchronousHooks(hookBuilder.getOnErrorHooks(), true);
+	        };
+	        trace_1.trace.traceTransitionStart(this);
+	        // Chain the next hook off the previous
+	        var appendHookToChain = function (prev, nextHook) {
+	            return prev.then(function () { return nextHook.invokeHook(); });
+	        };
+	        // Run the hooks, then resolve or reject the overall deferred in the .then() handler
+	        hookBuilder.asyncHooks()
+	            .reduce(appendHookToChain, syncResult)
+	            .then(transitionSuccess, transitionError);
+	        return this.promise;
+	    };
+	    /**
+	     * Checks if the Transition is valid
+	     *
+	     * @returns true if the Transition is valid
+	     */
+	    Transition.prototype.valid = function () {
+	        return !this.error();
+	    };
+	    /**
+	     * The reason the Transition is invalid
+	     *
+	     * @returns an error message explaining why the transition is invalid
+	     */
+	    Transition.prototype.error = function () {
+	        var state = this.$to();
+	        if (state.self[common_1.abstractKey])
+	            return "Cannot transition to abstract state '" + state.name + "'";
+	        if (!param_1.Param.validates(state.parameters(), this.params()))
+	            return "Param values not valid for state '" + state.name + "'";
+	    };
+	    /**
+	     * A string representation of the Transition
+	     *
+	     * @returns A string representation of the Transition
+	     */
+	    Transition.prototype.toString = function () {
+	        var fromStateOrName = this.from();
+	        var toStateOrName = this.to();
+	        var avoidEmptyHash = function (params) {
+	            return (params["#"] !== null && params["#"] !== undefined) ? params : common_1.omit(params, "#");
+	        };
+	        // (X) means the to state is invalid.
+	        var id = this.$id, from = predicates_1.isObject(fromStateOrName) ? fromStateOrName.name : fromStateOrName, fromParams = common_1.toJson(avoidEmptyHash(this._treeChanges.from.map(hof_1.prop('paramValues')).reduce(common_1.mergeR, {}))), toValid = this.valid() ? "" : "(X) ", to = predicates_1.isObject(toStateOrName) ? toStateOrName.name : toStateOrName, toParams = common_1.toJson(avoidEmptyHash(this.params()));
+	        return "Transition#" + id + "( '" + from + "'" + fromParams + " -> " + toValid + "'" + to + "'" + toParams + " )";
+	    };
+	    Transition.diToken = Transition;
+	    return Transition;
+	}());
+	exports.Transition = Transition;
+
+
+/***/ },
+/* 12 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/**
+	 * UI-Router Transition Tracing
+	 *
+	 * Enable transition tracing to print transition information to the console, in order to help debug your application.
+	 * Tracing logs detailed information about each Transition to your console.
+	 *
+	 * To enable tracing, import the [[trace]] singleton and enable one or more categories.
+	 *
+	 * ES6
+	 * ```
+	 *
+	 * import {trace} from "ui-router-ng2"; // or "angular-ui-router"
+	 * trace.enable(1, 5); // TRANSITION and VIEWCONFIG
+	 * ```
+	 *
+	 * CJS
+	 * ```
+	 *
+	 * let trace = require("angular-ui-router").trace; // or "ui-router-ng2"
+	 * trace.enable("TRANSITION", "VIEWCONFIG");
+	 * ```
+	 *
+	 * Globals
+	 * ```
+	 *
+	 * let trace = window["angular-ui-router"].trace; // or "ui-router-ng2"
+	 * trace.enable(); // Trace everything (very verbose)
+	 * ```
+	 *
+	 * @module trace
+	 */ /** for typedoc */
+	var hof_1 = __webpack_require__(5);
+	var predicates_1 = __webpack_require__(4);
+	var strings_1 = __webpack_require__(9);
+	/** @hidden */
+	function uiViewString(viewData) {
+	    if (!viewData)
+	        return 'ui-view (defunct)';
+	    return ("[ui-view#" + viewData.id + " tag ") +
+	        ("in template from '" + (viewData.creationContext && viewData.creationContext.name || '(root)') + "' state]: ") +
+	        ("fqn: '" + viewData.fqn + "', ") +
+	        ("name: '" + viewData.name + "@" + viewData.creationContext + "')");
+	}
+	/** @hidden */
+	var viewConfigString = function (viewConfig) {
+	    return ("[ViewConfig#" + viewConfig.$id + " from '" + (viewConfig.viewDecl.$context.name || '(root)') + "' state]: target ui-view: '" + viewConfig.viewDecl.$uiViewName + "@" + viewConfig.viewDecl.$uiViewContextAnchor + "'");
+	};
+	/** @hidden */
+	function normalizedCat(input) {
+	    return predicates_1.isNumber(input) ? Category[input] : Category[Category[input]];
+	}
+	/**
+	 * Trace categories
+	 *
+	 * [[Trace.enable]] or [[Trace.disable]] a category
+	 *
+	 * `trace.enable(Category.TRANSITION)`
+	 *
+	 * These can also be provided using a matching string, or position ordinal
+	 *
+	 * `trace.enable("TRANSITION")`
+	 *
+	 * `trace.enable(1)`
+	 */
+	(function (Category) {
+	    Category[Category["RESOLVE"] = 0] = "RESOLVE";
+	    Category[Category["TRANSITION"] = 1] = "TRANSITION";
+	    Category[Category["HOOK"] = 2] = "HOOK";
+	    Category[Category["INVOKE"] = 3] = "INVOKE";
+	    Category[Category["UIVIEW"] = 4] = "UIVIEW";
+	    Category[Category["VIEWCONFIG"] = 5] = "VIEWCONFIG";
+	})(exports.Category || (exports.Category = {}));
+	var Category = exports.Category;
+	/**
+	 * Prints UI-Router Transition trace information to the console.
+	 */
+	var Trace = (function () {
+	    function Trace() {
+	        /** @hidden */
+	        this._enabled = {};
+	        this.approximateDigests = 0;
+	    }
+	    /** @hidden */
+	    Trace.prototype._set = function (enabled, categories) {
+	        var _this = this;
+	        if (!categories.length) {
+	            categories = Object.keys(Category)
+	                .filter(function (k) { return isNaN(parseInt(k, 10)); })
+	                .map(function (key) { return Category[key]; });
+	        }
+	        categories.map(normalizedCat).forEach(function (category) { return _this._enabled[category] = enabled; });
+	    };
+	    /**
+	     * Enables a trace [[Category]]
+	     *
+	     * ```
+	     * trace.enable("TRANSITION");
+	     * ```
+	     *
+	     * @param categories categories to enable. If `categories` is omitted, all categories are enabled.
+	     *        Also takes strings (category name) or ordinal (category position)
+	     */
+	    Trace.prototype.enable = function () {
+	        var categories = [];
+	        for (var _i = 0; _i < arguments.length; _i++) {
+	            categories[_i - 0] = arguments[_i];
+	        }
+	        this._set(true, categories);
+	    };
+	    /**
+	     * Disables a trace [[Category]]
+	     *
+	     * ```
+	     * trace.disable("VIEWCONFIG");
+	     * ```
+	     *
+	     * @param categories categories to disable. If `categories` is omitted, all categories are disabled.
+	     *        Also takes strings (category name) or ordinal (category position)
+	     */
+	    Trace.prototype.disable = function () {
+	        var categories = [];
+	        for (var _i = 0; _i < arguments.length; _i++) {
+	            categories[_i - 0] = arguments[_i];
+	        }
+	        this._set(false, categories);
+	    };
+	    /**
+	     * Retrieves the enabled stateus of a [[Category]]
+	     *
+	     * ```
+	     * trace.enabled("VIEWCONFIG"); // true or false
+	     * ```
+	     *
+	     * @returns boolean true if the category is enabled
+	     */
+	    Trace.prototype.enabled = function (category) {
+	        return !!this._enabled[normalizedCat(category)];
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceTransitionStart = function (transition) {
+	        if (!this.enabled(Category.TRANSITION))
+	            return;
+	        var tid = transition.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(transition);
+	        console.log("Transition #" + tid + " Digest #" + digest + ": Started  -> " + transitionStr);
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceTransitionIgnored = function (trans) {
+	        if (!this.enabled(Category.TRANSITION))
+	            return;
+	        var tid = trans && trans.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(trans);
+	        console.log("Transition #" + tid + " Digest #" + digest + ": Ignored  <> " + transitionStr);
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceHookInvocation = function (step, options) {
+	        if (!this.enabled(Category.HOOK))
+	            return;
+	        var tid = hof_1.parse("transition.$id")(options), digest = this.approximateDigests, event = hof_1.parse("traceData.hookType")(options) || "internal", context = hof_1.parse("traceData.context.state.name")(options) || hof_1.parse("traceData.context")(options) || "unknown", name = strings_1.functionToString(step.fn);
+	        console.log("Transition #" + tid + " Digest #" + digest + ":   Hook -> " + event + " context: " + context + ", " + strings_1.maxLength(200, name));
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceHookResult = function (hookResult, transitionResult, transitionOptions) {
+	        if (!this.enabled(Category.HOOK))
+	            return;
+	        var tid = hof_1.parse("transition.$id")(transitionOptions), digest = this.approximateDigests, hookResultStr = strings_1.stringify(hookResult), transitionResultStr = strings_1.stringify(transitionResult);
+	        console.log("Transition #" + tid + " Digest #" + digest + ":   <- Hook returned: " + strings_1.maxLength(200, hookResultStr) + ", transition result: " + strings_1.maxLength(200, transitionResultStr));
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceResolvePath = function (path, when, trans) {
+	        if (!this.enabled(Category.RESOLVE))
+	            return;
+	        var tid = trans && trans.$id, digest = this.approximateDigests, pathStr = path && path.toString();
+	        console.log("Transition #" + tid + " Digest #" + digest + ":         Resolving " + pathStr + " (" + when + ")");
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceResolvableResolved = function (resolvable, trans) {
+	        if (!this.enabled(Category.RESOLVE))
+	            return;
+	        var tid = trans && trans.$id, digest = this.approximateDigests, resolvableStr = resolvable && resolvable.toString(), result = strings_1.stringify(resolvable.data);
+	        console.log("Transition #" + tid + " Digest #" + digest + ":               <- Resolved  " + resolvableStr + " to: " + strings_1.maxLength(200, result));
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceError = function (error, trans) {
+	        if (!this.enabled(Category.TRANSITION))
+	            return;
+	        var tid = trans && trans.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(trans);
+	        console.log("Transition #" + tid + " Digest #" + digest + ": <- Rejected " + transitionStr + ", reason: " + error);
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceSuccess = function (finalState, trans) {
+	        if (!this.enabled(Category.TRANSITION))
+	            return;
+	        var tid = trans && trans.$id, digest = this.approximateDigests, state = finalState.name, transitionStr = strings_1.stringify(trans);
+	        console.log("Transition #" + tid + " Digest #" + digest + ": <- Success  " + transitionStr + ", final state: " + state);
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceUIViewEvent = function (event, viewData, extra) {
+	        if (extra === void 0) { extra = ""; }
+	        if (!this.enabled(Category.UIVIEW))
+	            return;
+	        console.log("ui-view: " + strings_1.padString(30, event) + " " + uiViewString(viewData) + extra);
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceUIViewConfigUpdated = function (viewData, context) {
+	        if (!this.enabled(Category.UIVIEW))
+	            return;
+	        this.traceUIViewEvent("Updating", viewData, " with ViewConfig from context='" + context + "'");
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceUIViewScopeCreated = function (viewData, newScope) {
+	        if (!this.enabled(Category.UIVIEW))
+	            return;
+	        this.traceUIViewEvent("Created scope for", viewData, ", scope #" + newScope.$id);
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceUIViewFill = function (viewData, html) {
+	        if (!this.enabled(Category.UIVIEW))
+	            return;
+	        this.traceUIViewEvent("Fill", viewData, " with: " + strings_1.maxLength(200, html));
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceViewServiceEvent = function (event, viewConfig) {
+	        if (!this.enabled(Category.VIEWCONFIG))
+	            return;
+	        console.log("VIEWCONFIG: " + event + " " + viewConfigString(viewConfig));
+	    };
+	    /** called by ui-router code */
+	    Trace.prototype.traceViewServiceUIViewEvent = function (event, viewData) {
+	        if (!this.enabled(Category.VIEWCONFIG))
+	            return;
+	        console.log("VIEWCONFIG: " + event + " " + uiViewString(viewData));
+	    };
+	    return Trace;
+	}());
+	exports.Trace = Trace;
+	/**
+	 * The [[Trace]] singleton
+	 *
+	 * @example
+	 * ```js
+	 *
+	 * import {trace} from "angular-ui-router";
+	 * trace.enable(1, 5);
+	 * ```
+	 */
+	var trace = new Trace();
+	exports.trace = trace;
+
+
+/***/ },
+/* 13 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	var common_1 = __webpack_require__(3);
+	var strings_1 = __webpack_require__(9);
+	var predicates_1 = __webpack_require__(4);
+	var hof_1 = __webpack_require__(5);
+	var trace_1 = __webpack_require__(12);
+	var coreservices_1 = __webpack_require__(6);
+	var rejectFactory_1 = __webpack_require__(10);
+	var targetState_1 = __webpack_require__(14);
+	var defaultOptions = {
+	    async: true,
+	    rejectIfSuperseded: true,
+	    current: common_1.noop,
+	    transition: null,
+	    traceData: {},
+	    bind: null
+	};
+	/** @hidden */
+	var TransitionHook = (function () {
+	    function TransitionHook(transition, stateContext, hookFn, resolveContext, options) {
+	        var _this = this;
+	        this.transition = transition;
+	        this.stateContext = stateContext;
+	        this.hookFn = hookFn;
+	        this.resolveContext = resolveContext;
+	        this.options = options;
+	        this.isSuperseded = function () { return _this.options.current() !== _this.options.transition; };
+	        this.options = common_1.defaults(options, defaultOptions);
+	    }
+	    TransitionHook.prototype.invokeHook = function () {
+	        var _a = this, options = _a.options, hookFn = _a.hookFn, resolveContext = _a.resolveContext;
+	        trace_1.trace.traceHookInvocation(this, options);
+	        if (options.rejectIfSuperseded && this.isSuperseded()) {
+	            return rejectFactory_1.Rejection.superseded(options.current()).toPromise();
+	        }
+	        var hookResult = hookFn.call(options.bind, this.transition, this.stateContext);
+	        return this.handleHookResult(hookResult);
+	    };
+	    /**
+	     * This method handles the return value of a Transition Hook.
+	     *
+	     * A hook can return false, a redirect (TargetState), or a promise (which may resolve to false or a redirect)
+	     */
+	    TransitionHook.prototype.handleHookResult = function (hookResult) {
+	        var _this = this;
+	        if (!predicates_1.isDefined(hookResult))
+	            return undefined;
+	        /**
+	         * Handles transition superseded, transition aborted and transition redirect.
+	         */
+	        var mapHookResult = hof_1.pattern([
+	            // Transition is no longer current
+	            [this.isSuperseded, function () { return rejectFactory_1.Rejection.superseded(_this.options.current()).toPromise(); }],
+	            // If the hook returns false, abort the current Transition
+	            [hof_1.eq(false), function () { return rejectFactory_1.Rejection.aborted("Hook aborted transition").toPromise(); }],
+	            // If the hook returns a Transition, halt the current Transition and redirect to that Transition.
+	            [hof_1.is(targetState_1.TargetState), function (target) { return rejectFactory_1.Rejection.redirected(target).toPromise(); }],
+	            // A promise was returned, wait for the promise and then chain another hookHandler
+	            [predicates_1.isPromise, function (promise) { return promise.then(_this.handleHookResult.bind(_this)); }]
+	        ]);
+	        var transitionResult = mapHookResult(hookResult);
+	        if (transitionResult)
+	            trace_1.trace.traceHookResult(hookResult, transitionResult, this.options);
+	        return transitionResult;
+	    };
+	    TransitionHook.prototype.toString = function () {
+	        var _a = this, options = _a.options, hookFn = _a.hookFn;
+	        var event = hof_1.parse("traceData.hookType")(options) || "internal", context = hof_1.parse("traceData.context.state.name")(options) || hof_1.parse("traceData.context")(options) || "unknown", name = strings_1.fnToString(hookFn);
+	        return event + " context: " + context + ", " + strings_1.maxLength(200, name);
+	    };
+	    /**
+	     * Given an array of TransitionHooks, runs each one synchronously and sequentially.
+	     *
+	     * Returns a promise chain composed of any promises returned from each hook.invokeStep() call
+	     */
+	    TransitionHook.runSynchronousHooks = function (hooks, swallowExceptions) {
+	        if (swallowExceptions === void 0) { swallowExceptions = false; }
+	        var results = [];
+	        for (var i = 0; i < hooks.length; i++) {
+	            try {
+	                results.push(hooks[i].invokeHook());
+	            }
+	            catch (exception) {
+	                if (!swallowExceptions) {
+	                    return rejectFactory_1.Rejection.errored(exception).toPromise();
+	                }
+	                console.error("Swallowed exception during synchronous hook handler: " + exception); // TODO: What to do here?
+	            }
+	        }
+	        var rejections = results.filter(rejectFactory_1.Rejection.isTransitionRejectionPromise);
+	        if (rejections.length)
+	            return rejections[0];
+	        return results
+	            .filter(predicates_1.isPromise)
+	            .reduce(function (chain, promise) { return chain.then(hof_1.val(promise)); }, coreservices_1.services.$q.when());
+	    };
+	    return TransitionHook;
+	}());
+	exports.TransitionHook = TransitionHook;
+
+
+/***/ },
+/* 14 */
+/***/ function(module, exports) {
+
+	/** @module state */ /** for typedoc */
+	"use strict";
+	/**
+	 * @ngdoc object
+	 * @name ui.router.state.type:TargetState
+	 *
+	 * @description
+	 * Encapsulate the desired target of a transition.
+	 * Wraps an identifier for a state, a set of parameters, and transition options with the definition of the state.
+	 *
+	 * @param {StateOrName} _identifier  An identifier for a state. Either a fully-qualified path, or the object
+	 *            used to define the state.
+	 * @param {IState} _definition The `State` object definition.
+	 * @param {ParamsOrArray} _params Parameters for the target state
+	 * @param {TransitionOptions} _options Transition options.
+	 */
+	var TargetState = (function () {
+	    function TargetState(_identifier, _definition, _params, _options) {
+	        if (_params === void 0) { _params = {}; }
+	        if (_options === void 0) { _options = {}; }
+	        this._identifier = _identifier;
+	        this._definition = _definition;
+	        this._options = _options;
+	        this._params = _params || {};
+	    }
+	    TargetState.prototype.name = function () {
+	        return this._definition && this._definition.name || this._identifier;
+	    };
+	    TargetState.prototype.identifier = function () {
+	        return this._identifier;
+	    };
+	    TargetState.prototype.params = function () {
+	        return this._params;
+	    };
+	    TargetState.prototype.$state = function () {
+	        return this._definition;
+	    };
+	    TargetState.prototype.state = function () {
+	        return this._definition && this._definition.self;
+	    };
+	    TargetState.prototype.options = function () {
+	        return this._options;
+	    };
+	    TargetState.prototype.exists = function () {
+	        return !!(this._definition && this._definition.self);
+	    };
+	    TargetState.prototype.valid = function () {
+	        return !this.error();
+	    };
+	    TargetState.prototype.error = function () {
+	        var base = this.options().relative;
+	        if (!this._definition && !!base) {
+	            var stateName = base.name ? base.name : base;
+	            return "Could not resolve '" + this.name() + "' from state '" + stateName + "'";
+	        }
+	        if (!this._definition)
+	            return "No such state '" + this.name() + "'";
+	        if (!this._definition.self)
+	            return "State '" + this.name() + "' has an invalid definition";
+	    };
+	    return TargetState;
+	}());
+	exports.TargetState = TargetState;
+
+
+/***/ },
+/* 15 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module transition */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var glob_1 = __webpack_require__(7);
+	/**
+	 * Determines if the given state matches the matchCriteria
+	 *
+	 * @hidden
+	 *
+	 * @param state a State Object to test against
+	 * @param criterion
+	 * - If a string, matchState uses the string as a glob-matcher against the state name
+	 * - If an array (of strings), matchState uses each string in the array as a glob-matchers against the state name
+	 *   and returns a positive match if any of the globs match.
+	 * - If a function, matchState calls the function with the state and returns true if the function's result is truthy.
+	 * @returns {boolean}
+	 */
+	function matchState(state, criterion) {
+	    var toMatch = predicates_1.isString(criterion) ? [criterion] : criterion;
+	    function matchGlobs(_state) {
+	        var globStrings = toMatch;
+	        for (var i = 0; i < globStrings.length; i++) {
+	            var glob = glob_1.Glob.fromString(globStrings[i]);
+	            if ((glob && glob.matches(_state.name)) || (!glob && globStrings[i] === _state.name)) {
+	                return true;
+	            }
+	        }
+	        return false;
+	    }
+	    var matchFn = (predicates_1.isFunction(toMatch) ? toMatch : matchGlobs);
+	    return !!matchFn(state);
+	}
+	exports.matchState = matchState;
+	/** @hidden */
+	var EventHook = (function () {
+	    function EventHook(matchCriteria, callback, options) {
+	        if (options === void 0) { options = {}; }
+	        this.callback = callback;
+	        this.matchCriteria = common_1.extend({ to: true, from: true, exiting: true, retained: true, entering: true }, matchCriteria);
+	        this.priority = options.priority || 0;
+	        this.bind = options.bind || null;
+	    }
+	    EventHook._matchingNodes = function (nodes, criterion) {
+	        if (criterion === true)
+	            return nodes;
+	        var matching = nodes.filter(function (node) { return matchState(node.state, criterion); });
+	        return matching.length ? matching : null;
+	    };
+	    /**
+	     * Determines if this hook's [[matchCriteria]] match the given [[TreeChanges]]
+	     *
+	     * @returns an IMatchingNodes object, or null. If an IMatchingNodes object is returned, its values
+	     * are the matching [[PathNode]]s for each [[HookMatchCriterion]] (to, from, exiting, retained, entering)
+	     */
+	    EventHook.prototype.matches = function (treeChanges) {
+	        var mc = this.matchCriteria, _matchingNodes = EventHook._matchingNodes;
+	        var matches = {
+	            to: _matchingNodes([common_1.tail(treeChanges.to)], mc.to),
+	            from: _matchingNodes([common_1.tail(treeChanges.from)], mc.from),
+	            exiting: _matchingNodes(treeChanges.exiting, mc.exiting),
+	            retained: _matchingNodes(treeChanges.retained, mc.retained),
+	            entering: _matchingNodes(treeChanges.entering, mc.entering),
+	        };
+	        // Check if all the criteria matched the TreeChanges object
+	        var allMatched = ["to", "from", "exiting", "retained", "entering"]
+	            .map(function (prop) { return matches[prop]; })
+	            .reduce(common_1.allTrueR, true);
+	        return allMatched ? matches : null;
+	    };
+	    return EventHook;
+	}());
+	exports.EventHook = EventHook;
+	/** @hidden Return a registration function of the requested type. */
+	function makeHookRegistrationFn(hooks, name) {
+	    return function (matchObject, callback, options) {
+	        if (options === void 0) { options = {}; }
+	        var eventHook = new EventHook(matchObject, callback, options);
+	        hooks[name].push(eventHook);
+	        return function deregisterEventHook() {
+	            common_1.removeFrom(hooks[name])(eventHook);
+	        };
+	    };
+	}
+	/**
+	 * Mixin class acts as a Transition Hook registry.
+	 *
+	 * Holds the registered [[HookFn]] objects.
+	 * Exposes functions to register new hooks.
+	 *
+	 * This is a Mixin class which can be applied to other objects.
+	 *
+	 * The hook registration functions are [[onBefore]], [[onStart]], [[onEnter]], [[onRetain]], [[onExit]], [[onFinish]], [[onSuccess]], [[onError]].
+	 *
+	 * This class is mixed into both the [[TransitionService]] and every [[Transition]] object.
+	 * Global hooks are added to the [[TransitionService]].
+	 * Since each [[Transition]] is itself a `HookRegistry`, hooks can also be added to individual Transitions
+	 * (note: the hook criteria still must match the Transition).
+	 */
+	var HookRegistry = (function () {
+	    function HookRegistry() {
+	        var _this = this;
+	        this._transitionEvents = {
+	            onBefore: [], onStart: [], onEnter: [], onRetain: [], onExit: [], onFinish: [], onSuccess: [], onError: []
+	        };
+	        this.getHooks = function (name) { return _this._transitionEvents[name]; };
+	        /** @inheritdoc */
+	        this.onBefore = makeHookRegistrationFn(this._transitionEvents, "onBefore");
+	        /** @inheritdoc */
+	        this.onStart = makeHookRegistrationFn(this._transitionEvents, "onStart");
+	        /** @inheritdoc */
+	        this.onEnter = makeHookRegistrationFn(this._transitionEvents, "onEnter");
+	        /** @inheritdoc */
+	        this.onRetain = makeHookRegistrationFn(this._transitionEvents, "onRetain");
+	        /** @inheritdoc */
+	        this.onExit = makeHookRegistrationFn(this._transitionEvents, "onExit");
+	        /** @inheritdoc */
+	        this.onFinish = makeHookRegistrationFn(this._transitionEvents, "onFinish");
+	        /** @inheritdoc */
+	        this.onSuccess = makeHookRegistrationFn(this._transitionEvents, "onSuccess");
+	        /** @inheritdoc */
+	        this.onError = makeHookRegistrationFn(this._transitionEvents, "onError");
+	    }
+	    HookRegistry.mixin = function (source, target) {
+	        Object.keys(source._transitionEvents).concat(["getHooks"]).forEach(function (key) { return target[key] = source[key]; });
+	    };
+	    return HookRegistry;
+	}());
+	exports.HookRegistry = HookRegistry;
+
+
+/***/ },
+/* 16 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/** @module transition */ /** for typedoc */
+	"use strict";
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var transitionHook_1 = __webpack_require__(13);
+	var resolveContext_1 = __webpack_require__(17);
+	/**
+	 * This class returns applicable TransitionHooks for a specific Transition instance.
+	 *
+	 * Hooks (IEventHook) may be registered globally, e.g., $transitions.onEnter(...), or locally, e.g.
+	 * myTransition.onEnter(...).  The HookBuilder finds matching IEventHooks (where the match criteria is
+	 * determined by the type of hook)
+	 *
+	 * The HookBuilder also converts IEventHooks objects to TransitionHook objects, which are used to run a Transition.
+	 *
+	 * The HookBuilder constructor is given the $transitions service and a Transition instance.  Thus, a HookBuilder
+	 * instance may only be used for one specific Transition object. (side note: the _treeChanges accessor is private
+	 * in the Transition class, so we must also provide the Transition's _treeChanges)
+	 *
+	 */
+	var HookBuilder = (function () {
+	    function HookBuilder($transitions, transition, baseHookOptions) {
+	        var _this = this;
+	        this.$transitions = $transitions;
+	        this.transition = transition;
+	        this.baseHookOptions = baseHookOptions;
+	        this.getOnBeforeHooks = function () { return _this._buildNodeHooks("onBefore", "to", tupleSort(), { async: false }); };
+	        this.getOnStartHooks = function () { return _this._buildNodeHooks("onStart", "to", tupleSort()); };
+	        this.getOnExitHooks = function () { return _this._buildNodeHooks("onExit", "exiting", tupleSort(true), { stateHook: true }); };
+	        this.getOnRetainHooks = function () { return _this._buildNodeHooks("onRetain", "retained", tupleSort(false), { stateHook: true }); };
+	        this.getOnEnterHooks = function () { return _this._buildNodeHooks("onEnter", "entering", tupleSort(false), { stateHook: true }); };
+	        this.getOnFinishHooks = function () { return _this._buildNodeHooks("onFinish", "to", tupleSort()); };
+	        this.getOnSuccessHooks = function () { return _this._buildNodeHooks("onSuccess", "to", tupleSort(), { async: false, rejectIfSuperseded: false }); };
+	        this.getOnErrorHooks = function () { return _this._buildNodeHooks("onError", "to", tupleSort(), { async: false, rejectIfSuperseded: false }); };
+	        this.treeChanges = transition.treeChanges();
+	        this.toState = common_1.tail(this.treeChanges.to).state;
+	        this.fromState = common_1.tail(this.treeChanges.from).state;
+	        this.transitionOptions = transition.options();
+	    }
+	    HookBuilder.prototype.asyncHooks = function () {
+	        var onStartHooks = this.getOnStartHooks();
+	        var onExitHooks = this.getOnExitHooks();
+	        var onRetainHooks = this.getOnRetainHooks();
+	        var onEnterHooks = this.getOnEnterHooks();
+	        var onFinishHooks = this.getOnFinishHooks();
+	        var asyncHooks = [onStartHooks, onExitHooks, onRetainHooks, onEnterHooks, onFinishHooks];
+	        return asyncHooks.reduce(common_1.unnestR, []).filter(common_1.identity);
+	    };
+	    /**
+	     * Returns an array of newly built TransitionHook objects.
+	     *
+	     * - Finds all IEventHooks registered for the given `hookType` which matched the transition's [[TreeChanges]].
+	     * - Finds [[PathNode]] (or `PathNode[]`) to use as the TransitionHook context(s)
+	     * - For each of the [[PathNode]]s, creates a TransitionHook
+	     *
+	     * @param hookType the name of the hook registration function, e.g., 'onEnter', 'onFinish'.
+	     * @param matchingNodesProp selects which [[PathNode]]s from the [[IMatchingNodes]] object to create hooks for.
+	     * @param getLocals a function which accepts a [[PathNode]] and returns additional locals to provide to the hook as injectables
+	     * @param sortHooksFn a function which compares two HookTuple and returns <1, 0, or >1
+	     * @param options any specific Transition Hook Options
+	     */
+	    HookBuilder.prototype._buildNodeHooks = function (hookType, matchingNodesProp, sortHooksFn, options) {
+	        var _this = this;
+	        // Find all the matching registered hooks for a given hook type
+	        var matchingHooks = this._matchingHooks(hookType, this.treeChanges);
+	        if (!matchingHooks)
+	            return [];
+	        var makeTransitionHooks = function (hook) {
+	            // Fetch the Nodes that caused this hook to match.
+	            var matches = hook.matches(_this.treeChanges);
+	            // Select the PathNode[] that will be used as TransitionHook context objects
+	            var matchingNodes = matches[matchingNodesProp];
+	            // When invoking 'exiting' hooks, give them the "from path" for resolve data.
+	            // Everything else gets the "to path"
+	            var resolvePath = matchingNodesProp === 'exiting' ? _this.treeChanges.from : _this.treeChanges.to;
+	            var resolveContext = new resolveContext_1.ResolveContext(resolvePath);
+	            // Return an array of HookTuples
+	            return matchingNodes.map(function (node) {
+	                var _options = common_1.extend({ bind: hook.bind, traceData: { hookType: hookType, context: node } }, _this.baseHookOptions, options);
+	                var state = _options.stateHook ? node.state : null;
+	                var context = resolveContext.subContext(node.state);
+	                var transitionHook = new transitionHook_1.TransitionHook(_this.transition, state, hook.callback, context, _options);
+	                return { hook: hook, node: node, transitionHook: transitionHook };
+	            });
+	        };
+	        return matchingHooks.map(makeTransitionHooks)
+	            .reduce(common_1.unnestR, [])
+	            .sort(sortHooksFn)
+	            .map(function (tuple) { return tuple.transitionHook; });
+	    };
+	    /**
+	     * Finds all IEventHooks from:
+	     * - The Transition object instance hook registry
+	     * - The TransitionService ($transitions) global hook registry
+	     *
+	     * which matched:
+	     * - the eventType
+	     * - the matchCriteria (to, from, exiting, retained, entering)
+	     *
+	     * @returns an array of matched [[IEventHook]]s
+	     */
+	    HookBuilder.prototype._matchingHooks = function (hookName, treeChanges) {
+	        return [this.transition, this.$transitions] // Instance and Global hook registries
+	            .map(function (reg) { return reg.getHooks(hookName); }) // Get named hooks from registries
+	            .filter(common_1.assertPredicate(predicates_1.isArray, "broken event named: " + hookName)) // Sanity check
+	            .reduce(common_1.unnestR, []) // Un-nest IEventHook[][] to IEventHook[] array
+	            .filter(function (hook) { return hook.matches(treeChanges); }); // Only those satisfying matchCriteria
+	    };
+	    return HookBuilder;
+	}());
+	exports.HookBuilder = HookBuilder;
+	/**
+	 * A factory for a sort function for HookTuples.
+	 *
+	 * The sort function first compares the PathNode depth (how deep in the state tree a node is), then compares
+	 * the EventHook priority.
+	 *
+	 * @param reverseDepthSort a boolean, when true, reverses the sort order for the node depth
+	 * @returns a tuple sort function
+	 */
+	function tupleSort(reverseDepthSort) {
+	    if (reverseDepthSort === void 0) { reverseDepthSort = false; }
+	    return function nodeDepthThenPriority(l, r) {
+	        var factor = reverseDepthSort ? -1 : 1;
+	        var depthDelta = (l.node.state.path.length - r.node.state.path.length) * factor;
+	        return depthDelta !== 0 ? depthDelta : r.hook.priority - l.hook.priority;
+	    };
+	}
+
+
+/***/ },
+/* 17 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module resolve */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var hof_1 = __webpack_require__(5);
+	var trace_1 = __webpack_require__(12);
+	var coreservices_1 = __webpack_require__(6);
+	var interface_1 = __webpack_require__(18);
+	var resolvable_1 = __webpack_require__(19);
+	var pathFactory_1 = __webpack_require__(20);
+	var strings_1 = __webpack_require__(9);
+	var when = interface_1.resolvePolicies.when;
+	var ALL_WHENS = [when.EAGER, when.LAZY];
+	var EAGER_WHENS = [when.EAGER];
+	/**
+	 * Encapsulates Depenency Injection for a path of nodes
+	 *
+	 * UI-Router states are organized as a tree.
+	 * A nested state has a path of ancestors to the root of the tree.
+	 * When a state is being activated, each element in the path is wrapped as a [[PathNode]].
+	 * A `PathNode` is a stateful object that holds things like parameters and resolvables for the state being activated.
+	 *
+	 * The ResolveContext closes over the [[PathNode]]s, and provides DI for the last node in the path.
+	 */
+	var ResolveContext = (function () {
+	    function ResolveContext(_path) {
+	        this._path = _path;
+	    }
+	    /** Gets all the tokens found in the resolve context, de-duplicated */
+	    ResolveContext.prototype.getTokens = function () {
+	        return this._path.reduce(function (acc, node) { return acc.concat(node.resolvables.map(function (r) { return r.token; })); }, []).reduce(common_1.uniqR, []);
+	    };
+	    /**
+	     * Gets the Resolvable that matches the token
+	     *
+	     * Gets the last Resolvable that matches the token in this context, or undefined.
+	     * Throws an error if it doesn't exist in the ResolveContext
+	     */
+	    ResolveContext.prototype.getResolvable = function (token) {
+	        var matching = this._path.map(function (node) { return node.resolvables; })
+	            .reduce(common_1.unnestR, [])
+	            .filter(function (r) { return r.token === token; });
+	        return common_1.tail(matching);
+	    };
+	    /**
+	     * Returns a ResolveContext that includes a portion of this one
+	     *
+	     * Given a state, this method creates a new ResolveContext from this one.
+	     * The new context starts at the first node (root) and stops at the node for the `state` parameter.
+	     *
+	     * #### Why
+	     *
+	     * When a transition is created, the nodes in the "To Path" are injected from a ResolveContext.
+	     * A ResolveContext closes over a path of [[PathNode]]s and processes the resolvables.
+	     * The "To State" can inject values from its own resolvables, as well as those from all its ancestor state's (node's).
+	     * This method is used to create a narrower context when injecting ancestor nodes.
+	     *
+	     * @example
+	     * `let ABCD = new ResolveContext([A, B, C, D]);`
+	     *
+	     * Given a path `[A, B, C, D]`, where `A`, `B`, `C` and `D` are nodes for states `a`, `b`, `c`, `d`:
+	     * When injecting `D`, `D` should have access to all resolvables from `A`, `B`, `C`, `D`.
+	     * However, `B` should only be able to access resolvables from `A`, `B`.
+	     *
+	     * When resolving for the `B` node, first take the full "To Path" Context `[A,B,C,D]` and limit to the subpath `[A,B]`.
+	     * `let AB = ABCD.subcontext(a)`
+	     */
+	    ResolveContext.prototype.subContext = function (state) {
+	        return new ResolveContext(pathFactory_1.PathFactory.subPath(this._path, function (node) { return node.state === state; }));
+	    };
+	    /**
+	     * Adds Resolvables to the node that matches the state
+	     *
+	     * This adds a [[Resolvable]] (generally one created on the fly; not declared on a [[StateDeclaration.resolve]] block).
+	     * The resolvable is added to the node matching the `state` parameter.
+	     *
+	     * These new resolvables are not automatically fetched.
+	     * The calling code should either fetch them, fetch something that depends on them,
+	     * or rely on [[resolvePath]] being called when some state is being entered.
+	     *
+	     * Note: each resolvable's [[ResolvePolicy]] is merged with the state's policy, and the global default.
+	     *
+	     * @param newResolvables the new Resolvables
+	     * @param state Used to find the node to put the resolvable on
+	     */
+	    ResolveContext.prototype.addResolvables = function (newResolvables, state) {
+	        var node = common_1.find(this._path, hof_1.propEq('state', state));
+	        var keys = newResolvables.map(function (r) { return r.token; });
+	        node.resolvables = node.resolvables.filter(function (r) { return keys.indexOf(r.token) === -1; }).concat(newResolvables);
+	    };
+	    /**
+	     * Returns a promise for an array of resolved path Element promises
+	     *
+	     * @param when
+	     * @param trans
+	     * @returns {Promise<any>|any}
+	     */
+	    ResolveContext.prototype.resolvePath = function (when, trans) {
+	        var _this = this;
+	        if (when === void 0) { when = "LAZY"; }
+	        // This option determines which 'when' policy Resolvables we are about to fetch.
+	        var whenOption = common_1.inArray(ALL_WHENS, when) ? when : "LAZY";
+	        // If the caller specified EAGER, only the EAGER Resolvables are fetched.
+	        // if the caller specified LAZY, both EAGER and LAZY Resolvables are fetched.`
+	        var matchedWhens = whenOption === interface_1.resolvePolicies.when.EAGER ? EAGER_WHENS : ALL_WHENS;
+	        // get the subpath to the state argument, if provided
+	        trace_1.trace.traceResolvePath(this._path, when, trans);
+	        var promises = this._path.reduce(function (acc, node) {
+	            var matchesRequestedPolicy = function (resolvable) {
+	                return common_1.inArray(matchedWhens, resolvable.getPolicy(node.state).when);
+	            };
+	            var nodeResolvables = node.resolvables.filter(matchesRequestedPolicy);
+	            var subContext = _this.subContext(node.state);
+	            // For the matching Resolvables, start their async fetch process.
+	            var getResult = function (r) { return r.get(subContext, trans)
+	                .then(function (value) { return ({ token: r.token, value: value }); }); };
+	            return acc.concat(nodeResolvables.map(getResult));
+	        }, []);
+	        return coreservices_1.services.$q.all(promises);
+	    };
+	    ResolveContext.prototype.injector = function () {
+	        return new UIInjectorImpl(this);
+	    };
+	    ResolveContext.prototype.findNode = function (resolvable) {
+	        return common_1.find(this._path, function (node) { return common_1.inArray(node.resolvables, resolvable); });
+	    };
+	    /**
+	     * Gets the async dependencies of a Resolvable
+	     *
+	     * Given a Resolvable, returns its dependencies as a Resolvable[]
+	     */
+	    ResolveContext.prototype.getDependencies = function (resolvable) {
+	        var node = this.findNode(resolvable);
+	        // Find which other resolvables are "visible" to the `resolvable` argument
+	        // subpath stopping at resolvable's node, or the whole path (if the resolvable isn't in the path)
+	        var subPath = pathFactory_1.PathFactory.subPath(this._path, function (x) { return x === node; }) || this._path;
+	        var availableResolvables = subPath
+	            .reduce(function (acc, node) { return acc.concat(node.resolvables); }, []) //all of subpath's resolvables
+	            .filter(function (res) { return res !== resolvable; }); // filter out the `resolvable` argument
+	        var getDependency = function (token) {
+	            var matching = availableResolvables.filter(function (r) { return r.token === token; });
+	            if (matching.length)
+	                return common_1.tail(matching);
+	            var fromInjector = coreservices_1.services.$injector.get(token);
+	            if (!fromInjector) {
+	                throw new Error("Could not find Dependency Injection token: " + strings_1.stringify(token));
+	            }
+	            return new resolvable_1.Resolvable(token, function () { return fromInjector; }, [], fromInjector);
+	        };
+	        return resolvable.deps.map(getDependency);
+	    };
+	    return ResolveContext;
+	}());
+	exports.ResolveContext = ResolveContext;
+	var UIInjectorImpl = (function () {
+	    function UIInjectorImpl(context) {
+	        this.context = context;
+	        /** The native injector ($injector on ng1, Root Injector on ng2, justjs injector for everything else) */
+	        this.native = coreservices_1.services.$injector;
+	    }
+	    UIInjectorImpl.prototype.get = function (token) {
+	        var resolvable = this.context.getResolvable(token);
+	        if (resolvable) {
+	            if (!resolvable.resolved) {
+	                throw new Error("Resolvable async .get() not complete:" + strings_1.stringify(resolvable.token));
+	            }
+	            return resolvable.data;
+	        }
+	        return coreservices_1.services.$injector.get(token);
+	    };
+	    UIInjectorImpl.prototype.getAsync = function (token) {
+	        var resolvable = this.context.getResolvable(token);
+	        if (resolvable)
+	            return resolvable.get(this.context);
+	        return coreservices_1.services.$q.when(coreservices_1.services.$injector.get(token));
+	    };
+	    return UIInjectorImpl;
+	}());
+
+
+/***/ },
+/* 18 */
+/***/ function(module, exports) {
+
+	"use strict";
+	exports.resolvePolicies = {
+	    when: {
+	        LAZY: "LAZY",
+	        EAGER: "EAGER"
+	    },
+	    async: {
+	        WAIT: "WAIT",
+	        NOWAIT: "NOWAIT",
+	        RXWAIT: "RXWAIT"
+	    }
+	};
+
+
+/***/ },
+/* 19 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module resolve */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var coreservices_1 = __webpack_require__(6);
+	var trace_1 = __webpack_require__(12);
+	var strings_1 = __webpack_require__(9);
+	var predicates_1 = __webpack_require__(4);
+	// TODO: explicitly make this user configurable
+	exports.defaultResolvePolicy = {
+	    when: "LAZY",
+	    async: "WAIT"
+	};
+	/**
+	 * The basic building block for the resolve system.
+	 *
+	 * Resolvables encapsulate a state's resolve's resolveFn, the resolveFn's declared dependencies, the wrapped (.promise),
+	 * and the unwrapped-when-complete (.data) result of the resolveFn.
+	 *
+	 * Resolvable.get() either retrieves the Resolvable's existing promise, or else invokes resolve() (which invokes the
+	 * resolveFn) and returns the resulting promise.
+	 *
+	 * Resolvable.get() and Resolvable.resolve() both execute within a context path, which is passed as the first
+	 * parameter to those fns.
+	 */
+	var Resolvable = (function () {
+	    function Resolvable(arg1, resolveFn, deps, policy, data) {
+	        this.resolved = false;
+	        this.promise = undefined;
+	        if (arg1 instanceof Resolvable) {
+	            common_1.extend(this, arg1);
+	        }
+	        else if (predicates_1.isFunction(resolveFn)) {
+	            if (arg1 == null || arg1 == undefined)
+	                throw new Error("new Resolvable(): token argument is required");
+	            if (!predicates_1.isFunction(resolveFn))
+	                throw new Error("new Resolvable(): resolveFn argument must be a function");
+	            this.token = arg1;
+	            this.policy = policy;
+	            this.resolveFn = resolveFn;
+	            this.deps = deps || [];
+	            this.data = data;
+	            this.resolved = data !== undefined;
+	            this.promise = this.resolved ? coreservices_1.services.$q.when(this.data) : undefined;
+	        }
+	        else if (predicates_1.isObject(arg1) && arg1.token && predicates_1.isFunction(arg1.resolveFn)) {
+	            var literal = arg1;
+	            return new Resolvable(literal.token, literal.resolveFn, literal.deps, literal.policy, literal.data);
+	        }
+	    }
+	    Resolvable.prototype.getPolicy = function (state) {
+	        var thisPolicy = this.policy || {};
+	        var statePolicy = state && state.resolvePolicy || {};
+	        return {
+	            when: thisPolicy.when || statePolicy.when || exports.defaultResolvePolicy.when,
+	            async: thisPolicy.async || statePolicy.async || exports.defaultResolvePolicy.async,
+	        };
+	    };
+	    /**
+	     * Asynchronously resolve this Resolvable's data
+	     *
+	     * Given a ResolveContext that this Resolvable is found in:
+	     * Wait for this Resolvable's dependencies, then invoke this Resolvable's function
+	     * and update the Resolvable's state
+	     */
+	    Resolvable.prototype.resolve = function (resolveContext, trans) {
+	        var _this = this;
+	        var $q = coreservices_1.services.$q;
+	        // Gets all dependencies from ResolveContext and wait for them to be resolved
+	        var getResolvableDependencies = function () {
+	            return $q.all(resolveContext.getDependencies(_this).map(function (r) {
+	                return r.get(resolveContext, trans);
+	            }));
+	        };
+	        // Invokes the resolve function passing the resolved dependencies as arguments
+	        var invokeResolveFn = function (resolvedDeps) {
+	            return _this.resolveFn.apply(null, resolvedDeps);
+	        };
+	        /**
+	         * For RXWAIT policy:
+	         *
+	         * Given an observable returned from a resolve function:
+	         * - enables .cache() mode (this allows multicast subscribers)
+	         * - then calls toPromise() (this triggers subscribe() and thus fetches)
+	         * - Waits for the promise, then return the cached observable (not the first emitted value).
+	         */
+	        var waitForRx = function (observable$) {
+	            var cached = observable$.cache();
+	            return cached.toPromise().then(function () { return cached; });
+	        };
+	        // If the resolve policy is RXWAIT, wait for the observable to emit something. otherwise pass through.
+	        var node = resolveContext.findNode(this);
+	        var state = node && node.state;
+	        var maybeWaitForRx = this.getPolicy(state).async === "RXWAIT" ? waitForRx : function (x) { return x; };
+	        // After the final value has been resolved, update the state of the Resolvable
+	        var applyResolvedValue = function (resolvedValue) {
+	            _this.data = resolvedValue;
+	            _this.resolved = true;
+	            trace_1.trace.traceResolvableResolved(_this, trans);
+	            return _this.data;
+	        };
+	        // Sets the promise property first, then getsResolvableDependencies in the context of the promise chain. Always waits one tick.
+	        return this.promise = $q.when()
+	            .then(getResolvableDependencies)
+	            .then(invokeResolveFn)
+	            .then(maybeWaitForRx)
+	            .then(applyResolvedValue);
+	    };
+	    /**
+	     * Gets a promise for this Resolvable's data.
+	     *
+	     * Fetches the data and returns a promise.
+	     * Returns the existing promise if it has already been fetched once.
+	     */
+	    Resolvable.prototype.get = function (resolveContext, trans) {
+	        return this.promise || this.resolve(resolveContext, trans);
+	    };
+	    Resolvable.prototype.toString = function () {
+	        return "Resolvable(token: " + strings_1.stringify(this.token) + ", requires: [" + this.deps.map(strings_1.stringify) + "])";
+	    };
+	    Resolvable.prototype.clone = function () {
+	        return new Resolvable(this);
+	    };
+	    return Resolvable;
+	}());
+	exports.Resolvable = Resolvable;
+
+
+/***/ },
+/* 20 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/** @module path */ /** for typedoc */
+	"use strict";
+	var common_1 = __webpack_require__(3);
+	var hof_1 = __webpack_require__(5);
+	var targetState_1 = __webpack_require__(14);
+	var node_1 = __webpack_require__(21);
+	/**
+	 * This class contains functions which convert TargetStates, Nodes and paths from one type to another.
+	 */
+	var PathFactory = (function () {
+	    function PathFactory() {
+	    }
+	    /** Given a PathNode[], create an TargetState */
+	    PathFactory.makeTargetState = function (path) {
+	        var state = common_1.tail(path).state;
+	        return new targetState_1.TargetState(state, state, path.map(hof_1.prop("paramValues")).reduce(common_1.mergeR, {}));
+	    };
+	    PathFactory.buildPath = function (targetState) {
+	        var toParams = targetState.params();
+	        return targetState.$state().path.map(function (state) { return new node_1.PathNode(state).applyRawParams(toParams); });
+	    };
+	    /** Given a fromPath: PathNode[] and a TargetState, builds a toPath: PathNode[] */
+	    PathFactory.buildToPath = function (fromPath, targetState) {
+	        var toPath = PathFactory.buildPath(targetState);
+	        if (targetState.options().inherit) {
+	            return PathFactory.inheritParams(fromPath, toPath, Object.keys(targetState.params()));
+	        }
+	        return toPath;
+	    };
+	    /**
+	     * Creates ViewConfig objects and adds to nodes.
+	     *
+	     * On each [[PathNode]], creates ViewConfig objects from the views: property of the node's state
+	     */
+	    PathFactory.applyViewConfigs = function ($view, path, states) {
+	        // Only apply the viewConfigs to the nodes for the given states
+	        path.filter(function (node) { return common_1.inArray(states, node.state); }).forEach(function (node) {
+	            var viewDecls = common_1.values(node.state.views || {});
+	            var subPath = PathFactory.subPath(path, function (n) { return n === node; });
+	            var viewConfigs = viewDecls.map(function (view) { return $view.createViewConfig(subPath, view); });
+	            node.views = viewConfigs.reduce(common_1.unnestR, []);
+	        });
+	    };
+	    /**
+	     * Given a fromPath and a toPath, returns a new to path which inherits parameters from the fromPath
+	     *
+	     * For a parameter in a node to be inherited from the from path:
+	     * - The toPath's node must have a matching node in the fromPath (by state).
+	     * - The parameter name must not be found in the toKeys parameter array.
+	     *
+	     * Note: the keys provided in toKeys are intended to be those param keys explicitly specified by some
+	     * caller, for instance, $state.transitionTo(..., toParams).  If a key was found in toParams,
+	     * it is not inherited from the fromPath.
+	     */
+	    PathFactory.inheritParams = function (fromPath, toPath, toKeys) {
+	        if (toKeys === void 0) { toKeys = []; }
+	        function nodeParamVals(path, state) {
+	            var node = common_1.find(path, hof_1.propEq('state', state));
+	            return common_1.extend({}, node && node.paramValues);
+	        }
+	        /**
+	         * Given an [[PathNode]] "toNode", return a new [[PathNode]] with param values inherited from the
+	         * matching node in fromPath.  Only inherit keys that aren't found in "toKeys" from the node in "fromPath""
+	         */
+	        function makeInheritedParamsNode(toNode) {
+	            // All param values for the node (may include default key/vals, when key was not found in toParams)
+	            var toParamVals = common_1.extend({}, toNode && toNode.paramValues);
+	            // limited to only those keys found in toParams
+	            var incomingParamVals = common_1.pick(toParamVals, toKeys);
+	            toParamVals = common_1.omit(toParamVals, toKeys);
+	            var fromParamVals = nodeParamVals(fromPath, toNode.state) || {};
+	            // extend toParamVals with any fromParamVals, then override any of those those with incomingParamVals
+	            var ownParamVals = common_1.extend(toParamVals, fromParamVals, incomingParamVals);
+	            return new node_1.PathNode(toNode.state).applyRawParams(ownParamVals);
+	        }
+	        // The param keys specified by the incoming toParams
+	        return toPath.map(makeInheritedParamsNode);
+	    };
+	    /**
+	     * Computes the tree changes (entering, exiting) between a fromPath and toPath.
+	     */
+	    PathFactory.treeChanges = function (fromPath, toPath, reloadState) {
+	        var keep = 0, max = Math.min(fromPath.length, toPath.length);
+	        var staticParams = function (state) { return state.parameters({ inherit: false }).filter(hof_1.not(hof_1.prop('dynamic'))).map(hof_1.prop('id')); };
+	        var nodesMatch = function (node1, node2) { return node1.equals(node2, staticParams(node1.state)); };
+	        while (keep < max && fromPath[keep].state !== reloadState && nodesMatch(fromPath[keep], toPath[keep])) {
+	            keep++;
+	        }
+	        /** Given a retained node, return a new node which uses the to node's param values */
+	        function applyToParams(retainedNode, idx) {
+	            var cloned = node_1.PathNode.clone(retainedNode);
+	            cloned.paramValues = toPath[idx].paramValues;
+	            return cloned;
+	        }
+	        var from, retained, exiting, entering, to;
+	        from = fromPath;
+	        retained = from.slice(0, keep);
+	        exiting = from.slice(keep);
+	        // Create a new retained path (with shallow copies of nodes) which have the params of the toPath mapped
+	        var retainedWithToParams = retained.map(applyToParams);
+	        entering = toPath.slice(keep);
+	        to = (retainedWithToParams).concat(entering);
+	        return { from: from, to: to, retained: retained, exiting: exiting, entering: entering };
+	    };
+	    /**
+	     * Return a subpath of a path, which stops at the first matching node
+	     *
+	     * Given an array of nodes, returns a subset of the array starting from the first node,
+	     * stopping when the first node matches the predicate.
+	     *
+	     * @param path a path of [[PathNode]]s
+	     * @param predicate a [[Predicate]] fn that matches [[PathNode]]s
+	     * @returns a subpath up to the matching node, or undefined if no match is found
+	     */
+	    PathFactory.subPath = function (path, predicate) {
+	        var node = common_1.find(path, predicate);
+	        var elementIdx = path.indexOf(node);
+	        return elementIdx === -1 ? undefined : path.slice(0, elementIdx + 1);
+	    };
+	    /** Gets the raw parameter values from a path */
+	    PathFactory.paramValues = function (path) { return path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {}); };
+	    return PathFactory;
+	}());
+	exports.PathFactory = PathFactory;
+
+
+/***/ },
+/* 21 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module path */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var hof_1 = __webpack_require__(5);
+	var param_1 = __webpack_require__(22);
+	/**
+	 * A node in a [[TreeChanges]] path
+	 *
+	 * For a [[TreeChanges]] path, this class holds the stateful information for a single node in the path.
+	 * Each PathNode corresponds to a state being entered, exited, or retained.
+	 * The stateful information includes parameter values and resolve data.
+	 */
+	var PathNode = (function () {
+	    function PathNode(state) {
+	        if (state instanceof PathNode) {
+	            var node = state;
+	            this.state = node.state;
+	            this.paramSchema = node.paramSchema.slice();
+	            this.paramValues = common_1.extend({}, node.paramValues);
+	            this.resolvables = node.resolvables.slice();
+	            this.views = node.views && node.views.slice();
+	        }
+	        else {
+	            this.state = state;
+	            this.paramSchema = state.parameters({ inherit: false });
+	            this.paramValues = {};
+	            this.resolvables = state.resolvables.map(function (res) { return res.clone(); });
+	        }
+	    }
+	    /** Sets [[paramValues]] for the node, from the values of an object hash */
+	    PathNode.prototype.applyRawParams = function (params) {
+	        var getParamVal = function (paramDef) { return [paramDef.id, paramDef.value(params[paramDef.id])]; };
+	        this.paramValues = this.paramSchema.reduce(function (memo, pDef) { return common_1.applyPairs(memo, getParamVal(pDef)); }, {});
+	        return this;
+	    };
+	    /** Gets a specific [[Param]] metadata that belongs to the node */
+	    PathNode.prototype.parameter = function (name) {
+	        return common_1.find(this.paramSchema, hof_1.propEq("id", name));
+	    };
+	    /**
+	     * @returns true if the state and parameter values for another PathNode are
+	     * equal to the state and param values for this PathNode
+	     */
+	    PathNode.prototype.equals = function (node, keys) {
+	        var _this = this;
+	        if (keys === void 0) { keys = this.paramSchema.map(hof_1.prop('id')); }
+	        var paramValsEq = function (key) { return _this.parameter(key).type.equals(_this.paramValues[key], node.paramValues[key]); };
+	        return this.state === node.state && keys.map(paramValsEq).reduce(common_1.allTrueR, true);
+	    };
+	    /** Returns a clone of the PathNode */
+	    PathNode.clone = function (node) {
+	        return new PathNode(node);
+	    };
+	    /**
+	     * Returns a new path which is a subpath of the first path which matched the second path.
+	     *
+	     * The new path starts from root and contains any nodes that match the nodes in the second path.
+	     * Nodes are compared using their state property and parameter values.
+	     */
+	    PathNode.matching = function (pathA, pathB) {
+	        var matching = [];
+	        for (var i = 0; i < pathA.length && i < pathB.length; i++) {
+	            var a = pathA[i], b = pathB[i];
+	            if (a.state !== b.state)
+	                break;
+	            if (!param_1.Param.equals(a.paramSchema, a.paramValues, b.paramValues))
+	                break;
+	            matching.push(a);
+	        }
+	        return matching;
+	    };
+	    return PathNode;
+	}());
+	exports.PathNode = PathNode;
+
+
+/***/ },
+/* 22 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module params */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var hof_1 = __webpack_require__(5);
+	var predicates_1 = __webpack_require__(4);
+	var coreservices_1 = __webpack_require__(6);
+	var urlMatcherConfig_1 = __webpack_require__(23);
+	var type_1 = __webpack_require__(24);
+	var paramTypes_1 = __webpack_require__(25);
+	var hasOwn = Object.prototype.hasOwnProperty;
+	var isShorthand = function (cfg) { return ["value", "type", "squash", "array", "dynamic"].filter(hasOwn.bind(cfg || {})).length === 0; };
+	(function (DefType) {
+	    DefType[DefType["PATH"] = 0] = "PATH";
+	    DefType[DefType["SEARCH"] = 1] = "SEARCH";
+	    DefType[DefType["CONFIG"] = 2] = "CONFIG";
+	})(exports.DefType || (exports.DefType = {}));
+	var DefType = exports.DefType;
+	function unwrapShorthand(cfg) {
+	    cfg = isShorthand(cfg) && { value: cfg } || cfg;
+	    return common_1.extend(cfg, {
+	        $$fn: predicates_1.isInjectable(cfg.value) ? cfg.value : function () { return cfg.value; }
+	    });
+	}
+	function getType(cfg, urlType, location, id) {
+	    if (cfg.type && urlType && urlType.name !== 'string')
+	        throw new Error("Param '" + id + "' has two type configurations.");
+	    if (cfg.type && urlType && urlType.name === 'string' && paramTypes_1.paramTypes.type(cfg.type))
+	        return paramTypes_1.paramTypes.type(cfg.type);
+	    if (urlType)
+	        return urlType;
+	    if (!cfg.type)
+	        return (location === DefType.CONFIG ? paramTypes_1.paramTypes.type("any") : paramTypes_1.paramTypes.type("string"));
+	    return cfg.type instanceof type_1.ParamType ? cfg.type : paramTypes_1.paramTypes.type(cfg.type);
+	}
+	/**
+	 * returns false, true, or the squash value to indicate the "default parameter url squash policy".
+	 */
+	function getSquashPolicy(config, isOptional) {
+	    var squash = config.squash;
+	    if (!isOptional || squash === false)
+	        return false;
+	    if (!predicates_1.isDefined(squash) || squash == null)
+	        return urlMatcherConfig_1.matcherConfig.defaultSquashPolicy();
+	    if (squash === true || predicates_1.isString(squash))
+	        return squash;
+	    throw new Error("Invalid squash policy: '" + squash + "'. Valid policies: false, true, or arbitrary string");
+	}
+	function getReplace(config, arrayMode, isOptional, squash) {
+	    var replace, configuredKeys, defaultPolicy = [
+	        { from: "", to: (isOptional || arrayMode ? undefined : "") },
+	        { from: null, to: (isOptional || arrayMode ? undefined : "") }
+	    ];
+	    replace = predicates_1.isArray(config.replace) ? config.replace : [];
+	    if (predicates_1.isString(squash))
+	        replace.push({ from: squash, to: undefined });
+	    configuredKeys = common_1.map(replace, hof_1.prop("from"));
+	    return common_1.filter(defaultPolicy, function (item) { return configuredKeys.indexOf(item.from) === -1; }).concat(replace);
+	}
+	var Param = (function () {
+	    function Param(id, type, config, location) {
+	        config = unwrapShorthand(config);
+	        type = getType(config, type, location, id);
+	        var arrayMode = getArrayMode();
+	        type = arrayMode ? type.$asArray(arrayMode, location === DefType.SEARCH) : type;
+	        var isOptional = config.value !== undefined;
+	        var dynamic = predicates_1.isDefined(config.dynamic) ? !!config.dynamic : !!type.dynamic;
+	        var squash = getSquashPolicy(config, isOptional);
+	        var replace = getReplace(config, arrayMode, isOptional, squash);
+	        // array config: param name (param[]) overrides default settings.  explicit config overrides param name.
+	        function getArrayMode() {
+	            var arrayDefaults = { array: (location === DefType.SEARCH ? "auto" : false) };
+	            var arrayParamNomenclature = id.match(/\[\]$/) ? { array: true } : {};
+	            return common_1.extend(arrayDefaults, arrayParamNomenclature, config).array;
+	        }
+	        common_1.extend(this, { id: id, type: type, location: location, squash: squash, replace: replace, isOptional: isOptional, dynamic: dynamic, config: config, array: arrayMode });
+	    }
+	    Param.prototype.isDefaultValue = function (value) {
+	        return this.isOptional && this.type.equals(this.value(), value);
+	    };
+	    /**
+	     * [Internal] Gets the decoded representation of a value if the value is defined, otherwise, returns the
+	     * default value, which may be the result of an injectable function.
+	     */
+	    Param.prototype.value = function (value) {
+	        var _this = this;
+	        /**
+	         * [Internal] Get the default value of a parameter, which may be an injectable function.
+	         */
+	        var $$getDefaultValue = function () {
+	            if (!coreservices_1.services.$injector)
+	                throw new Error("Injectable functions cannot be called at configuration time");
+	            var defaultValue = coreservices_1.services.$injector.invoke(_this.config.$$fn);
+	            if (defaultValue !== null && defaultValue !== undefined && !_this.type.is(defaultValue))
+	                throw new Error("Default value (" + defaultValue + ") for parameter '" + _this.id + "' is not an instance of ParamType (" + _this.type.name + ")");
+	            return defaultValue;
+	        };
+	        var $replace = function (val) {
+	            var replacement = common_1.map(common_1.filter(_this.replace, hof_1.propEq('from', val)), hof_1.prop("to"));
+	            return replacement.length ? replacement[0] : val;
+	        };
+	        value = $replace(value);
+	        return !predicates_1.isDefined(value) ? $$getDefaultValue() : this.type.$normalize(value);
+	    };
+	    Param.prototype.isSearch = function () {
+	        return this.location === DefType.SEARCH;
+	    };
+	    Param.prototype.validates = function (value) {
+	        // There was no parameter value, but the param is optional
+	        if ((!predicates_1.isDefined(value) || value === null) && this.isOptional)
+	            return true;
+	        // The value was not of the correct ParamType, and could not be decoded to the correct ParamType
+	        var normalized = this.type.$normalize(value);
+	        if (!this.type.is(normalized))
+	            return false;
+	        // The value was of the correct type, but when encoded, did not match the ParamType's regexp
+	        var encoded = this.type.encode(normalized);
+	        return !(predicates_1.isString(encoded) && !this.type.pattern.exec(encoded));
+	    };
+	    Param.prototype.toString = function () {
+	        return "{Param:" + this.id + " " + this.type + " squash: '" + this.squash + "' optional: " + this.isOptional + "}";
+	    };
+	    /** Creates a new [[Param]] from a CONFIG block */
+	    Param.fromConfig = function (id, type, config) {
+	        return new Param(id, type, config, DefType.CONFIG);
+	    };
+	    /** Creates a new [[Param]] from a url PATH */
+	    Param.fromPath = function (id, type, config) {
+	        return new Param(id, type, config, DefType.PATH);
+	    };
+	    /** Creates a new [[Param]] from a url SEARCH */
+	    Param.fromSearch = function (id, type, config) {
+	        return new Param(id, type, config, DefType.SEARCH);
+	    };
+	    Param.values = function (params, values) {
+	        if (values === void 0) { values = {}; }
+	        return params.map(function (param) { return [param.id, param.value(values[param.id])]; }).reduce(common_1.applyPairs, {});
+	    };
+	    /**
+	     * Finds [[Param]] objects which have different param values
+	     *
+	     * Filters a list of [[Param]] objects to only those whose parameter values differ in two param value objects
+	     *
+	     * @param params: The list of Param objects to filter
+	     * @param values1: The first set of parameter values
+	     * @param values2: the second set of parameter values
+	     *
+	     * @returns any Param objects whose values were different between values1 and values2
+	     */
+	    Param.changed = function (params, values1, values2) {
+	        if (values1 === void 0) { values1 = {}; }
+	        if (values2 === void 0) { values2 = {}; }
+	        return params.filter(function (param) { return !param.type.equals(values1[param.id], values2[param.id]); });
+	    };
+	    /**
+	     * Checks if two param value objects are equal (for a set of [[Param]] objects)
+	     *
+	     * @param params The list of [[Param]] objects to check
+	     * @param values1 The first set of param values
+	     * @param values2 The second set of param values
+	     *
+	     * @returns true if the param values in values1 and values2 are equal
+	     */
+	    Param.equals = function (params, values1, values2) {
+	        if (values1 === void 0) { values1 = {}; }
+	        if (values2 === void 0) { values2 = {}; }
+	        return Param.changed(params, values1, values2).length === 0;
+	    };
+	    /** Returns true if a the parameter values are valid, according to the Param definitions */
+	    Param.validates = function (params, values) {
+	        if (values === void 0) { values = {}; }
+	        return params.map(function (param) { return param.validates(values[param.id]); }).reduce(common_1.allTrueR, true);
+	    };
+	    return Param;
+	}());
+	exports.Param = Param;
+
+
+/***/ },
+/* 23 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module url */ /** for typedoc */
+	var predicates_1 = __webpack_require__(4);
+	var MatcherConfig = (function () {
+	    function MatcherConfig() {
+	        this._isCaseInsensitive = false;
+	        this._isStrictMode = true;
+	        this._defaultSquashPolicy = false;
+	    }
+	    MatcherConfig.prototype.caseInsensitive = function (value) {
+	        return this._isCaseInsensitive = predicates_1.isDefined(value) ? value : this._isCaseInsensitive;
+	    };
+	    MatcherConfig.prototype.strictMode = function (value) {
+	        return this._isStrictMode = predicates_1.isDefined(value) ? value : this._isStrictMode;
+	    };
+	    MatcherConfig.prototype.defaultSquashPolicy = function (value) {
+	        if (predicates_1.isDefined(value) && value !== true && value !== false && !predicates_1.isString(value))
+	            throw new Error("Invalid squash policy: " + value + ". Valid policies: false, true, arbitrary-string");
+	        return this._defaultSquashPolicy = predicates_1.isDefined(value) ? value : this._defaultSquashPolicy;
+	    };
+	    return MatcherConfig;
+	}());
+	exports.MatcherConfig = MatcherConfig;
+	// TODO: Do not export global instance; create one in UIRouter() constructor
+	exports.matcherConfig = new MatcherConfig();
+
+
+/***/ },
+/* 24 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module params */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	/**
+	 * Wraps up a `ParamType` object to handle array values.
+	 */
+	function ArrayType(type, mode) {
+	    var _this = this;
+	    // Wrap non-array value as array
+	    function arrayWrap(val) { return predicates_1.isArray(val) ? val : (predicates_1.isDefined(val) ? [val] : []); }
+	    // Unwrap array value for "auto" mode. Return undefined for empty array.
+	    function arrayUnwrap(val) {
+	        switch (val.length) {
+	            case 0: return undefined;
+	            case 1: return mode === "auto" ? val[0] : val;
+	            default: return val;
+	        }
+	    }
+	    // Wraps type (.is/.encode/.decode) functions to operate on each value of an array
+	    function arrayHandler(callback, allTruthyMode) {
+	        return function handleArray(val) {
+	            if (predicates_1.isArray(val) && val.length === 0)
+	                return val;
+	            var arr = arrayWrap(val);
+	            var result = common_1.map(arr, callback);
+	            return (allTruthyMode === true) ? common_1.filter(result, function (x) { return !x; }).length === 0 : arrayUnwrap(result);
+	        };
+	    }
+	    // Wraps type (.equals) functions to operate on each value of an array
+	    function arrayEqualsHandler(callback) {
+	        return function handleArray(val1, val2) {
+	            var left = arrayWrap(val1), right = arrayWrap(val2);
+	            if (left.length !== right.length)
+	                return false;
+	            for (var i = 0; i < left.length; i++) {
+	                if (!callback(left[i], right[i]))
+	                    return false;
+	            }
+	            return true;
+	        };
+	    }
+	    ['encode', 'decode', 'equals', '$normalize'].map(function (name) {
+	        _this[name] = (name === 'equals' ? arrayEqualsHandler : arrayHandler)(type[name].bind(type));
+	    });
+	    common_1.extend(this, {
+	        dynamic: type.dynamic,
+	        name: type.name,
+	        pattern: type.pattern,
+	        is: arrayHandler(type.is.bind(type), true),
+	        $arrayMode: mode
+	    });
+	}
+	/**
+	 * A class that implements Custom Parameter Type functionality.
+	 *
+	 * This class has naive implementations for all the [[ParamTypeDefinition]] methods.
+	 *
+	 * An instance of this class is created when a custom [[ParamTypeDefinition]] object is registered with the [[UrlMatcherFactory.type]].
+	 *
+	 * Used by [[UrlMatcher]] when matching or formatting URLs, or comparing and validating parameter values.
+	 *
+	 * @example
+	 * ```
+	 *
+	 * {
+	 *   decode: function(val) { return parseInt(val, 10); },
+	 *   encode: function(val) { return val && val.toString(); },
+	 *   equals: function(a, b) { return this.is(a) && a === b; },
+	 *   is: function(val) { return angular.isNumber(val) && isFinite(val) && val % 1 === 0; },
+	 *   pattern: /\d+/
+	 * }
+	 * ```
+	 */
+	var ParamType = (function () {
+	    /**
+	     * @param def  A configuration object which contains the custom type definition.  The object's
+	     *        properties will override the default methods and/or pattern in `ParamType`'s public interface.
+	     * @returns a new ParamType object
+	     */
+	    function ParamType(def) {
+	        this.pattern = /.*/;
+	        common_1.extend(this, def);
+	    }
+	    // consider these four methods to be "abstract methods" that should be overridden
+	    /** @inheritdoc */
+	    ParamType.prototype.is = function (val, key) { return true; };
+	    /** @inheritdoc */
+	    ParamType.prototype.encode = function (val, key) { return val; };
+	    /** @inheritdoc */
+	    ParamType.prototype.decode = function (val, key) { return val; };
+	    /** @inheritdoc */
+	    ParamType.prototype.equals = function (a, b) { return a == b; };
+	    ParamType.prototype.$subPattern = function () {
+	        var sub = this.pattern.toString();
+	        return sub.substr(1, sub.length - 2);
+	    };
+	    ParamType.prototype.toString = function () {
+	        return "{ParamType:" + this.name + "}";
+	    };
+	    /** Given an encoded string, or a decoded object, returns a decoded object */
+	    ParamType.prototype.$normalize = function (val) {
+	        return this.is(val) ? val : this.decode(val);
+	    };
+	    /**
+	     * Wraps an existing custom ParamType as an array of ParamType, depending on 'mode'.
+	     * e.g.:
+	     * - urlmatcher pattern "/path?{queryParam[]:int}"
+	     * - url: "/path?queryParam=1&queryParam=2
+	     * - $stateParams.queryParam will be [1, 2]
+	     * if `mode` is "auto", then
+	     * - url: "/path?queryParam=1 will create $stateParams.queryParam: 1
+	     * - url: "/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2]
+	     */
+	    ParamType.prototype.$asArray = function (mode, isSearch) {
+	        if (!mode)
+	            return this;
+	        if (mode === "auto" && !isSearch)
+	            throw new Error("'auto' array mode is for query parameters only");
+	        return new ArrayType(this, mode);
+	    };
+	    return ParamType;
+	}());
+	exports.ParamType = ParamType;
+
+
+/***/ },
+/* 25 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module params */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var hof_1 = __webpack_require__(5);
+	var coreservices_1 = __webpack_require__(6);
+	var type_1 = __webpack_require__(24);
+	// Use tildes to pre-encode slashes.
+	// If the slashes are simply URLEncoded, the browser can choose to pre-decode them,
+	// and bidirectional encoding/decoding fails.
+	// Tilde was chosen because it's not a RFC 3986 section 2.2 Reserved Character
+	function valToString(val) { return val != null ? val.toString().replace(/~/g, "~~").replace(/\//g, "~2F") : val; }
+	function valFromString(val) { return val != null ? val.toString().replace(/~2F/g, "/").replace(/~~/g, "~") : val; }
+	var ParamTypes = (function () {
+	    function ParamTypes() {
+	        this.enqueue = true;
+	        this.typeQueue = [];
+	        this.defaultTypes = {
+	            "hash": {
+	                encode: valToString,
+	                decode: valFromString,
+	                is: hof_1.is(String),
+	                pattern: /.*/,
+	                equals: function (a, b) { return a == b; } // allow coersion for null/undefined/""
+	            },
+	            "string": {
+	                encode: valToString,
+	                decode: valFromString,
+	                is: hof_1.is(String),
+	                pattern: /[^/]*/
+	            },
+	            "int": {
+	                encode: valToString,
+	                decode: function (val) { return parseInt(val, 10); },
+	                is: function (val) { return predicates_1.isDefined(val) && this.decode(val.toString()) === val; },
+	                pattern: /-?\d+/
+	            },
+	            "bool": {
+	                encode: function (val) { return val && 1 || 0; },
+	                decode: function (val) { return parseInt(val, 10) !== 0; },
+	                is: hof_1.is(Boolean),
+	                pattern: /0|1/
+	            },
+	            "date": {
+	                encode: function (val) {
+	                    return !this.is(val) ? undefined : [
+	                        val.getFullYear(),
+	                        ('0' + (val.getMonth() + 1)).slice(-2),
+	                        ('0' + val.getDate()).slice(-2)
+	                    ].join("-");
+	                },
+	                decode: function (val) {
+	                    if (this.is(val))
+	                        return val;
+	                    var match = this.capture.exec(val);
+	                    return match ? new Date(match[1], match[2] - 1, match[3]) : undefined;
+	                },
+	                is: function (val) { return val instanceof Date && !isNaN(val.valueOf()); },
+	                equals: function (l, r) {
+	                    return ['getFullYear', 'getMonth', 'getDate']
+	                        .reduce(function (acc, fn) { return acc && l[fn]() === r[fn](); }, true);
+	                },
+	                pattern: /[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,
+	                capture: /([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/
+	            },
+	            "json": {
+	                encode: common_1.toJson,
+	                decode: common_1.fromJson,
+	                is: hof_1.is(Object),
+	                equals: common_1.equals,
+	                pattern: /[^/]*/
+	            },
+	            "any": {
+	                encode: common_1.identity,
+	                decode: common_1.identity,
+	                equals: common_1.equals,
+	                pattern: /.*/
+	            }
+	        };
+	        // Register default types. Store them in the prototype of this.types.
+	        var makeType = function (definition, name) { return new type_1.ParamType(common_1.extend({ name: name }, definition)); };
+	        this.types = common_1.inherit(common_1.map(this.defaultTypes, makeType), {});
+	    }
+	    ParamTypes.prototype.type = function (name, definition, definitionFn) {
+	        if (!predicates_1.isDefined(definition))
+	            return this.types[name];
+	        if (this.types.hasOwnProperty(name))
+	            throw new Error("A type named '" + name + "' has already been defined.");
+	        this.types[name] = new type_1.ParamType(common_1.extend({ name: name }, definition));
+	        if (definitionFn) {
+	            this.typeQueue.push({ name: name, def: definitionFn });
+	            if (!this.enqueue)
+	                this._flushTypeQueue();
+	        }
+	        return this;
+	    };
+	    ParamTypes.prototype._flushTypeQueue = function () {
+	        while (this.typeQueue.length) {
+	            var type = this.typeQueue.shift();
+	            if (type.pattern)
+	                throw new Error("You cannot override a type's .pattern at runtime.");
+	            common_1.extend(this.types[type.name], coreservices_1.services.$injector.invoke(type.def));
+	        }
+	    };
+	    return ParamTypes;
+	}());
+	exports.ParamTypes = ParamTypes;
+	exports.paramTypes = new ParamTypes();
+
+
+/***/ },
+/* 26 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module core */ /** */
+	var urlMatcherFactory_1 = __webpack_require__(27);
+	var urlRouter_1 = __webpack_require__(29);
+	var state_1 = __webpack_require__(30);
+	var urlRouter_2 = __webpack_require__(29);
+	var transitionService_1 = __webpack_require__(31);
+	var view_1 = __webpack_require__(37);
+	var stateRegistry_1 = __webpack_require__(38);
+	var stateService_1 = __webpack_require__(43);
+	var globals_1 = __webpack_require__(44);
+	/**
+	 * The master class used to instantiate an instance of UI-Router.
+	 *
+	 * This class instantiates and wires the global UI-Router services.
+	 *
+	 * After instantiating a new instance of the Router class, configure it for your app.  For instance, register
+	 * your app states with the [[stateRegistry]] (and set url options using ...).  Then, tell UI-Router to monitor
+	 * the URL by calling `urlRouter.listen()` ([[URLRouter.listen]])
+	 */
+	var UIRouter = (function () {
+	    function UIRouter() {
+	        this.viewService = new view_1.ViewService();
+	        this.transitionService = new transitionService_1.TransitionService(this);
+	        this.globals = new globals_1.Globals(this.transitionService);
+	        this.urlMatcherFactory = new urlMatcherFactory_1.UrlMatcherFactory();
+	        this.urlRouterProvider = new urlRouter_1.UrlRouterProvider(this.urlMatcherFactory, this.globals.params);
+	        this.urlRouter = new urlRouter_2.UrlRouter(this.urlRouterProvider);
+	        this.stateRegistry = new stateRegistry_1.StateRegistry(this.urlMatcherFactory, this.urlRouterProvider);
+	        /** @hidden TODO: move this to ng1.ts */
+	        this.stateProvider = new state_1.StateProvider(this.stateRegistry);
+	        this.stateService = new stateService_1.StateService(this);
+	        this.viewService.rootContext(this.stateRegistry.root());
+	        this.globals.$current = this.stateRegistry.root();
+	        this.globals.current = this.globals.$current.self;
+	    }
+	    return UIRouter;
+	}());
+	exports.UIRouter = UIRouter;
+
+
+/***/ },
+/* 27 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module url */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var urlMatcher_1 = __webpack_require__(28);
+	var urlMatcherConfig_1 = __webpack_require__(23);
+	var param_1 = __webpack_require__(22);
+	var paramTypes_1 = __webpack_require__(25);
+	/** @hidden */
+	function getDefaultConfig() {
+	    return {
+	        strict: urlMatcherConfig_1.matcherConfig.strictMode(),
+	        caseInsensitive: urlMatcherConfig_1.matcherConfig.caseInsensitive()
+	    };
+	}
+	/**
+	 * Factory for [[UrlMatcher]] instances.
+	 *
+	 * The factory is available to ng1 services as
+	 * `$urlMatcherFactor` or ng1 providers as `$urlMatcherFactoryProvider`.
+	 */
+	var UrlMatcherFactory = (function () {
+	    function UrlMatcherFactory() {
+	        common_1.extend(this, { UrlMatcher: urlMatcher_1.UrlMatcher, Param: param_1.Param });
+	    }
+	    /**
+	     * Defines whether URL matching should be case sensitive (the default behavior), or not.
+	     *
+	     * @param value `false` to match URL in a case sensitive manner; otherwise `true`;
+	     * @returns the current value of caseInsensitive
+	     */
+	    UrlMatcherFactory.prototype.caseInsensitive = function (value) {
+	        return urlMatcherConfig_1.matcherConfig.caseInsensitive(value);
+	    };
+	    /**
+	     * Defines whether URLs should match trailing slashes, or not (the default behavior).
+	     *
+	     * @param value `false` to match trailing slashes in URLs, otherwise `true`.
+	     * @returns the current value of strictMode
+	     */
+	    UrlMatcherFactory.prototype.strictMode = function (value) {
+	        return urlMatcherConfig_1.matcherConfig.strictMode(value);
+	    };
+	    /**
+	     * Sets the default behavior when generating or matching URLs with default parameter values.
+	     *
+	     * @param value A string that defines the default parameter URL squashing behavior.
+	     *    - `nosquash`: When generating an href with a default parameter value, do not squash the parameter value from the URL
+	     *    - `slash`: When generating an href with a default parameter value, squash (remove) the parameter value, and, if the
+	     *             parameter is surrounded by slashes, squash (remove) one slash from the URL
+	     *    - any other string, e.g. "~": When generating an href with a default parameter value, squash (remove)
+	     *             the parameter value from the URL and replace it with this string.
+	     * @returns the current value of defaultSquashPolicy
+	     */
+	    UrlMatcherFactory.prototype.defaultSquashPolicy = function (value) {
+	        return urlMatcherConfig_1.matcherConfig.defaultSquashPolicy(value);
+	    };
+	    /**
+	     * Creates a [[UrlMatcher]] for the specified pattern.
+	     *
+	     * @param pattern  The URL pattern.
+	     * @param config  The config object hash.
+	     * @returns The UrlMatcher.
+	     */
+	    UrlMatcherFactory.prototype.compile = function (pattern, config) {
+	        return new urlMatcher_1.UrlMatcher(pattern, common_1.extend(getDefaultConfig(), config));
+	    };
+	    /**
+	     * Returns true if the specified object is a [[UrlMatcher]], or false otherwise.
+	     *
+	     * @param object  The object to perform the type check against.
+	     * @returns `true` if the object matches the `UrlMatcher` interface, by
+	     *          implementing all the same methods.
+	     */
+	    UrlMatcherFactory.prototype.isMatcher = function (object) {
+	        // TODO: typeof?
+	        if (!predicates_1.isObject(object))
+	            return false;
+	        var result = true;
+	        common_1.forEach(urlMatcher_1.UrlMatcher.prototype, function (val, name) {
+	            if (predicates_1.isFunction(val))
+	                result = result && (predicates_1.isDefined(object[name]) && predicates_1.isFunction(object[name]));
+	        });
+	        return result;
+	    };
+	    ;
+	    /**
+	     * Creates and registers a custom [[ParamType]] object that can be used to generate URLs with typed parameters.
+	     *
+	     * @param name  The type name.
+	     * @param definition The type definition. See [[ParamTypeDefinition]] for information on the values accepted.
+	     * @param definitionFn A function that is injected before the app
+	     *        runtime starts.  The result of this function is merged into the existing `definition`.
+	     *        See [[ParamType]] for information on the values accepted.
+	     *
+	     * @returns - if a type was registered: the [[UrlMatcherFactory]]
+	     *   - if only the `name` parameter was specified: the currently registered [[ParamType]] object, or undefined
+	     *
+	     * This is a simple example of a custom type that encodes and decodes items from an
+	     * array, using the array index as the URL-encoded value:
+	     */
+	    UrlMatcherFactory.prototype.type = function (name, definition, definitionFn) {
+	        var type = paramTypes_1.paramTypes.type(name, definition, definitionFn);
+	        return !predicates_1.isDefined(definition) ? type : this;
+	    };
+	    ;
+	    /** @hidden */
+	    UrlMatcherFactory.prototype.$get = function () {
+	        paramTypes_1.paramTypes.enqueue = false;
+	        paramTypes_1.paramTypes._flushTypeQueue();
+	        return this;
+	    };
+	    ;
+	    return UrlMatcherFactory;
+	}());
+	exports.UrlMatcherFactory = UrlMatcherFactory;
+
+
+/***/ },
+/* 28 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module url */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var hof_1 = __webpack_require__(5);
+	var predicates_1 = __webpack_require__(4);
+	var param_1 = __webpack_require__(22);
+	var paramTypes_1 = __webpack_require__(25);
+	var predicates_2 = __webpack_require__(4);
+	var param_2 = __webpack_require__(22);
+	var common_2 = __webpack_require__(3);
+	var common_3 = __webpack_require__(3);
+	/** @hidden */
+	function quoteRegExp(string, param) {
+	    var surroundPattern = ['', ''], result = string.replace(/[\\\[\]\^$*+?.()|{}]/g, "\\$&");
+	    if (!param)
+	        return result;
+	    switch (param.squash) {
+	        case false:
+	            surroundPattern = ['(', ')' + (param.isOptional ? '?' : '')];
+	            break;
+	        case true:
+	            result = result.replace(/\/$/, '');
+	            surroundPattern = ['(?:\/(', ')|\/)?'];
+	            break;
+	        default:
+	            surroundPattern = [("(" + param.squash + "|"), ')?'];
+	            break;
+	    }
+	    return result + surroundPattern[0] + param.type.pattern.source + surroundPattern[1];
+	}
+	/** @hidden */
+	var memoizeTo = function (obj, prop, fn) { return obj[prop] = obj[prop] || fn(); };
+	/**
+	 * Matches URLs against patterns.
+	 *
+	 * Matches URLs against patterns and extracts named parameters from the path or the search
+	 * part of the URL.
+	 *
+	 * A URL pattern consists of a path pattern, optionally followed by '?' and a list of search (query)
+	 * parameters. Multiple search parameter names are separated by '&'. Search parameters
+	 * do not influence whether or not a URL is matched, but their values are passed through into
+	 * the matched parameters returned by [[UrlMatcher.exec]].
+	 *
+	 * - *Path parameters* are defined using curly brace placeholders (`/somepath/{param}`)
+	 * or colon placeholders (`/somePath/:param`).
+	 *
+	 * - *A parameter RegExp* may be defined for a param after a colon
+	 * (`/somePath/{param:[a-zA-Z0-9]+}`) in a curly brace placeholder.
+	 * The regexp must match for the url to be matched.
+	 * Should the regexp itself contain curly braces, they must be in matched pairs or escaped with a backslash.
+	 *
+	 * - *Custom parameter types* may also be specified after a colon (`/somePath/{param:int}`)
+	 * in curly brace parameters.  See [[UrlMatcherFactory.type]] for more information.
+	 *
+	 * - *Catch-all parameters* are defined using an asterisk placeholder (`/somepath/*catchallparam`).  A catch-all
+	 * parameter value will contain the remainder of the URL.
+	 *
+	 * ---
+	 *
+	 * Parameter names may contain only word characters (latin letters, digits, and underscore) and
+	 * must be unique within the pattern (across both path and search parameters).
+	 * A path parameter matches any number of characters other than '/'. For catch-all
+	 * placeholders the path parameter matches any number of characters.
+	 *
+	 * Examples:
+	 *
+	 * * `'/hello/'` - Matches only if the path is exactly '/hello/'. There is no special treatment for
+	 *   trailing slashes, and patterns have to match the entire path, not just a prefix.
+	 * * `'/user/:id'` - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or
+	 *   '/user/bob/details'. The second path segment will be captured as the parameter 'id'.
+	 * * `'/user/{id}'` - Same as the previous example, but using curly brace syntax.
+	 * * `'/user/{id:[^/]*}'` - Same as the previous example.
+	 * * `'/user/{id:[0-9a-fA-F]{1,8}}'` - Similar to the previous example, but only matches if the id
+	 *   parameter consists of 1 to 8 hex digits.
+	 * * `'/files/{path:.*}'` - Matches any URL starting with '/files/' and captures the rest of the
+	 *   path into the parameter 'path'.
+	 * * `'/files/*path'` - ditto.
+	 * * `'/calendar/{start:date}'` - Matches "/calendar/2014-11-12" (because the pattern defined
+	 *   in the built-in  `date` ParamType matches `2014-11-12`) and provides a Date object in $stateParams.start
+	 *
+	 */
+	var UrlMatcher = (function () {
+	    /**
+	     * @param pattern The pattern to compile into a matcher.
+	     * @param config  A configuration object hash
+	     * * `caseInsensitive` - `true` if URL matching should be case insensitive, otherwise `false`, the default value (for backward compatibility) is `false`.
+	     * * `strict` - `false` if matching against a URL with a trailing slash should be treated as equivalent to a URL without a trailing slash, the default value is `true`.
+	     *
+	     * @property {string} pattern  The pattern that was passed into the constructor
+	     */
+	    function UrlMatcher(pattern, config) {
+	        var _this = this;
+	        this.config = config;
+	        /** @hidden */
+	        this._cache = { path: [], pattern: null };
+	        /** @hidden */
+	        this._children = [];
+	        /** @hidden */
+	        this._params = [];
+	        /** @hidden */
+	        this._segments = [];
+	        /** @hidden */
+	        this._compiled = [];
+	        this.pattern = pattern;
+	        this.config = common_1.defaults(this.config, {
+	            params: {},
+	            strict: true,
+	            caseInsensitive: false,
+	            paramMap: common_1.identity
+	        });
+	        // Find all placeholders and create a compiled pattern, using either classic or curly syntax:
+	        //   '*' name
+	        //   ':' name
+	        //   '{' name '}'
+	        //   '{' name ':' regexp '}'
+	        // The regular expression is somewhat complicated due to the need to allow curly braces
+	        // inside the regular expression. The placeholder regexp breaks down as follows:
+	        //    ([:*])([\w\[\]]+)              - classic placeholder ($1 / $2) (search version has - for snake-case)
+	        //    \{([\w\[\]]+)(?:\:\s*( ... ))?\}  - curly brace placeholder ($3) with optional regexp/type ... ($4) (search version has - for snake-case
+	        //    (?: ... | ... | ... )+         - the regexp consists of any number of atoms, an atom being either
+	        //    [^{}\\]+                       - anything other than curly braces or backslash
+	        //    \\.                            - a backslash escape
+	        //    \{(?:[^{}\\]+|\\.)*\}          - a matched set of curly braces containing other atoms
+	        var placeholder = /([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g, searchPlaceholder = /([:]?)([\w\[\].-]+)|\{([\w\[\].-]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g, last = 0, m, patterns = [];
+	        var checkParamErrors = function (id) {
+	            if (!UrlMatcher.nameValidator.test(id))
+	                throw new Error("Invalid parameter name '" + id + "' in pattern '" + pattern + "'");
+	            if (common_1.find(_this._params, hof_1.propEq('id', id)))
+	                throw new Error("Duplicate parameter name '" + id + "' in pattern '" + pattern + "'");
+	        };
+	        // Split into static segments separated by path parameter placeholders.
+	        // The number of segments is always 1 more than the number of parameters.
+	        var matchDetails = function (m, isSearch) {
+	            // IE[78] returns '' for unmatched groups instead of null
+	            var id = m[2] || m[3], regexp = isSearch ? m[4] : m[4] || (m[1] === '*' ? '.*' : null);
+	            return {
+	                id: id,
+	                regexp: regexp,
+	                cfg: _this.config.params[id],
+	                segment: pattern.substring(last, m.index),
+	                type: !regexp ? null : paramTypes_1.paramTypes.type(regexp || "string") || common_1.inherit(paramTypes_1.paramTypes.type("string"), {
+	                    pattern: new RegExp(regexp, _this.config.caseInsensitive ? 'i' : undefined)
+	                })
+	            };
+	        };
+	        var p, segment;
+	        while ((m = placeholder.exec(pattern))) {
+	            p = matchDetails(m, false);
+	            if (p.segment.indexOf('?') >= 0)
+	                break; // we're into the search part
+	            checkParamErrors(p.id);
+	            this._params.push(param_1.Param.fromPath(p.id, p.type, this.config.paramMap(p.cfg, false)));
+	            this._segments.push(p.segment);
+	            patterns.push([p.segment, common_1.tail(this._params)]);
+	            last = placeholder.lastIndex;
+	        }
+	        segment = pattern.substring(last);
+	        // Find any search parameter names and remove them from the last segment
+	        var i = segment.indexOf('?');
+	        if (i >= 0) {
+	            var search = segment.substring(i);
+	            segment = segment.substring(0, i);
+	            if (search.length > 0) {
+	                last = 0;
+	                while ((m = searchPlaceholder.exec(search))) {
+	                    p = matchDetails(m, true);
+	                    checkParamErrors(p.id);
+	                    this._params.push(param_1.Param.fromSearch(p.id, p.type, this.config.paramMap(p.cfg, true)));
+	                    last = placeholder.lastIndex;
+	                }
+	            }
+	        }
+	        this._segments.push(segment);
+	        common_1.extend(this, {
+	            _compiled: patterns.map(function (pattern) { return quoteRegExp.apply(null, pattern); }).concat(quoteRegExp(segment)),
+	            prefix: this._segments[0]
+	        });
+	        Object.freeze(this);
+	    }
+	    /**
+	     * Creates a new concatenated UrlMatcher
+	     *
+	     * Builds a new UrlMatcher by appending another UrlMatcher to this one.
+	     *
+	     * @param url A `UrlMatcher` instance to append as a child of the current `UrlMatcher`.
+	     */
+	    UrlMatcher.prototype.append = function (url) {
+	        this._children.push(url);
+	        common_1.forEach(url._cache, function (val, key) { return url._cache[key] = predicates_1.isArray(val) ? [] : null; });
+	        url._cache.path = this._cache.path.concat(this);
+	        return url;
+	    };
+	    /** @hidden */
+	    UrlMatcher.prototype.isRoot = function () {
+	        return this._cache.path.length === 0;
+	    };
+	    /** Returns the input pattern string */
+	    UrlMatcher.prototype.toString = function () {
+	        return this.pattern;
+	    };
+	    /**
+	     * Tests the specified url/path against this matcher.
+	     *
+	     * Tests if the given url matches this matcher's pattern, and returns an object containing the captured
+	     * parameter values.  Returns null if the path does not match.
+	     *
+	     * The returned object contains the values
+	     * of any search parameters that are mentioned in the pattern, but their value may be null if
+	     * they are not present in `search`. This means that search parameters are always treated
+	     * as optional.
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * new UrlMatcher('/user/{id}?q&r').exec('/user/bob', {
+	     *   x: '1', q: 'hello'
+	     * });
+	     * // returns { id: 'bob', q: 'hello', r: null }
+	     * ```
+	     *
+	     * @param path    The URL path to match, e.g. `$location.path()`.
+	     * @param search  URL search parameters, e.g. `$location.search()`.
+	     * @param hash    URL hash e.g. `$location.hash()`.
+	     * @param options
+	     *
+	     * @returns The captured parameter values.
+	     */
+	    UrlMatcher.prototype.exec = function (path, search, hash, options) {
+	        var _this = this;
+	        if (search === void 0) { search = {}; }
+	        if (options === void 0) { options = {}; }
+	        var match = memoizeTo(this._cache, 'pattern', function () {
+	            return new RegExp([
+	                '^',
+	                common_1.unnest(_this._cache.path.concat(_this).map(hof_1.prop('_compiled'))).join(''),
+	                _this.config.strict === false ? '\/?' : '',
+	                '$'
+	            ].join(''), _this.config.caseInsensitive ? 'i' : undefined);
+	        }).exec(path);
+	        if (!match)
+	            return null;
+	        //options = defaults(options, { isolate: false });
+	        var allParams = this.parameters(), pathParams = allParams.filter(function (param) { return !param.isSearch(); }), searchParams = allParams.filter(function (param) { return param.isSearch(); }), nPathSegments = this._cache.path.concat(this).map(function (urlm) { return urlm._segments.length - 1; }).reduce(function (a, x) { return a + x; }), values = {};
+	        if (nPathSegments !== match.length - 1)
+	            throw new Error("Unbalanced capture group in route '" + this.pattern + "'");
+	        function decodePathArray(string) {
+	            var reverseString = function (str) { return str.split("").reverse().join(""); };
+	            var unquoteDashes = function (str) { return str.replace(/\\-/g, "-"); };
+	            var split = reverseString(string).split(/-(?!\\)/);
+	            var allReversed = common_1.map(split, reverseString);
+	            return common_1.map(allReversed, unquoteDashes).reverse();
+	        }
+	        for (var i = 0; i < nPathSegments; i++) {
+	            var param = pathParams[i];
+	            var value = match[i + 1];
+	            // if the param value matches a pre-replace pair, replace the value before decoding.
+	            for (var j = 0; j < param.replace.length; j++) {
+	                if (param.replace[j].from === value)
+	                    value = param.replace[j].to;
+	            }
+	            if (value && param.array === true)
+	                value = decodePathArray(value);
+	            if (predicates_2.isDefined(value))
+	                value = param.type.decode(value);
+	            values[param.id] = param.value(value);
+	        }
+	        common_1.forEach(searchParams, function (param) {
+	            var value = search[param.id];
+	            for (var j = 0; j < param.replace.length; j++) {
+	                if (param.replace[j].from === value)
+	                    value = param.replace[j].to;
+	            }
+	            if (predicates_2.isDefined(value))
+	                value = param.type.decode(value);
+	            values[param.id] = param.value(value);
+	        });
+	        if (hash)
+	            values["#"] = hash;
+	        return values;
+	    };
+	    /**
+	     * @hidden
+	     * Returns all the [[Param]] objects of all path and search parameters of this pattern in order of appearance.
+	     *
+	     * @returns {Array.<Param>}  An array of [[Param]] objects. Must be treated as read-only. If the
+	     *    pattern has no parameters, an empty array is returned.
+	     */
+	    UrlMatcher.prototype.parameters = function (opts) {
+	        if (opts === void 0) { opts = {}; }
+	        if (opts.inherit === false)
+	            return this._params;
+	        return common_1.unnest(this._cache.path.concat(this).map(hof_1.prop('_params')));
+	    };
+	    /**
+	     * @hidden
+	     * Returns a single parameter from this UrlMatcher by id
+	     *
+	     * @param id
+	     * @param opts
+	     * @returns {T|Param|any|boolean|UrlMatcher|null}
+	     */
+	    UrlMatcher.prototype.parameter = function (id, opts) {
+	        if (opts === void 0) { opts = {}; }
+	        var parent = common_1.tail(this._cache.path);
+	        return (common_1.find(this._params, hof_1.propEq('id', id)) ||
+	            (opts.inherit !== false && parent && parent.parameter(id)) ||
+	            null);
+	    };
+	    /**
+	     * Validates the input parameter values against this UrlMatcher
+	     *
+	     * Checks an object hash of parameters to validate their correctness according to the parameter
+	     * types of this `UrlMatcher`.
+	     *
+	     * @param params The object hash of parameters to validate.
+	     * @returns Returns `true` if `params` validates, otherwise `false`.
+	     */
+	    UrlMatcher.prototype.validates = function (params) {
+	        var _this = this;
+	        var validParamVal = function (param, val) { return !param || param.validates(val); };
+	        return common_1.pairs(params || {}).map(function (_a) {
+	            var key = _a[0], val = _a[1];
+	            return validParamVal(_this.parameter(key), val);
+	        }).reduce(common_1.allTrueR, true);
+	    };
+	    /**
+	     * Given a set of parameter values, creates a URL from this UrlMatcher.
+	     *
+	     * Creates a URL that matches this pattern by substituting the specified values
+	     * for the path and search parameters.
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });
+	     * // returns '/user/bob?q=yes'
+	     * ```
+	     *
+	     * @param values  the values to substitute for the parameters in this pattern.
+	     * @returns the formatted URL (path and optionally search part).
+	     */
+	    UrlMatcher.prototype.format = function (values) {
+	        if (values === void 0) { values = {}; }
+	        if (!this.validates(values))
+	            return null;
+	        // Build the full path of UrlMatchers (including all parent UrlMatchers)
+	        var urlMatchers = this._cache.path.slice().concat(this);
+	        // Extract all the static segments and Params into an ordered array
+	        var pathSegmentsAndParams = urlMatchers.map(UrlMatcher.pathSegmentsAndParams).reduce(common_2.unnestR, []);
+	        // Extract the query params into a separate array
+	        var queryParams = urlMatchers.map(UrlMatcher.queryParams).reduce(common_2.unnestR, []);
+	        /**
+	         * Given a Param,
+	         * Applies the parameter value, then returns details about it
+	         */
+	        function getDetails(param) {
+	            // Normalize to typed value
+	            var value = param.value(values[param.id]);
+	            var isDefaultValue = param.isDefaultValue(value);
+	            // Check if we're in squash mode for the parameter
+	            var squash = isDefaultValue ? param.squash : false;
+	            // Allow the Parameter's Type to encode the value
+	            var encoded = param.type.encode(value);
+	            return { param: param, value: value, isDefaultValue: isDefaultValue, squash: squash, encoded: encoded };
+	        }
+	        // Build up the path-portion from the list of static segments and parameters
+	        var pathString = pathSegmentsAndParams.reduce(function (acc, x) {
+	            // The element is a static segment (a raw string); just append it
+	            if (predicates_1.isString(x))
+	                return acc + x;
+	            // Otherwise, it's a Param.  Fetch details about the parameter value
+	            var _a = getDetails(x), squash = _a.squash, encoded = _a.encoded, param = _a.param;
+	            // If squash is === true, try to remove a slash from the path
+	            if (squash === true)
+	                return (acc.match(/\/$/)) ? acc.slice(0, -1) : acc;
+	            // If squash is a string, use the string for the param value
+	            if (predicates_1.isString(squash))
+	                return acc + squash;
+	            if (squash !== false)
+	                return acc; // ?
+	            if (encoded == null)
+	                return acc;
+	            // If this parameter value is an array, encode the value using encodeDashes
+	            if (predicates_1.isArray(encoded))
+	                return acc + common_1.map(encoded, UrlMatcher.encodeDashes).join("-");
+	            // If the parameter type is "raw", then do not encodeURIComponent
+	            if (param.type.raw)
+	                return acc + encoded;
+	            // Encode the value
+	            return acc + encodeURIComponent(encoded);
+	        }, "");
+	        // Build the query string by applying parameter values (array or regular)
+	        // then mapping to key=value, then flattening and joining using "&"
+	        var queryString = queryParams.map(function (param) {
+	            var _a = getDetails(param), squash = _a.squash, encoded = _a.encoded, isDefaultValue = _a.isDefaultValue;
+	            if (encoded == null || (isDefaultValue && squash !== false))
+	                return;
+	            if (!predicates_1.isArray(encoded))
+	                encoded = [encoded];
+	            if (encoded.length === 0)
+	                return;
+	            if (!param.type.raw)
+	                encoded = common_1.map(encoded, encodeURIComponent);
+	            return encoded.map(function (val) { return (param.id + "=" + val); });
+	        }).filter(common_1.identity).reduce(common_2.unnestR, []).join("&");
+	        // Concat the pathstring with the queryString (if exists) and the hashString (if exists)
+	        return pathString + (queryString ? "?" + queryString : "") + (values["#"] ? "#" + values["#"] : "");
+	    };
+	    /** @hidden */
+	    UrlMatcher.encodeDashes = function (str) {
+	        return encodeURIComponent(str).replace(/-/g, function (c) { return ("%5C%" + c.charCodeAt(0).toString(16).toUpperCase()); });
+	    };
+	    /** @hidden Given a matcher, return an array with the matcher's path segments and path params, in order */
+	    UrlMatcher.pathSegmentsAndParams = function (matcher) {
+	        var staticSegments = matcher._segments;
+	        var pathParams = matcher._params.filter(function (p) { return p.location === param_2.DefType.PATH; });
+	        return common_3.arrayTuples(staticSegments, pathParams.concat(undefined)).reduce(common_2.unnestR, []).filter(function (x) { return x !== "" && predicates_2.isDefined(x); });
+	    };
+	    /** @hidden Given a matcher, return an array with the matcher's query params */
+	    UrlMatcher.queryParams = function (matcher) {
+	        return matcher._params.filter(function (p) { return p.location === param_2.DefType.SEARCH; });
+	    };
+	    /** @hidden */
+	    UrlMatcher.nameValidator = /^\w+([-.]+\w+)*(?:\[\])?$/;
+	    return UrlMatcher;
+	}());
+	exports.UrlMatcher = UrlMatcher;
+
+
+/***/ },
+/* 29 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module url */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var coreservices_1 = __webpack_require__(6);
+	/** @hidden */
+	var $location = coreservices_1.services.location;
+	/** @hidden Returns a string that is a prefix of all strings matching the RegExp */
+	function regExpPrefix(re) {
+	    var prefix = /^\^((?:\\[^a-zA-Z0-9]|[^\\\[\]\^$*+?.()|{}]+)*)/.exec(re.source);
+	    return (prefix != null) ? prefix[1].replace(/\\(.)/g, "$1") : '';
+	}
+	/** @hidden Interpolates matched values into a String.replace()-style pattern */
+	function interpolate(pattern, match) {
+	    return pattern.replace(/\$(\$|\d{1,2})/, function (m, what) {
+	        return match[what === '$' ? 0 : Number(what)];
+	    });
+	}
+	/** @hidden */
+	function handleIfMatch($injector, $stateParams, handler, match) {
+	    if (!match)
+	        return false;
+	    var result = $injector.invoke(handler, handler, { $match: match, $stateParams: $stateParams });
+	    return predicates_1.isDefined(result) ? result : true;
+	}
+	/** @hidden */
+	function appendBasePath(url, isHtml5, absolute) {
+	    var baseHref = coreservices_1.services.locationConfig.baseHref();
+	    if (baseHref === '/')
+	        return url;
+	    if (isHtml5)
+	        return baseHref.slice(0, -1) + url;
+	    if (absolute)
+	        return baseHref.slice(1) + url;
+	    return url;
+	}
+	// TODO: Optimize groups of rules with non-empty prefix into some sort of decision tree
+	/** @hidden */
+	function update(rules, otherwiseFn, evt) {
+	    if (evt && evt.defaultPrevented)
+	        return;
+	    function check(rule) {
+	        var handled = rule(coreservices_1.services.$injector, $location);
+	        if (!handled)
+	            return false;
+	        if (predicates_1.isString(handled)) {
+	            $location.replace();
+	            $location.url(handled);
+	        }
+	        return true;
+	    }
+	    var n = rules.length, i;
+	    for (i = 0; i < n; i++) {
+	        if (check(rules[i]))
+	            return;
+	    }
+	    // always check otherwise last to allow dynamic updates to the set of rules
+	    if (otherwiseFn)
+	        check(otherwiseFn);
+	}
+	/**
+	 * Manages rules for client-side URL
+	 *
+	 * This class manages the router rules for what to do when the URL changes.
+	 */
+	var UrlRouterProvider = (function () {
+	    function UrlRouterProvider($urlMatcherFactory, $stateParams) {
+	        /** @hidden */
+	        this.rules = [];
+	        /** @hidden */
+	        this.interceptDeferred = false;
+	        this.$urlMatcherFactory = $urlMatcherFactory;
+	        this.$stateParams = $stateParams;
+	    }
+	    /**
+	     * Registers a url handler function.
+	     *
+	     * Registers a low level url handler (a `rule`). A rule detects specific URL patterns and returns
+	     * a redirect, or performs some action.
+	     *
+	     * If a rule returns a string, the URL is replaced with the string, and all rules are fired again.
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * var app = angular.module('app', ['ui.router.router']);
+	     *
+	     * app.config(function ($urlRouterProvider) {
+	     *   // Here's an example of how you might allow case insensitive urls
+	     *   $urlRouterProvider.rule(function ($injector, $location) {
+	     *     var path = $location.path(),
+	     *         normalized = path.toLowerCase();
+	     *
+	     *     if (path !== normalized) {
+	     *       return normalized;
+	     *     }
+	     *   });
+	     * });
+	     * ```
+	     *
+	     * @param rule
+	     * Handler function that takes `$injector` and `$location` services as arguments.
+	     * You can use them to detect a url and return a different url as a string.
+	     *
+	     * @return [[$urlRouterProvider]] (`this`)
+	     */
+	    UrlRouterProvider.prototype.rule = function (rule) {
+	        if (!predicates_1.isFunction(rule))
+	            throw new Error("'rule' must be a function");
+	        this.rules.push(rule);
+	        return this;
+	    };
+	    ;
+	    /**
+	     * Defines the path or behavior to use when no url can be matched.
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * var app = angular.module('app', ['ui.router.router']);
+	     *
+	     * app.config(function ($urlRouterProvider) {
+	     *   // if the path doesn't match any of the urls you configured
+	     *   // otherwise will take care of routing the user to the
+	     *   // specified url
+	     *   $urlRouterProvider.otherwise('/index');
+	     *
+	     *   // Example of using function rule as param
+	     *   $urlRouterProvider.otherwise(function ($injector, $location) {
+	     *     return '/a/valid/url';
+	     *   });
+	     * });
+	     * ```
+	     *
+	     * @param rule
+	     * The url path you want to redirect to or a function rule that returns the url path or performs a `$state.go()`.
+	     * The function version is passed two params: `$injector` and `$location` services, and should return a url string.
+	     *
+	     * @return {object} `$urlRouterProvider` - `$urlRouterProvider` instance
+	     */
+	    UrlRouterProvider.prototype.otherwise = function (rule) {
+	        if (!predicates_1.isFunction(rule) && !predicates_1.isString(rule))
+	            throw new Error("'rule' must be a string or function");
+	        this.otherwiseFn = predicates_1.isString(rule) ? function () { return rule; } : rule;
+	        return this;
+	    };
+	    ;
+	    /**
+	     * Registers a handler for a given url matching.
+	     *
+	     * If the handler is a string, it is
+	     * treated as a redirect, and is interpolated according to the syntax of match
+	     * (i.e. like `String.replace()` for `RegExp`, or like a `UrlMatcher` pattern otherwise).
+	     *
+	     * If the handler is a function, it is injectable.
+	     * It gets invoked if `$location` matches.
+	     * You have the option of inject the match object as `$match`.
+	     *
+	     * The handler can return
+	     *
+	     * - **falsy** to indicate that the rule didn't match after all, then `$urlRouter`
+	     *   will continue trying to find another one that matches.
+	     * - **string** which is treated as a redirect and passed to `$location.url()`
+	     * - **void** or any **truthy** value tells `$urlRouter` that the url was handled.
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * var app = angular.module('app', ['ui.router.router']);
+	     *
+	     * app.config(function ($urlRouterProvider) {
+	     *   $urlRouterProvider.when($state.url, function ($match, $stateParams) {
+	     *     if ($state.$current.navigable !== state ||
+	     *         !equalForKeys($match, $stateParams) {
+	     *      $state.transitionTo(state, $match, false);
+	     *     }
+	     *   });
+	     * });
+	     * ```
+	     *
+	     * @param what A pattern string to match, compiled as a [[UrlMatcher]].
+	     * @param handler The path (or function that returns a path) that you want to redirect your user to.
+	     *
+	     * Note: the handler may also invoke arbitrary code, such as `$state.go()`
+	     */
+	    UrlRouterProvider.prototype.when = function (what, handler) {
+	        var _a = this, $urlMatcherFactory = _a.$urlMatcherFactory, $stateParams = _a.$stateParams;
+	        var redirect, handlerIsString = predicates_1.isString(handler);
+	        // @todo Queue this
+	        if (predicates_1.isString(what))
+	            what = $urlMatcherFactory.compile(what);
+	        if (!handlerIsString && !predicates_1.isFunction(handler) && !predicates_1.isArray(handler))
+	            throw new Error("invalid 'handler' in when()");
+	        var strategies = {
+	            matcher: function (_what, _handler) {
+	                if (handlerIsString) {
+	                    redirect = $urlMatcherFactory.compile(_handler);
+	                    _handler = ['$match', redirect.format.bind(redirect)];
+	                }
+	                return common_1.extend(function () {
+	                    return handleIfMatch(coreservices_1.services.$injector, $stateParams, _handler, _what.exec($location.path(), $location.search(), $location.hash()));
+	                }, {
+	                    prefix: predicates_1.isString(_what.prefix) ? _what.prefix : ''
+	                });
+	            },
+	            regex: function (_what, _handler) {
+	                if (_what.global || _what.sticky)
+	                    throw new Error("when() RegExp must not be global or sticky");
+	                if (handlerIsString) {
+	                    redirect = _handler;
+	                    _handler = ['$match', function ($match) { return interpolate(redirect, $match); }];
+	                }
+	                return common_1.extend(function () {
+	                    return handleIfMatch(coreservices_1.services.$injector, $stateParams, _handler, _what.exec($location.path()));
+	                }, {
+	                    prefix: regExpPrefix(_what)
+	                });
+	            }
+	        };
+	        var check = {
+	            matcher: $urlMatcherFactory.isMatcher(what),
+	            regex: what instanceof RegExp
+	        };
+	        for (var n in check) {
+	            if (check[n])
+	                return this.rule(strategies[n](what, handler));
+	        }
+	        throw new Error("invalid 'what' in when()");
+	    };
+	    ;
+	    /**
+	     * Disables monitoring of the URL.
+	     *
+	     * Call this method before UI-Router has bootstrapped.
+	     * It will stop UI-Router from performing the initial url sync.
+	     *
+	     * This can be useful to perform some asynchronous initialization before the router starts.
+	     * Once the initialization is complete, call [[listen]] to tell UI-Router to start watching and synchronizing the URL.
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * var app = angular.module('app', ['ui.router']);
+	     *
+	     * app.config(function ($urlRouterProvider) {
+	     *   // Prevent $urlRouter from automatically intercepting URL changes;
+	     *   $urlRouterProvider.deferIntercept();
+	     * })
+	     *
+	     * app.run(function (MyService, $urlRouter, $http) {
+	     *   $http.get("/stuff").then(function(resp) {
+	     *     MyService.doStuff(resp.data);
+	     *     $urlRouter.listen();
+	     *     $urlRouter.sync();
+	     *   });
+	     * });
+	     * ```
+	     *
+	     * @param defer Indicates whether to defer location change interception. Passing
+	     *        no parameter is equivalent to `true`.
+	     */
+	    UrlRouterProvider.prototype.deferIntercept = function (defer) {
+	        if (defer === undefined)
+	            defer = true;
+	        this.interceptDeferred = defer;
+	    };
+	    ;
+	    return UrlRouterProvider;
+	}());
+	exports.UrlRouterProvider = UrlRouterProvider;
+	var UrlRouter = (function () {
+	    /** @hidden */
+	    function UrlRouter(urlRouterProvider) {
+	        this.urlRouterProvider = urlRouterProvider;
+	        common_1.bindFunctions(UrlRouter.prototype, this, this);
+	    }
+	    /**
+	     * Checks the current URL for a matching rule
+	     *
+	     * Triggers an update; the same update that happens when the address bar url changes, aka `$locationChangeSuccess`.
+	     * This method is useful when you need to use `preventDefault()` on the `$locationChangeSuccess` event,
+	     * perform some custom logic (route protection, auth, config, redirection, etc) and then finally proceed
+	     * with the transition by calling `$urlRouter.sync()`.
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * angular.module('app', ['ui.router'])
+	     *   .run(function($rootScope, $urlRouter) {
+	     *     $rootScope.$on('$locationChangeSuccess', function(evt) {
+	     *       // Halt state change from even starting
+	     *       evt.preventDefault();
+	     *       // Perform custom logic
+	     *       var meetsRequirement = ...
+	     *       // Continue with the update and state transition if logic allows
+	     *       if (meetsRequirement) $urlRouter.sync();
+	     *     });
+	     * });
+	     * ```
+	     */
+	    UrlRouter.prototype.sync = function () {
+	        update(this.urlRouterProvider.rules, this.urlRouterProvider.otherwiseFn);
+	    };
+	    /**
+	     * Starts listening for URL changes
+	     *
+	     * Call this sometime after calling [[deferIntercept]] to start monitoring the url.
+	     * This causes [[UrlRouter]] to start listening for changes to the URL, if it wasn't already listening.
+	     */
+	    UrlRouter.prototype.listen = function () {
+	        var _this = this;
+	        return this.listener = this.listener || $location.onChange(function (evt) { return update(_this.urlRouterProvider.rules, _this.urlRouterProvider.otherwiseFn, evt); });
+	    };
+	    /**
+	     * Internal API.
+	     */
+	    UrlRouter.prototype.update = function (read) {
+	        if (read) {
+	            this.location = $location.url();
+	            return;
+	        }
+	        if ($location.url() === this.location)
+	            return;
+	        $location.url(this.location);
+	        $location.replace();
+	    };
+	    /**
+	     * Internal API.
+	     *
+	     * Pushes a new location to the browser history.
+	     *
+	     * @param urlMatcher
+	     * @param params
+	     * @param options
+	     */
+	    UrlRouter.prototype.push = function (urlMatcher, params, options) {
+	        $location.url(urlMatcher.format(params || {}));
+	        if (options && options.replace)
+	            $location.replace();
+	    };
+	    /**
+	     * Builds and returns a URL with interpolated parameters
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * $bob = $urlRouter.href(new UrlMatcher("/about/:person"), {
+	     *   person: "bob"
+	     * });
+	     * // $bob == "/about/bob";
+	     * ```
+	     *
+	     * @param urlMatcher The [[UrlMatcher]] object which is used as the template of the URL to generate.
+	     * @param params An object of parameter values to fill the matcher's required parameters.
+	     * @param options Options object. The options are:
+	     *
+	     * - **`absolute`** - {boolean=false},  If true will generate an absolute url, e.g. "http://www.example.com/fullurl".
+	     *
+	     * @returns Returns the fully compiled URL, or `null` if `params` fail validation against `urlMatcher`
+	     */
+	    UrlRouter.prototype.href = function (urlMatcher, params, options) {
+	        if (!urlMatcher.validates(params))
+	            return null;
+	        var url = urlMatcher.format(params);
+	        options = options || { absolute: false };
+	        var cfg = coreservices_1.services.locationConfig;
+	        var isHtml5 = cfg.html5Mode();
+	        if (!isHtml5 && url !== null) {
+	            url = "#" + cfg.hashPrefix() + url;
+	        }
+	        url = appendBasePath(url, isHtml5, options.absolute);
+	        if (!options.absolute || !url) {
+	            return url;
+	        }
+	        var slash = (!isHtml5 && url ? '/' : ''), port = cfg.port();
+	        port = (port === 80 || port === 443 ? '' : ':' + port);
+	        return [cfg.protocol(), '://', cfg.host(), port, slash, url].join('');
+	    };
+	    return UrlRouter;
+	}());
+	exports.UrlRouter = UrlRouter;
+
+
+/***/ },
+/* 30 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module state */ /** for typedoc */
+	var predicates_1 = __webpack_require__(4);
+	var common_1 = __webpack_require__(3);
+	/**
+	 * @ngdoc object
+	 * @name ui.router.state.$stateProvider
+	 *
+	 * @requires ui.router.router.$urlRouterProvider
+	 * @requires ui.router.util.$urlMatcherFactoryProvider
+	 *
+	 * @description
+	 * The new `$stateProvider` works similar to Angular's v1 router, but it focuses purely
+	 * on state.
+	 *
+	 * A state corresponds to a "place" in the application in terms of the overall UI and
+	 * navigation. A state describes (via the controller / template / view properties) what
+	 * the UI looks like and does at that place.
+	 *
+	 * States often have things in common, and the primary way of factoring out these
+	 * commonalities in this model is via the state hierarchy, i.e. parent/child states aka
+	 * nested states.
+	 *
+	 * The `$stateProvider` provides interfaces to declare these states for your app.
+	 */
+	var StateProvider = (function () {
+	    function StateProvider(stateRegistry) {
+	        this.stateRegistry = stateRegistry;
+	        this.invalidCallbacks = [];
+	        common_1.bindFunctions(StateProvider.prototype, this, this);
+	    }
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.$stateProvider#decorator
+	     * @methodOf ui.router.state.$stateProvider
+	     *
+	     * @description
+	     * Allows you to extend (carefully) or override (at your own peril) the
+	     * `stateBuilder` object used internally by `$stateProvider`. This can be used
+	     * to add custom functionality to ui-router, for example inferring templateUrl
+	     * based on the state name.
+	     *
+	     * When passing only a name, it returns the current (original or decorated) builder
+	     * function that matches `name`.
+	     *
+	     * The builder functions that can be decorated are listed below. Though not all
+	     * necessarily have a good use case for decoration, that is up to you to decide.
+	     *
+	     * In addition, users can attach custom decorators, which will generate new
+	     * properties within the state's internal definition. There is currently no clear
+	     * use-case for this beyond accessing internal states (i.e. $state.$current),
+	     * however, expect this to become increasingly relevant as we introduce additional
+	     * meta-programming features.
+	     *
+	     * **Warning**: Decorators should not be interdependent because the order of
+	     * execution of the builder functions in non-deterministic. Builder functions
+	     * should only be dependent on the state definition object and super function.
+	     *
+	     *
+	     * Existing builder functions and current return values:
+	     *
+	     * - **parent** `{object}` - returns the parent state object.
+	     * - **data** `{object}` - returns state data, including any inherited data that is not
+	     *   overridden by own values (if any).
+	     * - **url** `{object}` - returns a {@link ui.router.util.type:UrlMatcher UrlMatcher}
+	     *   or `null`.
+	     * - **navigable** `{object}` - returns closest ancestor state that has a URL (aka is
+	     *   navigable).
+	     * - **params** `{object}` - returns an array of state params that are ensured to
+	     *   be a super-set of parent's params.
+	     * - **views** `{object}` - returns a views object where each key is an absolute view
+	     *   name (i.e. "viewName@stateName") and each value is the config object
+	     *   (template, controller) for the view. Even when you don't use the views object
+	     *   explicitly on a state config, one is still created for you internally.
+	     *   So by decorating this builder function you have access to decorating template
+	     *   and controller properties.
+	     * - **ownParams** `{object}` - returns an array of params that belong to the state,
+	     *   not including any params defined by ancestor states.
+	     * - **path** `{string}` - returns the full path from the root down to this state.
+	     *   Needed for state activation.
+	     * - **includes** `{object}` - returns an object that includes every state that
+	     *   would pass a `$state.includes()` test.
+	     *
+	     * @example
+	     * <pre>
+	     * // Override the internal 'views' builder with a function that takes the state
+	     * // definition, and a reference to the internal function being overridden:
+	     * $stateProvider.decorator('views', function (state, parent) {
+	     *   let result = {},
+	     *       views = parent(state);
+	     *
+	     *   angular.forEach(views, function (config, name) {
+	     *     let autoName = (state.name + '.' + name).replace('.', '/');
+	     *     config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html';
+	     *     result[name] = config;
+	     *   });
+	     *   return result;
+	     * });
+	     *
+	     * $stateProvider.state('home', {
+	     *   views: {
+	     *     'contact.list': { controller: 'ListController' },
+	     *     'contact.item': { controller: 'ItemController' }
+	     *   }
+	     * });
+	     *
+	     * // ...
+	     *
+	     * $state.go('home');
+	     * // Auto-populates list and item views with /partials/home/contact/list.html,
+	     * // and /partials/home/contact/item.html, respectively.
+	     * </pre>
+	     *
+	     * @param {string} name The name of the builder function to decorate.
+	     * @param {object} func A function that is responsible for decorating the original
+	     * builder function. The function receives two parameters:
+	     *
+	     *   - `{object}` - state - The state config object.
+	     *   - `{object}` - super - The original builder function.
+	     *
+	     * @return {object} $stateProvider - $stateProvider instance
+	     */
+	    StateProvider.prototype.decorator = function (name, func) {
+	        return this.stateRegistry.decorator(name, func) || this;
+	    };
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.$stateProvider#state
+	     * @methodOf ui.router.state.$stateProvider
+	     *
+	     * @description
+	     * Registers a state configuration under a given state name. The stateConfig object
+	     * has the following acceptable properties.
+	     *
+	     * <a id='template'></a>
+	     *
+	     * - **`template`** - {string|function=} - html template as a string or a function that returns
+	     *   an html template as a string which should be used by the uiView directives. This property
+	     *   takes precedence over templateUrl.
+	     *
+	     *   If `template` is a function, it will be called with the following parameters:
+	     *
+	     *   - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by
+	     *     applying the current state
+	     *
+	     * <a id='templateUrl'></a>
+	     *
+	     * - **`templateUrl`** - {string|function=} - path or function that returns a path to an html
+	     *   template that should be used by uiView.
+	     *
+	     *   If `templateUrl` is a function, it will be called with the following parameters:
+	     *
+	     *   - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by
+	     *     applying the current state
+	     *
+	     * <a id='templateProvider'></a>
+	     *
+	     * - **`templateProvider`** - {function=} - Provider function that returns HTML content
+	     *   string.
+	     *
+	     * <a id='controller'></a>
+	     *
+	     * - **`controller`** - {string|function=} -  Controller fn that should be associated with newly
+	     *   related scope or the name of a registered controller if passed as a string.
+	     *
+	     * <a id='controllerProvider'></a>
+	     *
+	     * - **`controllerProvider`** - {function=} - Injectable provider function that returns
+	     *   the actual controller or string.
+	     *
+	     * <a id='controllerAs'></a>
+	     *
+	     * - **`controllerAs`** – {string=} – A controller alias name. If present the controller will be
+	     *   published to scope under the controllerAs name.
+	     *
+	     * <a id='resolve'></a>
+	     *
+	     * - **`resolve`** - {object.&lt;string, function&gt;=} - An optional map of dependencies which
+	     *   should be injected into the controller. If any of these dependencies are promises,
+	     *   the router will wait for them all to be resolved or one to be rejected before the
+	     *   controller is instantiated. If all the promises are resolved successfully, the values
+	     *   of the resolved promises are injected and $stateChangeSuccess event is fired. If any
+	     *   of the promises are rejected the $stateChangeError event is fired. The map object is:
+	     *
+	     *   - key - {string}: name of dependency to be injected into controller
+	     *   - factory - {string|function}: If string then it is alias for service. Otherwise if function,
+	     *     it is injected and return value it treated as dependency. If result is a promise, it is
+	     *     resolved before its value is injected into controller.
+	     *
+	     * <a id='url'></a>
+	     *
+	     * - **`url`** - {string=} - A url with optional parameters. When a state is navigated or
+	     *   transitioned to, the `$stateParams` service will be populated with any
+	     *   parameters that were passed.
+	     *
+	     * <a id='params'></a>
+	     *
+	     * - **`params`** - {object=} - An array of parameter names or regular expressions. Only
+	     *   use this within a state if you are not using url. Otherwise you can specify your
+	     *   parameters within the url. When a state is navigated or transitioned to, the
+	     *   $stateParams service will be populated with any parameters that were passed.
+	     *
+	     * <a id='views'></a>
+	     *
+	     * - **`views`** - {object=} - Use the views property to set up multiple views or to target views
+	     *   manually/explicitly.
+	     *
+	     * <a id='abstract'></a>
+	     *
+	     * - **`abstract`** - {boolean=} - An abstract state will never be directly activated,
+	     *   but can provide inherited properties to its common children states.
+	     *
+	     * <a id='onEnter'></a>
+	     *
+	     * - **`onEnter`** - {object=} - Callback function for when a state is entered. Good way
+	     *   to trigger an action or dispatch an event, such as opening a dialog.
+	     * If minifying your scripts, make sure to use the `['injection1', 'injection2', function(injection1, injection2){}]` syntax.
+	     *
+	     * <a id='onExit'></a>
+	     *
+	     * - **`onExit`** - {object=} - Callback function for when a state is exited. Good way to
+	     *   trigger an action or dispatch an event, such as opening a dialog.
+	     * If minifying your scripts, make sure to use the `['injection1', 'injection2', function(injection1, injection2){}]` syntax.
+	     *
+	     * <a id='reloadOnSearch'></a>
+	     *
+	     * - **`reloadOnSearch = true`** - {boolean=} - If `false`, will not retrigger the same state
+	     *   just because a search/query parameter has changed (via $location.search() or $location.hash()).
+	     *   Useful for when you'd like to modify $location.search() without triggering a reload.
+	     *
+	     * <a id='data'></a>
+	     *
+	     * - **`data`** - {object=} - Arbitrary data object, useful for custom configuration.
+	     *
+	     * @example
+	     * <pre>
+	     * // Some state name examples
+	     *
+	     * // stateName can be a single top-level name (must be unique).
+	     * $stateProvider.state("home", {});
+	     *
+	     * // Or it can be a nested state name. This state is a child of the
+	     * // above "home" state.
+	     * $stateProvider.state("home.newest", {});
+	     *
+	     * // Nest states as deeply as needed.
+	     * $stateProvider.state("home.newest.abc.xyz.inception", {});
+	     *
+	     * // state() returns $stateProvider, so you can chain state declarations.
+	     * $stateProvider
+	     *   .state("home", {})
+	     *   .state("about", {})
+	     *   .state("contacts", {});
+	     * </pre>
+	     *
+	     * @param {string} name A unique state name, e.g. "home", "about", "contacts".
+	     * To create a parent/child state use a dot, e.g. "about.sales", "home.newest".
+	     * @param {object} definition State configuration object.
+	     */
+	    StateProvider.prototype.state = function (name, definition) {
+	        if (predicates_1.isObject(name)) {
+	            definition = name;
+	        }
+	        else {
+	            definition.name = name;
+	        }
+	        this.stateRegistry.register(definition);
+	        return this;
+	    };
+	    /**
+	     * Registers an invalid state handler
+	     *
+	     * Registers a function to be injected and invoked when [[StateService.transitionTo]] has been called with an invalid
+	     * state reference parameter
+	     *
+	     * This function can be injected with one some special values:
+	     * - **`$to$`**: TargetState
+	     * - **`$from$`**: TargetState
+	     *
+	     * Note: This API is subject to change.
+	     * Replacement of dependency injection support with some alternative is likely.
+	     *
+	     * @param {function} callback
+	     *   The function which will be injected and invoked, when a matching transition is started.
+	     *   The function may optionally return a {TargetState} or a Promise for a TargetState.  If one
+	     *   is returned, it is treated as a redirect.
+	     */
+	    StateProvider.prototype.onInvalid = function (callback) {
+	        this.invalidCallbacks.push(callback);
+	    };
+	    return StateProvider;
+	}());
+	exports.StateProvider = StateProvider;
+
+
+/***/ },
+/* 31 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	var transition_1 = __webpack_require__(11);
+	var hookRegistry_1 = __webpack_require__(15);
+	var resolve_1 = __webpack_require__(32);
+	var views_1 = __webpack_require__(33);
+	var url_1 = __webpack_require__(34);
+	var redirectTo_1 = __webpack_require__(35);
+	var onEnterExitRetain_1 = __webpack_require__(36);
+	var hof_1 = __webpack_require__(5);
+	/**
+	 * The default [[Transition]] options.
+	 *
+	 * Include this object when applying custom defaults:
+	 * let reloadOpts = { reload: true, notify: true }
+	 * let options = defaults(theirOpts, customDefaults, defaultOptions);
+	 */
+	exports.defaultTransOpts = {
+	    location: true,
+	    relative: null,
+	    inherit: false,
+	    notify: true,
+	    reload: false,
+	    custom: {},
+	    current: function () { return null; }
+	};
+	/**
+	 * This class provides services related to Transitions.
+	 *
+	 * - Most importantly, it allows global Transition Hooks to be registered.
+	 * - It allows the default transition error handler to be set.
+	 * - It also has a factory function for creating new [[Transition]] objects, (used internally by the [[StateService]]).
+	 *
+	 * At bootstrap, [[UIRouter]] creates a single instance (singleton) of this class.
+	 */
+	var TransitionService = (function () {
+	    function TransitionService(_router) {
+	        this._router = _router;
+	        this.$view = _router.viewService;
+	        hookRegistry_1.HookRegistry.mixin(new hookRegistry_1.HookRegistry(), this);
+	        this._deregisterHookFns = {};
+	        this.registerTransitionHooks();
+	    }
+	    /** @hidden */
+	    TransitionService.prototype.registerTransitionHooks = function () {
+	        var fns = this._deregisterHookFns;
+	        // Wire up redirectTo hook
+	        fns.redirectTo = this.onStart({ to: function (state) { return !!state.redirectTo; } }, redirectTo_1.redirectToHook);
+	        // Wire up onExit/Retain/Enter state hooks
+	        fns.onExit = this.onExit({ exiting: function (state) { return !!state.onExit; } }, onEnterExitRetain_1.onExitHook);
+	        fns.onRetain = this.onRetain({ retained: function (state) { return !!state.onRetain; } }, onEnterExitRetain_1.onRetainHook);
+	        fns.onEnter = this.onEnter({ entering: function (state) { return !!state.onEnter; } }, onEnterExitRetain_1.onEnterHook);
+	        // Wire up Resolve hooks
+	        fns.eagerResolve = this.onStart({}, resolve_1.eagerResolvePath, { priority: 1000 });
+	        fns.lazyResolve = this.onEnter({ entering: hof_1.val(true) }, resolve_1.lazyResolveState, { priority: 1000 });
+	        // Wire up the View management hooks
+	        fns.loadViews = this.onStart({}, views_1.loadEnteringViews);
+	        fns.activateViews = this.onSuccess({}, views_1.activateViews);
+	        // After globals.current is updated at priority: 10000
+	        fns.updateUrl = this.onSuccess({}, url_1.updateUrl, { priority: 9999 });
+	    };
+	    /** @inheritdoc */
+	    TransitionService.prototype.onBefore = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    TransitionService.prototype.onStart = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    TransitionService.prototype.onExit = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    TransitionService.prototype.onRetain = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    TransitionService.prototype.onEnter = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    TransitionService.prototype.onFinish = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    TransitionService.prototype.onSuccess = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /** @inheritdoc */
+	    TransitionService.prototype.onError = function (matchCriteria, callback, options) { throw ""; };
+	    ;
+	    /**
+	     * Creates a new [[Transition]] object
+	     *
+	     * This is a factory function for creating new Transition objects.
+	     * It is used internally by the [[StateService]] and should generally not be called by application code.
+	     *
+	     * @param fromPath the path to the current state (the from state)
+	     * @param targetState the target state (destination)
+	     * @returns a Transition
+	     */
+	    TransitionService.prototype.create = function (fromPath, targetState) {
+	        return new transition_1.Transition(fromPath, targetState, this._router);
+	    };
+	    return TransitionService;
+	}());
+	exports.TransitionService = TransitionService;
+
+
+/***/ },
+/* 32 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module hooks */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var resolveContext_1 = __webpack_require__(17);
+	/**
+	 * A [[TransitionHookFn]] which resolves all EAGER Resolvables in the To Path
+	 *
+	 * Registered using `transitionService.onStart({}, eagerResolvePath);`
+	 *
+	 * When a Transition starts, this hook resolves all the EAGER Resolvables, which the transition then waits for.
+	 *
+	 * See [[StateDeclaration.resolve]]
+	 */
+	exports.eagerResolvePath = function (trans) {
+	    return new resolveContext_1.ResolveContext(trans.treeChanges().to)
+	        .resolvePath("EAGER", trans)
+	        .then(common_1.noop);
+	};
+	/**
+	 * A [[TransitionHookFn]] which resolves all LAZY Resolvables for the state (and all its ancestors) in the To Path
+	 *
+	 * Registered using `transitionService.onEnter({ entering: () => true }, lazyResolveState);`
+	 *
+	 * When a State is being entered, this hook resolves all the Resolvables for this state, which the transition then waits for.
+	 *
+	 * See [[StateDeclaration.resolve]]
+	 */
+	exports.lazyResolveState = function (trans, state) {
+	    return new resolveContext_1.ResolveContext(trans.treeChanges().to)
+	        .subContext(state)
+	        .resolvePath("LAZY", trans)
+	        .then(common_1.noop);
+	};
+
+
+/***/ },
+/* 33 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module hooks */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var coreservices_1 = __webpack_require__(6);
+	/**
+	 * A [[TransitionHookFn]] which waits for the views to load
+	 *
+	 * Registered using `transitionService.onStart({}, loadEnteringViews);`
+	 *
+	 * Allows the views to do async work in [[ViewConfig.load]] before the transition continues.
+	 * In angular 1, this includes loading the templates.
+	 */
+	function loadEnteringViews(transition) {
+	    var enteringViews = transition.views("entering");
+	    if (!enteringViews.length)
+	        return;
+	    return coreservices_1.services.$q.all(enteringViews.map(function (view) { return view.load(); })).then(common_1.noop);
+	}
+	exports.loadEnteringViews = loadEnteringViews;
+	/**
+	 * A [[TransitionHookFn]] which activates the new views when a transition is successful.
+	 *
+	 * Registered using `transitionService.onSuccess({}, activateViews);`
+	 *
+	 * After a transition is complete, this hook deactivates the old views from the previous state,
+	 * and activates the new views from the destination state.
+	 *
+	 * See [[ViewService]]
+	 */
+	function activateViews(transition) {
+	    var enteringViews = transition.views("entering");
+	    var exitingViews = transition.views("exiting");
+	    if (!enteringViews.length && !exitingViews.length)
+	        return;
+	    var $view = transition.router.viewService;
+	    exitingViews.forEach(function (vc) { return $view.deactivateViewConfig(vc); });
+	    enteringViews.forEach(function (vc) { return $view.activateViewConfig(vc); });
+	    $view.sync();
+	}
+	exports.activateViews = activateViews;
+
+
+/***/ },
+/* 34 */
+/***/ function(module, exports) {
+
+	"use strict";
+	/**
+	 * A [[TransitionHookFn]] which updates the URL after a successful transition
+	 *
+	 * Registered using `transitionService.onSuccess({}, updateUrl);`
+	 */
+	function updateUrl(transition) {
+	    var options = transition.options();
+	    var $state = transition.router.stateService;
+	    var $urlRouter = transition.router.urlRouter;
+	    if (options.location && $state.$current.navigable) {
+	        var urlOptions = { replace: options.location === 'replace' };
+	        $urlRouter.push($state.$current.navigable.url, $state.params, urlOptions);
+	    }
+	    $urlRouter.update(true);
+	}
+	exports.updateUrl = updateUrl;
+
+
+/***/ },
+/* 35 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module hooks */ /** */
+	var predicates_1 = __webpack_require__(4);
+	var coreservices_1 = __webpack_require__(6);
+	var targetState_1 = __webpack_require__(14);
+	/**
+	 * A [[TransitionHookFn]] that redirects to a different state or params
+	 *
+	 * Registered using `transitionService.onStart({ to: (state) => !!state.redirectTo }, redirectHook);`
+	 *
+	 * See [[StateDeclaration.redirectTo]]
+	 */
+	exports.redirectToHook = function (trans) {
+	    var redirect = trans.to().redirectTo;
+	    if (!redirect)
+	        return;
+	    function handleResult(result) {
+	        var $state = trans.router.stateService;
+	        if (result instanceof targetState_1.TargetState)
+	            return result;
+	        if (predicates_1.isString(result))
+	            return $state.target(result, trans.params(), trans.options());
+	        if (result['state'] || result['params'])
+	            return $state.target(result['state'] || trans.to(), result['params'] || trans.params(), trans.options());
+	    }
+	    if (predicates_1.isFunction(redirect)) {
+	        return coreservices_1.services.$q.when(redirect(trans)).then(handleResult);
+	    }
+	    return handleResult(redirect);
+	};
+
+
+/***/ },
+/* 36 */
+/***/ function(module, exports) {
+
+	"use strict";
+	/**
+	 * A factory which creates an onEnter, onExit or onRetain transition hook function
+	 *
+	 * The returned function invokes the (for instance) state.onEnter hook when the
+	 * state is being entered.
+	 *
+	 * @hidden
+	 */
+	function makeEnterExitRetainHook(hookName) {
+	    return function (transition, state) {
+	        return state[hookName](transition, state);
+	    };
+	}
+	/**
+	 * The [[TransitionStateHookFn]] for onExit
+	 *
+	 * When the state is being exited, the state's .onExit function is invoked.
+	 *
+	 * Registered using `transitionService.onExit({ exiting: (state) => !!state.onExit }, onExitHook);`
+	 */
+	exports.onExitHook = makeEnterExitRetainHook('onExit');
+	/**
+	 * The [[TransitionStateHookFn]] for onRetain
+	 *
+	 * When the state is being exited, the state's .onRetain function is invoked.
+	 *
+	 * Registered using `transitionService.onRetain({ retained: (state) => !!state.onRetain }, onRetainHook);`
+	 */
+	exports.onRetainHook = makeEnterExitRetainHook('onRetain');
+	/**
+	 * The [[TransitionStateHookFn]] for onEnter
+	 *
+	 * When the state is being exited, the state's .onEnter function is invoked.
+	 *
+	 * Registered using `transitionService.onEnter({ entering: (state) => !!state.onEnter }, onEnterHook);`
+	 */
+	exports.onEnterHook = makeEnterExitRetainHook('onEnter');
+
+
+/***/ },
+/* 37 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module view */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var hof_1 = __webpack_require__(5);
+	var predicates_1 = __webpack_require__(4);
+	var trace_1 = __webpack_require__(12);
+	var match = function (obj1) {
+	    var keys = [];
+	    for (var _i = 1; _i < arguments.length; _i++) {
+	        keys[_i - 1] = arguments[_i];
+	    }
+	    return function (obj2) { return keys.reduce(function (memo, key) { return memo && obj1[key] === obj2[key]; }, true); };
+	};
+	/**
+	 * The View service
+	 */
+	var ViewService = (function () {
+	    function ViewService() {
+	        var _this = this;
+	        this.uiViews = [];
+	        this.viewConfigs = [];
+	        this._viewConfigFactories = {};
+	        this.sync = function () {
+	            var uiViewsByFqn = _this.uiViews.map(function (uiv) { return [uiv.fqn, uiv]; }).reduce(common_1.applyPairs, {});
+	            /**
+	             * Given a ui-view and a ViewConfig, determines if they "match".
+	             *
+	             * A ui-view has a fully qualified name (fqn) and a context object.  The fqn is built from its overall location in
+	             * the DOM, describing its nesting relationship to any parent ui-view tags it is nested inside of.
+	             *
+	             * A ViewConfig has a target ui-view name and a context anchor.  The ui-view name can be a simple name, or
+	             * can be a segmented ui-view path, describing a portion of a ui-view fqn.
+	             *
+	             * In order for a ui-view to match ViewConfig, ui-view's $type must match the ViewConfig's $type
+	             *
+	             * If the ViewConfig's target ui-view name is a simple name (no dots), then a ui-view matches if:
+	             * - the ui-view's name matches the ViewConfig's target name
+	             * - the ui-view's context matches the ViewConfig's anchor
+	             *
+	             * If the ViewConfig's target ui-view name is a segmented name (with dots), then a ui-view matches if:
+	             * - There exists a parent ui-view where:
+	             *    - the parent ui-view's name matches the first segment (index 0) of the ViewConfig's target name
+	             *    - the parent ui-view's context matches the ViewConfig's anchor
+	             * - And the remaining segments (index 1..n) of the ViewConfig's target name match the tail of the ui-view's fqn
+	             *
+	             * Example:
+	             *
+	             * DOM:
+	             * <div ui-view>                        <!-- created in the root context (name: "") -->
+	             *   <div ui-view="foo">                <!-- created in the context named: "A"      -->
+	             *     <div ui-view>                    <!-- created in the context named: "A.B"    -->
+	             *       <div ui-view="bar">            <!-- created in the context named: "A.B.C"  -->
+	             *       </div>
+	             *     </div>
+	             *   </div>
+	             * </div>
+	             *
+	             * uiViews: [
+	             *  { fqn: "$default",                  creationContext: { name: "" } },
+	             *  { fqn: "$default.foo",              creationContext: { name: "A" } },
+	             *  { fqn: "$default.foo.$default",     creationContext: { name: "A.B" } }
+	             *  { fqn: "$default.foo.$default.bar", creationContext: { name: "A.B.C" } }
+	             * ]
+	             *
+	             * These four view configs all match the ui-view with the fqn: "$default.foo.$default.bar":
+	             *
+	             * - ViewConfig1: { uiViewName: "bar",                       uiViewContextAnchor: "A.B.C" }
+	             * - ViewConfig2: { uiViewName: "$default.bar",              uiViewContextAnchor: "A.B" }
+	             * - ViewConfig3: { uiViewName: "foo.$default.bar",          uiViewContextAnchor: "A" }
+	             * - ViewConfig4: { uiViewName: "$default.foo.$default.bar", uiViewContextAnchor: "" }
+	             *
+	             * Using ViewConfig3 as an example, it matches the ui-view with fqn "$default.foo.$default.bar" because:
+	             * - The ViewConfig's segmented target name is: [ "foo", "$default", "bar" ]
+	             * - There exists a parent ui-view (which has fqn: "$default.foo") where:
+	             *    - the parent ui-view's name "foo" matches the first segment "foo" of the ViewConfig's target name
+	             *    - the parent ui-view's context "A" matches the ViewConfig's anchor context "A"
+	             * - And the remaining segments [ "$default", "bar" ].join("."_ of the ViewConfig's target name match
+	             *   the tail of the ui-view's fqn "default.bar"
+	             */
+	            var matches = function (uiView) { return function (viewConfig) {
+	                // Don't supply an ng1 ui-view with an ng2 ViewConfig, etc
+	                if (uiView.$type !== viewConfig.viewDecl.$type)
+	                    return false;
+	                // Split names apart from both viewConfig and uiView into segments
+	                var vc = viewConfig.viewDecl;
+	                var vcSegments = vc.$uiViewName.split(".");
+	                var uivSegments = uiView.fqn.split(".");
+	                // Check if the tails of the segment arrays match. ex, these arrays' tails match:
+	                // vc: ["foo", "bar"], uiv fqn: ["$default", "foo", "bar"]
+	                if (!common_1.equals(vcSegments, uivSegments.slice(0 - vcSegments.length)))
+	                    return false;
+	                // Now check if the fqn ending at the first segment of the viewConfig matches the context:
+	                // ["$default", "foo"].join(".") == "$default.foo", does the ui-view $default.foo context match?
+	                var negOffset = (1 - vcSegments.length) || undefined;
+	                var fqnToFirstSegment = uivSegments.slice(0, negOffset).join(".");
+	                var uiViewContext = uiViewsByFqn[fqnToFirstSegment].creationContext;
+	                return vc.$uiViewContextAnchor === (uiViewContext && uiViewContext.name);
+	            }; };
+	            // Return the number of dots in the fully qualified name
+	            function uiViewDepth(uiView) {
+	                return uiView.fqn.split(".").length;
+	            }
+	            // Return the ViewConfig's context's depth in the context tree.
+	            function viewConfigDepth(config) {
+	                var context = config.viewDecl.$context, count = 0;
+	                while (++count && context.parent)
+	                    context = context.parent;
+	                return count;
+	            }
+	            // Given a depth function, returns a compare function which can return either ascending or descending order
+	            var depthCompare = hof_1.curry(function (depthFn, posNeg, left, right) { return posNeg * (depthFn(left) - depthFn(right)); });
+	            var matchingConfigPair = function (uiView) {
+	                var matchingConfigs = _this.viewConfigs.filter(matches(uiView));
+	                if (matchingConfigs.length > 1)
+	                    matchingConfigs.sort(depthCompare(viewConfigDepth, -1)); // descending
+	                return [uiView, matchingConfigs[0]];
+	            };
+	            var configureUIView = function (_a) {
+	                var uiView = _a[0], viewConfig = _a[1];
+	                // If a parent ui-view is reconfigured, it could destroy child ui-views.
+	                // Before configuring a child ui-view, make sure it's still in the active uiViews array.
+	                if (_this.uiViews.indexOf(uiView) !== -1)
+	                    uiView.configUpdated(viewConfig);
+	            };
+	            _this.uiViews.sort(depthCompare(uiViewDepth, 1)).map(matchingConfigPair).forEach(configureUIView);
+	        };
+	    }
+	    ViewService.prototype.rootContext = function (context) {
+	        return this._rootContext = context || this._rootContext;
+	    };
+	    ;
+	    ViewService.prototype.viewConfigFactory = function (viewType, factory) {
+	        this._viewConfigFactories[viewType] = factory;
+	    };
+	    ViewService.prototype.createViewConfig = function (path, decl) {
+	        var cfgFactory = this._viewConfigFactories[decl.$type];
+	        if (!cfgFactory)
+	            throw new Error("ViewService: No view config factory registered for type " + decl.$type);
+	        var cfgs = cfgFactory(path, decl);
+	        return predicates_1.isArray(cfgs) ? cfgs : [cfgs];
+	    };
+	    /**
+	     * De-registers a ViewConfig.
+	     *
+	     * @param viewConfig The ViewConfig view to deregister.
+	     */
+	    ViewService.prototype.deactivateViewConfig = function (viewConfig) {
+	        trace_1.trace.traceViewServiceEvent("<- Removing", viewConfig);
+	        common_1.removeFrom(this.viewConfigs, viewConfig);
+	    };
+	    ;
+	    ViewService.prototype.activateViewConfig = function (viewConfig) {
+	        trace_1.trace.traceViewServiceEvent("-> Registering", viewConfig);
+	        this.viewConfigs.push(viewConfig);
+	    };
+	    ;
+	    /**
+	     * Allows a `ui-view` element to register its canonical name with a callback that allows it to
+	     * be updated with a template, controller, and local variables.
+	     *
+	     * @param {String} name The fully-qualified name of the `ui-view` object being registered.
+	     * @param {Function} configUpdatedCallback A callback that receives updates to the content & configuration
+	     *                   of the view.
+	     * @return {Function} Returns a de-registration function used when the view is destroyed.
+	     */
+	    ViewService.prototype.registerUIView = function (uiView) {
+	        trace_1.trace.traceViewServiceUIViewEvent("-> Registering", uiView);
+	        var uiViews = this.uiViews;
+	        var fqnMatches = function (uiv) { return uiv.fqn === uiView.fqn; };
+	        if (uiViews.filter(fqnMatches).length)
+	            trace_1.trace.traceViewServiceUIViewEvent("!!!! duplicate uiView named:", uiView);
+	        uiViews.push(uiView);
+	        this.sync();
+	        return function () {
+	            var idx = uiViews.indexOf(uiView);
+	            if (idx <= 0) {
+	                trace_1.trace.traceViewServiceUIViewEvent("Tried removing non-registered uiView", uiView);
+	                return;
+	            }
+	            trace_1.trace.traceViewServiceUIViewEvent("<- Deregistering", uiView);
+	            common_1.removeFrom(uiViews)(uiView);
+	        };
+	    };
+	    ;
+	    /**
+	     * Returns the list of views currently available on the page, by fully-qualified name.
+	     *
+	     * @return {Array} Returns an array of fully-qualified view names.
+	     */
+	    ViewService.prototype.available = function () {
+	        return this.uiViews.map(hof_1.prop("fqn"));
+	    };
+	    /**
+	     * Returns the list of views on the page containing loaded content.
+	     *
+	     * @return {Array} Returns an array of fully-qualified view names.
+	     */
+	    ViewService.prototype.active = function () {
+	        return this.uiViews.filter(hof_1.prop("$config")).map(hof_1.prop("name"));
+	    };
+	    /**
+	     * Normalizes a view's name from a state.views configuration block.
+	     *
+	     * @param context the context object (state declaration) that the view belongs to
+	     * @param rawViewName the name of the view, as declared in the [[StateDeclaration.views]]
+	     *
+	     * @returns the normalized uiViewName and uiViewContextAnchor that the view targets
+	     */
+	    ViewService.normalizeUIViewTarget = function (context, rawViewName) {
+	        if (rawViewName === void 0) { rawViewName = ""; }
+	        // TODO: Validate incoming view name with a regexp to allow:
+	        // ex: "view.name@foo.bar" , "^.^.view.name" , "view.name@^.^" , "" ,
+	        // "@" , "$default@^" , "!$default.$default" , "!foo.bar"
+	        var viewAtContext = rawViewName.split("@");
+	        var uiViewName = viewAtContext[0] || "$default"; // default to unnamed view
+	        var uiViewContextAnchor = predicates_1.isString(viewAtContext[1]) ? viewAtContext[1] : "^"; // default to parent context
+	        // Handle relative view-name sugar syntax.
+	        // Matches rawViewName "^.^.^.foo.bar" into array: ["^.^.^.foo.bar", "^.^.^", "foo.bar"],
+	        var relativeViewNameSugar = /^(\^(?:\.\^)*)\.(.*$)/.exec(uiViewName);
+	        if (relativeViewNameSugar) {
+	            // Clobbers existing contextAnchor (rawViewName validation will fix this)
+	            uiViewContextAnchor = relativeViewNameSugar[1]; // set anchor to "^.^.^"
+	            uiViewName = relativeViewNameSugar[2]; // set view-name to "foo.bar"
+	        }
+	        if (uiViewName.charAt(0) === '!') {
+	            uiViewName = uiViewName.substr(1);
+	            uiViewContextAnchor = ""; // target absolutely from root
+	        }
+	        // handle parent relative targeting "^.^.^"
+	        var relativeMatch = /^(\^(?:\.\^)*)$/;
+	        if (relativeMatch.exec(uiViewContextAnchor)) {
+	            var anchor = uiViewContextAnchor.split(".").reduce((function (anchor, x) { return anchor.parent; }), context);
+	            uiViewContextAnchor = anchor.name;
+	        }
+	        return { uiViewName: uiViewName, uiViewContextAnchor: uiViewContextAnchor };
+	    };
+	    return ViewService;
+	}());
+	exports.ViewService = ViewService;
+
+
+/***/ },
+/* 38 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/** @module state */ /** for typedoc */
+	"use strict";
+	var stateMatcher_1 = __webpack_require__(39);
+	var stateBuilder_1 = __webpack_require__(40);
+	var stateQueueManager_1 = __webpack_require__(41);
+	var StateRegistry = (function () {
+	    function StateRegistry(urlMatcherFactory, urlRouterProvider) {
+	        this.states = {};
+	        this.matcher = new stateMatcher_1.StateMatcher(this.states);
+	        this.builder = new stateBuilder_1.StateBuilder(this.matcher, urlMatcherFactory);
+	        this.stateQueue = new stateQueueManager_1.StateQueueManager(this.states, this.builder, urlRouterProvider);
+	        var rootStateDef = {
+	            name: '',
+	            url: '^',
+	            views: null,
+	            params: {
+	                '#': { value: null, type: 'hash', dynamic: true }
+	            },
+	            abstract: true
+	        };
+	        var _root = this._root = this.stateQueue.register(rootStateDef);
+	        _root.navigable = null;
+	    }
+	    StateRegistry.prototype.root = function () {
+	        return this._root;
+	    };
+	    StateRegistry.prototype.register = function (stateDefinition) {
+	        return this.stateQueue.register(stateDefinition);
+	    };
+	    StateRegistry.prototype.get = function (stateOrName, base) {
+	        var _this = this;
+	        if (arguments.length === 0)
+	            return Object.keys(this.states).map(function (name) { return _this.states[name].self; });
+	        var found = this.matcher.find(stateOrName, base);
+	        return found && found.self || null;
+	    };
+	    StateRegistry.prototype.decorator = function (name, func) {
+	        return this.builder.builder(name, func);
+	    };
+	    return StateRegistry;
+	}());
+	exports.StateRegistry = StateRegistry;
+
+
+/***/ },
+/* 39 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module state */ /** for typedoc */
+	var predicates_1 = __webpack_require__(4);
+	var StateMatcher = (function () {
+	    function StateMatcher(_states) {
+	        this._states = _states;
+	    }
+	    StateMatcher.prototype.isRelative = function (stateName) {
+	        stateName = stateName || "";
+	        return stateName.indexOf(".") === 0 || stateName.indexOf("^") === 0;
+	    };
+	    StateMatcher.prototype.find = function (stateOrName, base) {
+	        if (!stateOrName && stateOrName !== "")
+	            return undefined;
+	        var isStr = predicates_1.isString(stateOrName);
+	        var name = isStr ? stateOrName : stateOrName.name;
+	        if (this.isRelative(name))
+	            name = this.resolvePath(name, base);
+	        var state = this._states[name];
+	        if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) {
+	            return state;
+	        }
+	        return undefined;
+	    };
+	    StateMatcher.prototype.resolvePath = function (name, base) {
+	        if (!base)
+	            throw new Error("No reference point given for path '" + name + "'");
+	        var baseState = this.find(base);
+	        var splitName = name.split("."), i = 0, pathLength = splitName.length, current = baseState;
+	        for (; i < pathLength; i++) {
+	            if (splitName[i] === "" && i === 0) {
+	                current = baseState;
+	                continue;
+	            }
+	            if (splitName[i] === "^") {
+	                if (!current.parent)
+	                    throw new Error("Path '" + name + "' not valid for state '" + baseState.name + "'");
+	                current = current.parent;
+	                continue;
+	            }
+	            break;
+	        }
+	        var relName = splitName.slice(i).join(".");
+	        return current.name + (current.name && relName ? "." : "") + relName;
+	    };
+	    return StateMatcher;
+	}());
+	exports.StateMatcher = StateMatcher;
+
+
+/***/ },
+/* 40 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module state */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var strings_1 = __webpack_require__(9);
+	var hof_1 = __webpack_require__(5);
+	var param_1 = __webpack_require__(22);
+	var resolvable_1 = __webpack_require__(19);
+	var coreservices_1 = __webpack_require__(6);
+	var parseUrl = function (url) {
+	    if (!predicates_1.isString(url))
+	        return false;
+	    var root = url.charAt(0) === '^';
+	    return { val: root ? url.substring(1) : url, root: root };
+	};
+	function selfBuilder(state) {
+	    state.self.$$state = function () { return state; };
+	    return state.self;
+	}
+	function dataBuilder(state) {
+	    if (state.parent && state.parent.data) {
+	        state.data = state.self.data = common_1.inherit(state.parent.data, state.data);
+	    }
+	    return state.data;
+	}
+	var getUrlBuilder = function ($urlMatcherFactoryProvider, root) {
+	    return function urlBuilder(state) {
+	        var stateDec = state;
+	        var parsed = parseUrl(stateDec.url), parent = state.parent;
+	        var url = !parsed ? stateDec.url : $urlMatcherFactoryProvider.compile(parsed.val, {
+	            params: state.params || {},
+	            paramMap: function (paramConfig, isSearch) {
+	                if (stateDec.reloadOnSearch === false && isSearch)
+	                    paramConfig = common_1.extend(paramConfig || {}, { dynamic: true });
+	                return paramConfig;
+	            }
+	        });
+	        if (!url)
+	            return null;
+	        if (!$urlMatcherFactoryProvider.isMatcher(url))
+	            throw new Error("Invalid url '" + url + "' in state '" + state + "'");
+	        return (parsed && parsed.root) ? url : ((parent && parent.navigable) || root()).url.append(url);
+	    };
+	};
+	var getNavigableBuilder = function (isRoot) {
+	    return function navigableBuilder(state) {
+	        return !isRoot(state) && state.url ? state : (state.parent ? state.parent.navigable : null);
+	    };
+	};
+	function paramsBuilder(state) {
+	    var makeConfigParam = function (config, id) { return param_1.Param.fromConfig(id, null, config); };
+	    var urlParams = (state.url && state.url.parameters({ inherit: false })) || [];
+	    var nonUrlParams = common_1.values(common_1.map(common_1.omit(state.params || {}, urlParams.map(hof_1.prop('id'))), makeConfigParam));
+	    return urlParams.concat(nonUrlParams).map(function (p) { return [p.id, p]; }).reduce(common_1.applyPairs, {});
+	}
+	function pathBuilder(state) {
+	    return state.parent ? state.parent.path.concat(state) : [state];
+	}
+	function includesBuilder(state) {
+	    var includes = state.parent ? common_1.extend({}, state.parent.includes) : {};
+	    includes[state.name] = true;
+	    return includes;
+	}
+	/**
+	 * This is a [[StateBuilder.builder]] function for the `resolve:` block on a [[StateDeclaration]].
+	 *
+	 * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder
+	 * validates the `resolve` property and converts it to a [[Resolvable]] array.
+	 *
+	 * resolve: input value can be:
+	 *
+	 * {
+	 *   // analyzed but not injected
+	 *   myFooResolve: function() { return "myFooData"; },
+	 *
+	 *   // function.toString() parsed, "DependencyName" dep as string (not min-safe)
+	 *   myBarResolve: function(DependencyName) { return DependencyName.fetchSomethingAsPromise() },
+	 *
+	 *   // Array split; "DependencyName" dep as string
+	 *   myBazResolve: [ "DependencyName", function(dep) { return dep.fetchSomethingAsPromise() },
+	 *
+	 *   // Array split; DependencyType dep as token (compared using ===)
+	 *   myQuxResolve: [ DependencyType, function(dep) { return dep.fetchSometingAsPromise() },
+	 *
+	 *   // val.$inject used as deps
+	 *   // where:
+	 *   //     corgeResolve.$inject = ["DependencyName"];
+	 *   //     function corgeResolve(dep) { dep.fetchSometingAsPromise() }
+	 *   // then "DependencyName" dep as string
+	 *   myCorgeResolve: corgeResolve,
+	 *
+	 *  // inject service by name
+	 *  // When a string is found, desugar creating a resolve that injects the named service
+	 *   myGraultResolve: "SomeService"
+	 * }
+	 *
+	 * or:
+	 *
+	 * [
+	 *   new Resolvable("myFooResolve", function() { return "myFooData" }),
+	 *   new Resolvable("myBarResolve", function(dep) { return dep.fetchSomethingAsPromise() }, [ "DependencyName" ]),
+	 *   { provide: "myBazResolve", useFactory: function(dep) { dep.fetchSomethingAsPromise() }, deps: [ "DependencyName" ] }
+	 * ]
+	 */
+	function resolvablesBuilder(state) {
+	    /** convert a resolve: {} object to an array of tuples */
+	    var obj2Tuples = function (obj) { return Object.keys(obj || {}).map(function (token) { return ({ token: token, val: obj[token], deps: undefined }); }); };
+	    /** fetch DI annotations from a function or ng1-style array */
+	    var annotate = function (fn) { return fn.$inject || coreservices_1.services.$injector.annotate(fn, coreservices_1.services.$injector.strictDi); };
+	    /** true if the object has both `token` and `resolveFn`, and is probably a [[ResolveLiteral]] */
+	    var isResolveLiteral = function (obj) { return !!(obj.token && obj.resolveFn); };
+	    /** true if the object looks like a provide literal, or a ng2 Provider */
+	    var isLikeNg2Provider = function (obj) { return !!((obj.provide || obj.token) && (obj.useValue || obj.useFactory || obj.useExisting || obj.useClass)); };
+	    /** true if the object looks like a tuple from obj2Tuples */
+	    var isTupleFromObj = function (obj) { return !!(obj && obj.val && (predicates_1.isString(obj.val) || predicates_1.isArray(obj.val) || predicates_1.isFunction(obj.val))); };
+	    /** extracts the token from a Provider or provide literal */
+	    var token = function (p) { return p.provide || p.token; };
+	    /** Given a literal resolve or provider object, returns a Resolvable */
+	    var literal2Resolvable = hof_1.pattern([
+	        [hof_1.prop('resolveFn'), function (p) { return new resolvable_1.Resolvable(token(p), p.resolveFn, p.deps, p.policy); }],
+	        [hof_1.prop('useFactory'), function (p) { return new resolvable_1.Resolvable(token(p), p.useFactory, (p.deps || p.dependencies), p.policy); }],
+	        [hof_1.prop('useClass'), function (p) { return new resolvable_1.Resolvable(token(p), function () { return new p.useClass(); }, [], p.policy); }],
+	        [hof_1.prop('useValue'), function (p) { return new resolvable_1.Resolvable(token(p), function () { return p.useValue; }, [], p.policy, p.useValue); }],
+	        [hof_1.prop('useExisting'), function (p) { return new resolvable_1.Resolvable(token(p), function (x) { return x; }, [p.useExisting], p.policy); }],
+	    ]);
+	    var tuple2Resolvable = hof_1.pattern([
+	        [hof_1.pipe(hof_1.prop("val"), predicates_1.isString), function (tuple) { return new resolvable_1.Resolvable(tuple.token, function (x) { return x; }, [tuple.val], tuple.policy); }],
+	        [hof_1.pipe(hof_1.prop("val"), predicates_1.isArray), function (tuple) { return new resolvable_1.Resolvable(tuple.token, common_1.tail(tuple.val), tuple.val.slice(0, -1), tuple.policy); }],
+	        [hof_1.pipe(hof_1.prop("val"), predicates_1.isFunction), function (tuple) { return new resolvable_1.Resolvable(tuple.token, tuple.val, annotate(tuple.val), tuple.policy); }],
+	    ]);
+	    var item2Resolvable = hof_1.pattern([
+	        [hof_1.is(resolvable_1.Resolvable), function (r) { return r; }],
+	        [isResolveLiteral, literal2Resolvable],
+	        [isLikeNg2Provider, literal2Resolvable],
+	        [isTupleFromObj, tuple2Resolvable],
+	        [hof_1.val(true), function (tuple) { throw new Error("Invalid resolve value: " + strings_1.stringify(tuple)); }]
+	    ]);
+	    // If resolveBlock is already an array, use it as-is.
+	    // Otherwise, assume it's an object and convert to an Array of tuples
+	    var decl = state.resolve;
+	    var items = predicates_1.isArray(decl) ? decl : obj2Tuples(decl);
+	    return items.map(item2Resolvable);
+	}
+	exports.resolvablesBuilder = resolvablesBuilder;
+	/**
+	 * @internalapi A internal global service
+	 *
+	 * StateBuilder is a factory for the internal [[State]] objects.
+	 *
+	 * When you register a state with the [[StateRegistry]], you register a plain old javascript object which
+	 * conforms to the [[StateDeclaration]] interface.  This factory takes that object and builds the corresponding
+	 * [[State]] object, which has an API and is used internally.
+	 *
+	 * Custom properties or API may be added to the internal [[State]] object by registering a decorator function
+	 * using the [[builder]] method.
+	 */
+	var StateBuilder = (function () {
+	    function StateBuilder(matcher, $urlMatcherFactoryProvider) {
+	        this.matcher = matcher;
+	        var self = this;
+	        var root = function () { return matcher.find(""); };
+	        var isRoot = function (state) { return state.name === ""; };
+	        function parentBuilder(state) {
+	            if (isRoot(state))
+	                return null;
+	            return matcher.find(self.parentName(state)) || root();
+	        }
+	        this.builders = {
+	            self: [selfBuilder],
+	            parent: [parentBuilder],
+	            data: [dataBuilder],
+	            // Build a URLMatcher if necessary, either via a relative or absolute URL
+	            url: [getUrlBuilder($urlMatcherFactoryProvider, root)],
+	            // Keep track of the closest ancestor state that has a URL (i.e. is navigable)
+	            navigable: [getNavigableBuilder(isRoot)],
+	            params: [paramsBuilder],
+	            // Each framework-specific ui-router implementation should define its own `views` builder
+	            // e.g., src/ng1/statebuilders/views.ts
+	            views: [],
+	            // Keep a full path from the root down to this state as this is needed for state activation.
+	            path: [pathBuilder],
+	            // Speed up $state.includes() as it's used a lot
+	            includes: [includesBuilder],
+	            resolvables: [resolvablesBuilder]
+	        };
+	    }
+	    /**
+	     * Registers a [[BuilderFunction]] for a specific [[State]] property (e.g., `parent`, `url`, or `path`).
+	     * More than one BuilderFunction can be registered for a given property.
+	     *
+	     * The BuilderFunction(s) will be used to define the property on any subsequently built [[State]] objects.
+	     *
+	     * @param name The name of the State property being registered for.
+	     * @param fn The BuilderFunction which will be used to build the State property
+	     * @returns a function which deregisters the BuilderFunction
+	     */
+	    StateBuilder.prototype.builder = function (name, fn) {
+	        var builders = this.builders;
+	        var array = builders[name] || [];
+	        // Backwards compat: if only one builder exists, return it, else return whole arary.
+	        if (predicates_1.isString(name) && !predicates_1.isDefined(fn))
+	            return array.length > 1 ? array : array[0];
+	        if (!predicates_1.isString(name) || !predicates_1.isFunction(fn))
+	            return;
+	        builders[name] = array;
+	        builders[name].push(fn);
+	        return function () { return builders[name].splice(builders[name].indexOf(fn, 1)) && null; };
+	    };
+	    /**
+	     * Builds all of the properties on an essentially blank State object, returning a State object which has all its
+	     * properties and API built.
+	     *
+	     * @param state an uninitialized State object
+	     * @returns the built State object
+	     */
+	    StateBuilder.prototype.build = function (state) {
+	        var _a = this, matcher = _a.matcher, builders = _a.builders;
+	        var parent = this.parentName(state);
+	        if (parent && !matcher.find(parent))
+	            return null;
+	        for (var key in builders) {
+	            if (!builders.hasOwnProperty(key))
+	                continue;
+	            var chain = builders[key].reduce(function (parentFn, step) { return function (_state) { return step(_state, parentFn); }; }, common_1.noop);
+	            state[key] = chain(state);
+	        }
+	        return state;
+	    };
+	    StateBuilder.prototype.parentName = function (state) {
+	        var name = state.name || "";
+	        if (name.indexOf('.') !== -1)
+	            return name.substring(0, name.lastIndexOf('.'));
+	        if (!state.parent)
+	            return "";
+	        return predicates_1.isString(state.parent) ? state.parent : state.parent.name;
+	    };
+	    StateBuilder.prototype.name = function (state) {
+	        var name = state.name;
+	        if (name.indexOf('.') !== -1 || !state.parent)
+	            return name;
+	        var parentName = predicates_1.isString(state.parent) ? state.parent : state.parent.name;
+	        return parentName ? parentName + "." + name : name;
+	    };
+	    return StateBuilder;
+	}());
+	exports.StateBuilder = StateBuilder;
+
+
+/***/ },
+/* 41 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module state */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var stateObject_1 = __webpack_require__(42);
+	var StateQueueManager = (function () {
+	    function StateQueueManager(states, builder, $urlRouterProvider) {
+	        this.states = states;
+	        this.builder = builder;
+	        this.$urlRouterProvider = $urlRouterProvider;
+	        this.queue = [];
+	    }
+	    StateQueueManager.prototype.register = function (config) {
+	        var _a = this, states = _a.states, queue = _a.queue, $state = _a.$state;
+	        // Wrap a new object around the state so we can store our private details easily.
+	        // @TODO: state = new State(extend({}, config, { ... }))
+	        var state = common_1.inherit(new stateObject_1.State(), common_1.extend({}, config, {
+	            self: config,
+	            resolve: config.resolve || [],
+	            toString: function () { return config.name; }
+	        }));
+	        if (!predicates_1.isString(state.name))
+	            throw new Error("State must have a valid name");
+	        if (states.hasOwnProperty(state.name) || common_1.pluck(queue, 'name').indexOf(state.name) !== -1)
+	            throw new Error("State '" + state.name + "' is already defined");
+	        queue.push(state);
+	        if (this.$state) {
+	            this.flush($state);
+	        }
+	        return state;
+	    };
+	    StateQueueManager.prototype.flush = function ($state) {
+	        var _a = this, queue = _a.queue, states = _a.states, builder = _a.builder;
+	        var result, state, orphans = [], orphanIdx, previousQueueLength = {};
+	        while (queue.length > 0) {
+	            state = queue.shift();
+	            result = builder.build(state);
+	            orphanIdx = orphans.indexOf(state);
+	            if (result) {
+	                if (states.hasOwnProperty(state.name))
+	                    throw new Error("State '" + name + "' is already defined");
+	                states[state.name] = state;
+	                this.attachRoute($state, state);
+	                if (orphanIdx >= 0)
+	                    orphans.splice(orphanIdx, 1);
+	                continue;
+	            }
+	            var prev = previousQueueLength[state.name];
+	            previousQueueLength[state.name] = queue.length;
+	            if (orphanIdx >= 0 && prev === queue.length) {
+	                // Wait until two consecutive iterations where no additional states were dequeued successfully.
+	                // throw new Error(`Cannot register orphaned state '${state.name}'`);
+	                return states;
+	            }
+	            else if (orphanIdx < 0) {
+	                orphans.push(state);
+	            }
+	            queue.push(state);
+	        }
+	        return states;
+	    };
+	    StateQueueManager.prototype.autoFlush = function ($state) {
+	        this.$state = $state;
+	        this.flush($state);
+	    };
+	    StateQueueManager.prototype.attachRoute = function ($state, state) {
+	        var $urlRouterProvider = this.$urlRouterProvider;
+	        if (state[common_1.abstractKey] || !state.url)
+	            return;
+	        $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {
+	                if ($state.$current.navigable !== state || !common_1.equalForKeys($match, $stateParams)) {
+	                    $state.transitionTo(state, $match, { inherit: true, location: false });
+	                }
+	            }]);
+	    };
+	    return StateQueueManager;
+	}());
+	exports.StateQueueManager = StateQueueManager;
+
+
+/***/ },
+/* 42 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/** @module state */ /** for typedoc */
+	"use strict";
+	var common_1 = __webpack_require__(3);
+	var hof_1 = __webpack_require__(5);
+	/**
+	 * @ngdoc object
+	 * @name ui.router.state.type:State
+	 *
+	 * @description
+	 * Definition object for states. Includes methods for manipulating the state heirarchy.
+	 *
+	 * @param {Object} config  A configuration object hash that includes the results of user-supplied
+	 *        values, as well as values from `StateBuilder`.
+	 *
+	 * @returns {Object}  Returns a new `State` object.
+	 */
+	var State = (function () {
+	    function State(config) {
+	        common_1.extend(this, config);
+	        // Object.freeze(this);
+	    }
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.type:State#is
+	     * @methodOf ui.router.state.type:State
+	     *
+	     * @description
+	     * Compares the identity of the state against the passed value, which is either an object
+	     * reference to the actual `State` instance, the original definition object passed to
+	     * `$stateProvider.state()`, or the fully-qualified name.
+	     *
+	     * @param {Object} ref Can be one of (a) a `State` instance, (b) an object that was passed
+	     *        into `$stateProvider.state()`, (c) the fully-qualified name of a state as a string.
+	     * @returns {boolean} Returns `true` if `ref` matches the current `State` instance.
+	     */
+	    State.prototype.is = function (ref) {
+	        return this === ref || this.self === ref || this.fqn() === ref;
+	    };
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.type:State#fqn
+	     * @methodOf ui.router.state.type:State
+	     *
+	     * @description
+	     * Returns the fully-qualified name of the state, based on its current position in the tree.
+	     *
+	     * @returns {string} Returns a dot-separated name of the state.
+	     */
+	    State.prototype.fqn = function () {
+	        if (!this.parent || !(this.parent instanceof this.constructor))
+	            return this.name;
+	        var name = this.parent.fqn();
+	        return name ? name + "." + this.name : this.name;
+	    };
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.type:State#root
+	     * @methodOf ui.router.state.type:State
+	     *
+	     * @description
+	     * Returns the root node of this state's tree.
+	     *
+	     * @returns {State} The root of this state's tree.
+	     */
+	    State.prototype.root = function () {
+	        return this.parent && this.parent.root() || this;
+	    };
+	    State.prototype.parameters = function (opts) {
+	        opts = common_1.defaults(opts, { inherit: true });
+	        var inherited = opts.inherit && this.parent && this.parent.parameters() || [];
+	        return inherited.concat(common_1.values(this.params));
+	    };
+	    State.prototype.parameter = function (id, opts) {
+	        if (opts === void 0) { opts = {}; }
+	        return (this.url && this.url.parameter(id, opts) ||
+	            common_1.find(common_1.values(this.params), hof_1.propEq('id', id)) ||
+	            opts.inherit && this.parent && this.parent.parameter(id));
+	    };
+	    State.prototype.toString = function () {
+	        return this.fqn();
+	    };
+	    return State;
+	}());
+	exports.State = State;
+
+
+/***/ },
+/* 43 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module state */ /** */
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var queue_1 = __webpack_require__(8);
+	var coreservices_1 = __webpack_require__(6);
+	var pathFactory_1 = __webpack_require__(20);
+	var node_1 = __webpack_require__(21);
+	var transitionService_1 = __webpack_require__(31);
+	var rejectFactory_1 = __webpack_require__(10);
+	var targetState_1 = __webpack_require__(14);
+	var param_1 = __webpack_require__(22);
+	var glob_1 = __webpack_require__(7);
+	var common_2 = __webpack_require__(3);
+	var common_3 = __webpack_require__(3);
+	var StateService = (function () {
+	    /** @hidden */
+	    function StateService(router) {
+	        this.router = router;
+	        /** @hidden */
+	        this._defaultErrorHandler = function $defaultErrorHandler($error$) {
+	            if ($error$ instanceof Error && $error$.stack) {
+	                console.error($error$.stack);
+	            }
+	            else if ($error$ instanceof rejectFactory_1.Rejection) {
+	                console.error($error$);
+	                if ($error$.detail && $error$.detail.stack)
+	                    console.error($error$.detail.stack);
+	            }
+	            else {
+	                console.error($error$);
+	            }
+	        };
+	        var getters = ['current', '$current', 'params', 'transition'];
+	        var boundFns = Object.keys(StateService.prototype).filter(function (key) { return getters.indexOf(key) === -1; });
+	        common_3.bindFunctions(StateService.prototype, this, this, boundFns);
+	    }
+	    Object.defineProperty(StateService.prototype, "transition", {
+	        get: function () { return this.router.globals.transition; },
+	        enumerable: true,
+	        configurable: true
+	    });
+	    Object.defineProperty(StateService.prototype, "params", {
+	        get: function () { return this.router.globals.params; },
+	        enumerable: true,
+	        configurable: true
+	    });
+	    Object.defineProperty(StateService.prototype, "current", {
+	        get: function () { return this.router.globals.current; },
+	        enumerable: true,
+	        configurable: true
+	    });
+	    Object.defineProperty(StateService.prototype, "$current", {
+	        get: function () { return this.router.globals.$current; },
+	        enumerable: true,
+	        configurable: true
+	    });
+	    /**
+	     * Handler for when [[transitionTo]] is called with an invalid state.
+	     *
+	     * Invokes the [[onInvalid]] callbacks, in natural order.
+	     * Each callback's return value is checked in sequence until one of them returns an instance of TargetState.
+	     * The results of the callbacks are wrapped in $q.when(), so the callbacks may return promises.
+	     *
+	     * If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and the result returned.
+	     */
+	    StateService.prototype._handleInvalidTargetState = function (fromPath, $to$) {
+	        var _this = this;
+	        var globals = this.router.globals;
+	        var latestThing = function () { return globals.transitionHistory.peekTail(); };
+	        var latest = latestThing();
+	        var $from$ = pathFactory_1.PathFactory.makeTargetState(fromPath);
+	        var callbackQueue = new queue_1.Queue([].concat(this.router.stateProvider.invalidCallbacks));
+	        var $q = coreservices_1.services.$q, $injector = coreservices_1.services.$injector;
+	        var invokeCallback = function (callback) { return $q.when($injector.invoke(callback, null, { $to$: $to$, $from$: $from$ })); };
+	        var checkForRedirect = function (result) {
+	            if (!(result instanceof targetState_1.TargetState)) {
+	                return;
+	            }
+	            var target = result;
+	            // Recreate the TargetState, in case the state is now defined.
+	            target = _this.target(target.identifier(), target.params(), target.options());
+	            if (!target.valid())
+	                return rejectFactory_1.Rejection.invalid(target.error()).toPromise();
+	            if (latestThing() !== latest)
+	                return rejectFactory_1.Rejection.superseded().toPromise();
+	            return _this.transitionTo(target.identifier(), target.params(), target.options());
+	        };
+	        function invokeNextCallback() {
+	            var nextCallback = callbackQueue.dequeue();
+	            if (nextCallback === undefined)
+	                return rejectFactory_1.Rejection.invalid($to$.error()).toPromise();
+	            return invokeCallback(nextCallback).then(checkForRedirect).then(function (result) { return result || invokeNextCallback(); });
+	        }
+	        return invokeNextCallback();
+	    };
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.$state#reload
+	     * @methodOf ui.router.state.$state
+	     *
+	     * @description
+	     * A method that force reloads the current state, or a partial state hierarchy. All resolves are re-resolved,
+	     * controllers reinstantiated, and events re-fired.
+	     *
+	     * @example
+	     * <pre>
+	     * let app angular.module('app', ['ui.router']);
+	     *
+	     * app.controller('ctrl', function ($scope, $state) {
+	     *   $scope.reload = function(){
+	     *     $state.reload();
+	     *   }
+	     * });
+	     * </pre>
+	     *
+	     * `reload()` is just an alias for:
+	     * <pre>
+	     * $state.transitionTo($state.current, $stateParams, {
+	     *   reload: true, inherit: false, notify: true
+	     * });
+	     * </pre>
+	     *
+	     * @param {string=|object=} reloadState - A state name or a state object, which is the root of the resolves to be re-resolved.
+	     * @example
+	     * <pre>
+	     * //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item'
+	     * //and current state is 'contacts.detail.item'
+	     * let app angular.module('app', ['ui.router']);
+	     *
+	     * app.controller('ctrl', function ($scope, $state) {
+	     *   $scope.reload = function(){
+	     *     //will reload 'contact.detail' and nested 'contact.detail.item' states
+	     *     $state.reload('contact.detail');
+	     *   }
+	     * });
+	     * </pre>
+	     *
+	     * @returns {promise} A promise representing the state of the new transition. See
+	     * {@link ui.router.state.$state#methods_go $state.go}.
+	     */
+	    StateService.prototype.reload = function (reloadState) {
+	        return this.transitionTo(this.current, this.params, {
+	            reload: predicates_1.isDefined(reloadState) ? reloadState : true,
+	            inherit: false,
+	            notify: false
+	        });
+	    };
+	    ;
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.$state#go
+	     * @methodOf ui.router.state.$state
+	     *
+	     * @description
+	     * Convenience method for transitioning to a new state. `$state.go` calls
+	     * `$state.transitionTo` internally but automatically sets options to
+	     * `{ location: true, inherit: true, relative: $state.$current, notify: true }`.
+	     * This allows you to easily use an absolute or relative to path and specify
+	     * only the parameters you'd like to update (while letting unspecified parameters
+	     * inherit from the currently active ancestor states).
+	     *
+	     * @example
+	     * <pre>
+	     * let app = angular.module('app', ['ui.router']);
+	     *
+	     * app.controller('ctrl', function ($scope, $state) {
+	     *   $scope.changeState = function () {
+	     *     $state.go('contact.detail');
+	     *   };
+	     * });
+	     * </pre>
+	     * <img src='../ngdoc_assets/StateGoExamples.png'/>
+	     *
+	     * @param {string} to Absolute state name or relative state path. Some examples:
+	     *
+	     * - `$state.go('contact.detail')` - will go to the `contact.detail` state
+	     * - `$state.go('^')` - will go to a parent state
+	     * - `$state.go('^.sibling')` - will go to a sibling state
+	     * - `$state.go('.child.grandchild')` - will go to grandchild state
+	     *
+	     * @param {object=} params A map of the parameters that will be sent to the state,
+	     * will populate $stateParams. Any parameters that are not specified will be inherited from currently
+	     * defined parameters. This allows, for example, going to a sibling state that shares parameters
+	     * specified in a parent state. Parameter inheritance only works between common ancestor states, I.e.
+	     * transitioning to a sibling will get you the parameters for all parents, transitioning to a child
+	     * will get you all current parameters, etc.
+	     * @param {object=} options Options object. The options are:
+	     *
+	     * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`
+	     *    will not. If string, must be `"replace"`, which will update url and also replace last history record.
+	     * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.
+	     * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),
+	     *    defines which state to be relative from.
+	     * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.
+	     * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params
+	     *    have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd
+	     *    use this when you want to force a reload when *everything* is the same, including search params.
+	     *
+	     * @returns {promise} A promise representing the state of the new transition.
+	     *
+	     * Possible success values:
+	     *
+	     * - $state.current
+	     *
+	     * <br/>Possible rejection values:
+	     *
+	     * - 'transition superseded' - when a newer transition has been started after this one
+	     * - 'transition prevented' - when `event.preventDefault()` has been called in a `$stateChangeStart` listener
+	     * - 'transition aborted' - when `event.preventDefault()` has been called in a `$stateNotFound` listener or
+	     *   when a `$stateNotFound` `event.retry` promise errors.
+	     * - 'transition failed' - when a state has been unsuccessfully found after 2 tries.
+	     * - *resolve error* - when an error has occurred with a `resolve`
+	     *
+	     */
+	    StateService.prototype.go = function (to, params, options) {
+	        var defautGoOpts = { relative: this.$current, inherit: true };
+	        var transOpts = common_1.defaults(options, defautGoOpts, transitionService_1.defaultTransOpts);
+	        return this.transitionTo(to, params, transOpts);
+	    };
+	    ;
+	    /** Factory method for creating a TargetState */
+	    StateService.prototype.target = function (identifier, params, options) {
+	        if (options === void 0) { options = {}; }
+	        // If we're reloading, find the state object to reload from
+	        if (predicates_1.isObject(options.reload) && !options.reload.name)
+	            throw new Error('Invalid reload state object');
+	        var reg = this.router.stateRegistry;
+	        options.reloadState = options.reload === true ? reg.root() : reg.matcher.find(options.reload, options.relative);
+	        if (options.reload && !options.reloadState)
+	            throw new Error("No such reload state '" + (predicates_1.isString(options.reload) ? options.reload : options.reload.name) + "'");
+	        var stateDefinition = reg.matcher.find(identifier, options.relative);
+	        return new targetState_1.TargetState(identifier, stateDefinition, params, options);
+	    };
+	    ;
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.$state#transitionTo
+	     * @methodOf ui.router.state.$state
+	     *
+	     * @description
+	     * Low-level method for transitioning to a new state. {@link ui.router.state.$state#methods_go $state.go}
+	     * uses `transitionTo` internally. `$state.go` is recommended in most situations.
+	     *
+	     * @example
+	     * <pre>
+	     * let app = angular.module('app', ['ui.router']);
+	     *
+	     * app.controller('ctrl', function ($scope, $state) {
+	     *   $scope.changeState = function () {
+	     *     $state.transitionTo('contact.detail');
+	     *   };
+	     * });
+	     * </pre>
+	     *
+	     * @param {string} to State name.
+	     * @param {object=} toParams A map of the parameters that will be sent to the state,
+	     * will populate $stateParams.
+	     * @param {object=} options Options object. The options are:
+	     *
+	     * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`
+	     *    will not. If string, must be `"replace"`, which will update url and also replace last history record.
+	     * - **`inherit`** - {boolean=false}, If `true` will inherit url parameters from current url.
+	     * - **`relative`** - {object=}, When transitioning with relative path (e.g '^'),
+	     *    defines which state to be relative from.
+	     * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.
+	     * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params
+	     *    have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd
+	     *    use this when you want to force a reload when *everything* is the same, including search params.
+	     *
+	     * @returns {promise} A promise representing the state of the new transition. See
+	     * {@link ui.router.state.$state#methods_go $state.go}.
+	     */
+	    StateService.prototype.transitionTo = function (to, toParams, options) {
+	        var _this = this;
+	        if (toParams === void 0) { toParams = {}; }
+	        if (options === void 0) { options = {}; }
+	        var router = this.router;
+	        var globals = router.globals;
+	        var transHistory = globals.transitionHistory;
+	        options = common_1.defaults(options, transitionService_1.defaultTransOpts);
+	        options = common_1.extend(options, { current: transHistory.peekTail.bind(transHistory) });
+	        var ref = this.target(to, toParams, options);
+	        var latestSuccess = globals.successfulTransitions.peekTail();
+	        var rootPath = function () { return [new node_1.PathNode(_this.router.stateRegistry.root())]; };
+	        var currentPath = latestSuccess ? latestSuccess.treeChanges().to : rootPath();
+	        if (!ref.exists())
+	            return this._handleInvalidTargetState(currentPath, ref);
+	        if (!ref.valid())
+	            return common_1.silentRejection(ref.error());
+	        /**
+	         * Special handling for Ignored, Aborted, and Redirected transitions
+	         *
+	         * The semantics for the transition.run() promise and the StateService.transitionTo()
+	         * promise differ. For instance, the run() promise may be rejected because it was
+	         * IGNORED, but the transitionTo() promise is resolved because from the user perspective
+	         * no error occurred.  Likewise, the transition.run() promise may be rejected because of
+	         * a Redirect, but the transitionTo() promise is chained to the new Transition's promise.
+	         */
+	        var rejectedTransitionHandler = function (transition) { return function (error) {
+	            if (error instanceof rejectFactory_1.Rejection) {
+	                if (error.type === rejectFactory_1.RejectType.IGNORED) {
+	                    router.urlRouter.update();
+	                    return globals.current;
+	                }
+	                if (error.type === rejectFactory_1.RejectType.SUPERSEDED && error.redirected && error.detail instanceof targetState_1.TargetState) {
+	                    var redirect = transition.redirect(error.detail);
+	                    return redirect.run().catch(rejectedTransitionHandler(redirect));
+	                }
+	                if (error.type === rejectFactory_1.RejectType.ABORTED) {
+	                    router.urlRouter.update();
+	                    return coreservices_1.services.$q.reject(error);
+	                }
+	            }
+	            var errorHandler = _this.defaultErrorHandler();
+	            errorHandler(error);
+	            return coreservices_1.services.$q.reject(error);
+	        }; };
+	        var transition = this.router.transitionService.create(currentPath, ref);
+	        var transitionToPromise = transition.run().catch(rejectedTransitionHandler(transition));
+	        common_1.silenceUncaughtInPromise(transitionToPromise); // issue #2676
+	        // Return a promise for the transition, which also has the transition object on it.
+	        return common_1.extend(transitionToPromise, { transition: transition });
+	    };
+	    ;
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.$state#is
+	     * @methodOf ui.router.state.$state
+	     *
+	     * @description
+	     * Similar to {@link ui.router.state.$state#methods_includes $state.includes},
+	     * but only checks for the full state name. If params is supplied then it will be
+	     * tested for strict equality against the current active params object, so all params
+	     * must match with none missing and no extras.
+	     *
+	     * @example
+	     * <pre>
+	     * $state.$current.name = 'contacts.details.item';
+	     *
+	     * // absolute name
+	     * $state.is('contact.details.item'); // returns true
+	     * $state.is(contactDetailItemStateObject); // returns true
+	     *
+	     * // relative name (. and ^), typically from a template
+	     * // E.g. from the 'contacts.details' template
+	     * <div ng-class="{highlighted: $state.is('.item')}">Item</div>
+	     * </pre>
+	     *
+	     * @param {string|object} stateOrName The state name (absolute or relative) or state object you'd like to check.
+	     * @param {object=} params A param object, e.g. `{sectionId: section.id}`, that you'd like
+	     * to test against the current active state.
+	     * @param {object=} options An options object.  The options are:
+	     *
+	     * - **`relative`** - {string|object} -  If `stateOrName` is a relative state name and `options.relative` is set, .is will
+	     * test relative to `options.relative` state (or name).
+	     *
+	     * @returns {boolean} Returns true if it is the state.
+	     */
+	    StateService.prototype.is = function (stateOrName, params, options) {
+	        options = common_1.defaults(options, { relative: this.$current });
+	        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative);
+	        if (!predicates_1.isDefined(state))
+	            return undefined;
+	        if (this.$current !== state)
+	            return false;
+	        return predicates_1.isDefined(params) && params !== null ? param_1.Param.equals(state.parameters(), this.params, params) : true;
+	    };
+	    ;
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.$state#includes
+	     * @methodOf ui.router.state.$state
+	     *
+	     * @description
+	     * A method to determine if the current active state is equal to or is the child of the
+	     * state stateName. If any params are passed then they will be tested for a match as well.
+	     * Not all the parameters need to be passed, just the ones you'd like to test for equality.
+	     *
+	     * @example
+	     * Partial and relative names
+	     * <pre>
+	     * $state.$current.name = 'contacts.details.item';
+	     *
+	     * // Using partial names
+	     * $state.includes("contacts"); // returns true
+	     * $state.includes("contacts.details"); // returns true
+	     * $state.includes("contacts.details.item"); // returns true
+	     * $state.includes("contacts.list"); // returns false
+	     * $state.includes("about"); // returns false
+	     *
+	     * // Using relative names (. and ^), typically from a template
+	     * // E.g. from the 'contacts.details' template
+	     * <div ng-class="{highlighted: $state.includes('.item')}">Item</div>
+	     * </pre>
+	     *
+	     * Basic globbing patterns
+	     * <pre>
+	     * $state.$current.name = 'contacts.details.item.url';
+	     *
+	     * $state.includes("*.details.*.*"); // returns true
+	     * $state.includes("*.details.**"); // returns true
+	     * $state.includes("**.item.**"); // returns true
+	     * $state.includes("*.details.item.url"); // returns true
+	     * $state.includes("*.details.*.url"); // returns true
+	     * $state.includes("*.details.*"); // returns false
+	     * $state.includes("item.**"); // returns false
+	     * </pre>
+	     *
+	     * @param {string} stateOrName A partial name, relative name, or glob pattern
+	     * to be searched for within the current state name.
+	     * @param {object=} params A param object, e.g. `{sectionId: section.id}`,
+	     * that you'd like to test against the current active state.
+	     * @param {object=} options An options object.  The options are:
+	     *
+	     * - **`relative`** - {string|object=} -  If `stateOrName` is a relative state reference and `options.relative` is set,
+	     * .includes will test relative to `options.relative` state (or name).
+	     *
+	     * @returns {boolean} Returns true if it does include the state
+	     */
+	    StateService.prototype.includes = function (stateOrName, params, options) {
+	        options = common_1.defaults(options, { relative: this.$current });
+	        var glob = predicates_1.isString(stateOrName) && glob_1.Glob.fromString(stateOrName);
+	        if (glob) {
+	            if (!glob.matches(this.$current.name))
+	                return false;
+	            stateOrName = this.$current.name;
+	        }
+	        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative), include = this.$current.includes;
+	        if (!predicates_1.isDefined(state))
+	            return undefined;
+	        if (!predicates_1.isDefined(include[state.name]))
+	            return false;
+	        // @TODO Replace with Param.equals() ?
+	        return params ? common_2.equalForKeys(param_1.Param.values(state.parameters(), params), this.params, Object.keys(params)) : true;
+	    };
+	    ;
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.$state#href
+	     * @methodOf ui.router.state.$state
+	     *
+	     * @description
+	     * A url generation method that returns the compiled url for the given state populated with the given params.
+	     *
+	     * @example
+	     * <pre>
+	     * expect($state.href("about.person", { person: "bob" })).toEqual("/about/bob");
+	     * </pre>
+	     *
+	     * @param {string|object} stateOrName The state name or state object you'd like to generate a url from.
+	     * @param {object=} params An object of parameter values to fill the state's required parameters.
+	     * @param {object=} options Options object. The options are:
+	     *
+	     * - **`lossy`** - {boolean=true} -  If true, and if there is no url associated with the state provided in the
+	     *    first parameter, then the constructed href url will be built from the first navigable ancestor (aka
+	     *    ancestor with a valid url).
+	     * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.
+	     * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),
+	     *    defines which state to be relative from.
+	     * - **`absolute`** - {boolean=false},  If true will generate an absolute url, e.g. "http://www.example.com/fullurl".
+	     *
+	     * @returns {string} compiled state url
+	     */
+	    StateService.prototype.href = function (stateOrName, params, options) {
+	        var defaultHrefOpts = {
+	            lossy: true,
+	            inherit: true,
+	            absolute: false,
+	            relative: this.$current
+	        };
+	        options = common_1.defaults(options, defaultHrefOpts);
+	        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative);
+	        if (!predicates_1.isDefined(state))
+	            return null;
+	        if (options.inherit)
+	            params = this.params.$inherit(params || {}, this.$current, state);
+	        var nav = (state && options.lossy) ? state.navigable : state;
+	        if (!nav || nav.url === undefined || nav.url === null) {
+	            return null;
+	        }
+	        return this.router.urlRouter.href(nav.url, param_1.Param.values(state.parameters(), params), {
+	            absolute: options.absolute
+	        });
+	    };
+	    ;
+	    /**
+	     * Sets or gets the default [[transitionTo]] error handler.
+	     *
+	     * The error handler is called when a [[Transition]] is rejected or when any error occurred during the Transition.
+	     * This includes errors caused by resolves and transition hooks.
+	     *
+	     * The built-in default error handler logs the error to the console.
+	     *
+	     * You can provide your own custom handler.
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * stateService.defaultErrorHandler(function() {
+	     *   // Do not log transitionTo errors
+	     * });
+	     * ```
+	     *
+	     * @param handler a global error handler function
+	     * @returns the current global error handler
+	     */
+	    StateService.prototype.defaultErrorHandler = function (handler) {
+	        return this._defaultErrorHandler = handler || this._defaultErrorHandler;
+	    };
+	    StateService.prototype.get = function (stateOrName, base) {
+	        var reg = this.router.stateRegistry;
+	        if (arguments.length === 0)
+	            return reg.get();
+	        return reg.get(stateOrName, base || this.$current);
+	    };
+	    return StateService;
+	}());
+	exports.StateService = StateService;
+
+
+/***/ },
+/* 44 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module core */ /** */
+	var stateParams_1 = __webpack_require__(45);
+	var queue_1 = __webpack_require__(8);
+	var common_1 = __webpack_require__(3);
+	/**
+	 * Global mutable state
+	 */
+	var Globals = (function () {
+	    function Globals(transitionService) {
+	        var _this = this;
+	        this.params = new stateParams_1.StateParams();
+	        this.transitionHistory = new queue_1.Queue([], 1);
+	        this.successfulTransitions = new queue_1.Queue([], 1);
+	        var beforeNewTransition = function ($transition$) {
+	            _this.transition = $transition$;
+	            _this.transitionHistory.enqueue($transition$);
+	            var updateGlobalState = function () {
+	                _this.successfulTransitions.enqueue($transition$);
+	                _this.$current = $transition$.$to();
+	                _this.current = _this.$current.self;
+	                common_1.copy($transition$.params(), _this.params);
+	            };
+	            $transition$.onSuccess({}, updateGlobalState, { priority: 10000 });
+	            var clearCurrentTransition = function () { if (_this.transition === $transition$)
+	                _this.transition = null; };
+	            $transition$.promise.then(clearCurrentTransition, clearCurrentTransition);
+	        };
+	        transitionService.onBefore({}, beforeNewTransition);
+	    }
+	    return Globals;
+	}());
+	exports.Globals = Globals;
+
+
+/***/ },
+/* 45 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module params */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var StateParams = (function () {
+	    function StateParams(params) {
+	        if (params === void 0) { params = {}; }
+	        common_1.extend(this, params);
+	    }
+	    /**
+	     * Merges a set of parameters with all parameters inherited between the common parents of the
+	     * current state and a given destination state.
+	     *
+	     * @param {Object} newParams The set of parameters which will be composited with inherited params.
+	     * @param {Object} $current Internal definition of object representing the current state.
+	     * @param {Object} $to Internal definition of object representing state to transition to.
+	     */
+	    StateParams.prototype.$inherit = function (newParams, $current, $to) {
+	        var parents = common_1.ancestors($current, $to), parentParams, inherited = {}, inheritList = [];
+	        for (var i in parents) {
+	            if (!parents[i] || !parents[i].params)
+	                continue;
+	            parentParams = Object.keys(parents[i].params);
+	            if (!parentParams.length)
+	                continue;
+	            for (var j in parentParams) {
+	                if (inheritList.indexOf(parentParams[j]) >= 0)
+	                    continue;
+	                inheritList.push(parentParams[j]);
+	                inherited[parentParams[j]] = this[parentParams[j]];
+	            }
+	        }
+	        return common_1.extend({}, inherited, newParams);
+	    };
+	    ;
+	    return StateParams;
+	}());
+	exports.StateParams = StateParams;
+
+
+/***/ },
+/* 46 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	/**
+	 * This module contains code for State Parameters.
+	 *
+	 * See [[ParamDeclaration]]
+	 * @module params
+	 * @preferred doc
+	 */
+	/** for typedoc */
+	__export(__webpack_require__(22));
+	__export(__webpack_require__(25));
+	__export(__webpack_require__(45));
+	__export(__webpack_require__(24));
+
+
+/***/ },
+/* 47 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	/** @module path */ /** for typedoc */
+	__export(__webpack_require__(21));
+	__export(__webpack_require__(20));
+
+
+/***/ },
+/* 48 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	/** @module resolve */ /** for typedoc */
+	__export(__webpack_require__(18));
+	__export(__webpack_require__(19));
+	__export(__webpack_require__(17));
+
+
+/***/ },
+/* 49 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	/** @module state */ /** for typedoc */
+	__export(__webpack_require__(30));
+	__export(__webpack_require__(40));
+	__export(__webpack_require__(42));
+	__export(__webpack_require__(39));
+	__export(__webpack_require__(41));
+	__export(__webpack_require__(38));
+	__export(__webpack_require__(43));
+	__export(__webpack_require__(14));
+
+
+/***/ },
+/* 50 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	/**
+	 * This module contains APIs related to a Transition.
+	 *
+	 * See [[Transition]], [[$transitions]]
+	 *
+	 * @module transition
+	 * @preferred
+	 */
+	/** for typedoc */
+	__export(__webpack_require__(16));
+	__export(__webpack_require__(15));
+	__export(__webpack_require__(10));
+	__export(__webpack_require__(11));
+	__export(__webpack_require__(13));
+	__export(__webpack_require__(31));
+
+
+/***/ },
+/* 51 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	/** @module url */ /** for typedoc */
+	__export(__webpack_require__(28));
+	__export(__webpack_require__(23));
+	__export(__webpack_require__(27));
+	__export(__webpack_require__(29));
+
+
+/***/ },
+/* 52 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	function __export(m) {
+	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+	}
+	/** @module view */ /** for typedoc */
+	__export(__webpack_require__(37));
+
+
+/***/ },
+/* 53 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/**
+	 * # UI-Router for Angular 1
+	 *
+	 * - Provides an implementation for the [[CoreServices]] API, based on angular 1 services.
+	 * - Also registers some services with the angular 1 injector.
+	 * - Creates and bootstraps a new [[UIRouter]] object.  Ties it to the the angular 1 lifecycle.
+	 *
+	 * @module ng1
+	 * @preferred
+	 */
+	"use strict";
+	/** for typedoc */
+	var router_1 = __webpack_require__(26);
+	var coreservices_1 = __webpack_require__(6);
+	var common_1 = __webpack_require__(3);
+	var hof_1 = __webpack_require__(5);
+	var predicates_1 = __webpack_require__(4);
+	var resolveService_1 = __webpack_require__(54);
+	var trace_1 = __webpack_require__(12);
+	var views_1 = __webpack_require__(55);
+	var templateFactory_1 = __webpack_require__(56);
+	var onEnterExitRetain_1 = __webpack_require__(57);
+	/** @hidden */
+	var app = angular.module("ui.router.angular1", []);
+	/**
+	 * @ngdoc overview
+	 * @name ui.router.util
+	 *
+	 * @description
+	 * # ui.router.util sub-module
+	 *
+	 * This module is a dependency of other sub-modules. Do not include this module as a dependency
+	 * in your angular app (use {@link ui.router} module instead).
+	 *
+	 */
+	angular.module('ui.router.util', ['ng', 'ui.router.init']);
+	/**
+	 * @ngdoc overview
+	 * @name ui.router.router
+	 *
+	 * @requires ui.router.util
+	 *
+	 * @description
+	 * # ui.router.router sub-module
+	 *
+	 * This module is a dependency of other sub-modules. Do not include this module as a dependency
+	 * in your angular app (use {@link ui.router} module instead).
+	 */
+	angular.module('ui.router.router', ['ui.router.util']);
+	/**
+	 * @ngdoc overview
+	 * @name ui.router.state
+	 *
+	 * @requires ui.router.router
+	 * @requires ui.router.util
+	 *
+	 * @description
+	 * # ui.router.state sub-module
+	 *
+	 * This module is a dependency of the main ui.router module. Do not include this module as a dependency
+	 * in your angular app (use {@link ui.router} module instead).
+	 *
+	 */
+	angular.module('ui.router.state', ['ui.router.router', 'ui.router.util', 'ui.router.angular1']);
+	/**
+	 * @ngdoc overview
+	 * @name ui.router
+	 *
+	 * @requires ui.router.state
+	 *
+	 * @description
+	 * # ui.router
+	 *
+	 * ## The main module for ui.router
+	 * There are several sub-modules included with the ui.router module, however only this module is needed
+	 * as a dependency within your angular app. The other modules are for organization purposes.
+	 *
+	 * The modules are:
+	 * * ui.router - the main "umbrella" module
+	 * * ui.router.router -
+	 *
+	 * *You'll need to include **only** this module as the dependency within your angular app.*
+	 *
+	 * <pre>
+	 * <!doctype html>
+	 * <html ng-app="myApp">
+	 * <head>
+	 *   <script src="js/angular.js"></script>
+	 *   <!-- Include the ui-router script -->
+	 *   <script src="js/angular-ui-router.min.js"></script>
+	 *   <script>
+	 *     // ...and add 'ui.router' as a dependency
+	 *     var myApp = angular.module('myApp', ['ui.router']);
+	 *   </script>
+	 * </head>
+	 * <body>
+	 * </body>
+	 * </html>
+	 * </pre>
+	 */
+	angular.module('ui.router', ['ui.router.init', 'ui.router.state', 'ui.router.angular1']);
+	angular.module('ui.router.compat', ['ui.router']);
+	/**
+	 * Annotates a controller expression (may be a controller function(), a "controllername",
+	 * or "controllername as name")
+	 *
+	 * - Temporarily decorates $injector.instantiate.
+	 * - Invokes $controller() service
+	 *   - Calls $injector.instantiate with controller constructor
+	 * - Annotate constructor
+	 * - Undecorate $injector
+	 *
+	 * returns an array of strings, which are the arguments of the controller expression
+	 */
+	function annotateController(controllerExpression) {
+	    var $injector = coreservices_1.services.$injector;
+	    var $controller = $injector.get("$controller");
+	    var oldInstantiate = $injector.instantiate;
+	    try {
+	        var deps_1;
+	        $injector.instantiate = function fakeInstantiate(constructorFunction) {
+	            $injector.instantiate = oldInstantiate; // Un-decorate ASAP
+	            deps_1 = $injector.annotate(constructorFunction);
+	        };
+	        $controller(controllerExpression, { $scope: {} });
+	        return deps_1;
+	    }
+	    finally {
+	        $injector.instantiate = oldInstantiate;
+	    }
+	}
+	exports.annotateController = annotateController;
+	runBlock.$inject = ['$injector', '$q'];
+	function runBlock($injector, $q) {
+	    coreservices_1.services.$injector = $injector;
+	    coreservices_1.services.$q = $q;
+	}
+	app.run(runBlock);
+	var router = null;
+	ng1UIRouter.$inject = ['$locationProvider'];
+	/** This angular 1 provider instantiates a Router and exposes its services via the angular injector */
+	function ng1UIRouter($locationProvider) {
+	    // Create a new instance of the Router when the ng1UIRouterProvider is initialized
+	    router = new router_1.UIRouter();
+	    // Apply ng1 specific StateBuilder code for `views`, `resolve`, and `onExit/Retain/Enter` properties
+	    router.stateRegistry.decorator("views", views_1.ng1ViewsBuilder);
+	    router.stateRegistry.decorator("onExit", onEnterExitRetain_1.getStateHookBuilder("onExit"));
+	    router.stateRegistry.decorator("onRetain", onEnterExitRetain_1.getStateHookBuilder("onRetain"));
+	    router.stateRegistry.decorator("onEnter", onEnterExitRetain_1.getStateHookBuilder("onEnter"));
+	    router.viewService.viewConfigFactory('ng1', views_1.ng1ViewConfigFactory);
+	    // Bind LocationConfig.hashPrefix to $locationProvider.hashPrefix
+	    common_1.bindFunctions($locationProvider, coreservices_1.services.locationConfig, $locationProvider, ['hashPrefix']);
+	    // Create a LocationService.onChange registry
+	    var urlListeners = [];
+	    coreservices_1.services.location.onChange = function (callback) {
+	        urlListeners.push(callback);
+	        return function () { return common_1.removeFrom(urlListeners)(callback); };
+	    };
+	    this.$get = $get;
+	    $get.$inject = ['$location', '$browser', '$sniffer', '$rootScope', '$http', '$templateCache'];
+	    function $get($location, $browser, $sniffer, $rootScope, $http, $templateCache) {
+	        // Bind $locationChangeSuccess to the listeners registered in LocationService.onChange
+	        $rootScope.$on("$locationChangeSuccess", function (evt) { return urlListeners.forEach(function (fn) { return fn(evt); }); });
+	        // Bind LocationConfig.html5Mode to $locationProvider.html5Mode and $sniffer.history
+	        coreservices_1.services.locationConfig.html5Mode = function () {
+	            var html5Mode = $locationProvider.html5Mode();
+	            html5Mode = predicates_1.isObject(html5Mode) ? html5Mode.enabled : html5Mode;
+	            return html5Mode && $sniffer.history;
+	        };
+	        coreservices_1.services.template.get = function (url) {
+	            return $http.get(url, { cache: $templateCache, headers: { Accept: 'text/html' } }).then(hof_1.prop("data"));
+	        };
+	        // Bind these LocationService functions to $location
+	        common_1.bindFunctions($location, coreservices_1.services.location, $location, ["replace", "url", "path", "search", "hash"]);
+	        // Bind these LocationConfig functions to $location
+	        common_1.bindFunctions($location, coreservices_1.services.locationConfig, $location, ['port', 'protocol', 'host']);
+	        // Bind these LocationConfig functions to $browser
+	        common_1.bindFunctions($browser, coreservices_1.services.locationConfig, $browser, ['baseHref']);
+	        return router;
+	    }
+	}
+	function $stateParamsFactory(ng1UIRouter) {
+	    return ng1UIRouter.globals.params;
+	}
+	// The 'ui.router' ng1 module depends on 'ui.router.init' module.
+	angular.module('ui.router.init', []).provider("ng1UIRouter", ng1UIRouter);
+	// This effectively calls $get() to init when we enter runtime
+	angular.module('ui.router.init').run(['ng1UIRouter', function (ng1UIRouter) { }]);
+	// $urlMatcherFactory service and $urlMatcherFactoryProvider
+	angular.module('ui.router.util').provider('$urlMatcherFactory', ['ng1UIRouterProvider', function () { return router.urlMatcherFactory; }]);
+	angular.module('ui.router.util').run(['$urlMatcherFactory', function ($urlMatcherFactory) { }]);
+	// $urlRouter service and $urlRouterProvider
+	function getUrlRouterProvider() {
+	    router.urlRouterProvider["$get"] = function () {
+	        router.urlRouter.update(true);
+	        if (!this.interceptDeferred)
+	            router.urlRouter.listen();
+	        return router.urlRouter;
+	    };
+	    return router.urlRouterProvider;
+	}
+	angular.module('ui.router.router').provider('$urlRouter', ['ng1UIRouterProvider', getUrlRouterProvider]);
+	angular.module('ui.router.router').run(['$urlRouter', function ($urlRouter) { }]);
+	// $state service and $stateProvider
+	// $urlRouter service and $urlRouterProvider
+	function getStateProvider() {
+	    router.stateProvider["$get"] = function () {
+	        // Autoflush once we are in runtime
+	        router.stateRegistry.stateQueue.autoFlush(router.stateService);
+	        return router.stateService;
+	    };
+	    return router.stateProvider;
+	}
+	angular.module('ui.router.state').provider('$state', ['ng1UIRouterProvider', getStateProvider]);
+	angular.module('ui.router.state').run(['$state', function ($state) { }]);
+	// $stateParams service
+	angular.module('ui.router.state').factory('$stateParams', ['ng1UIRouter', function (ng1UIRouter) {
+	        return ng1UIRouter.globals.params;
+	    }]);
+	// $transitions service and $transitionsProvider
+	function getTransitionsProvider() {
+	    router.transitionService["$get"] = function () { return router.transitionService; };
+	    return router.transitionService;
+	}
+	angular.module('ui.router.state').provider('$transitions', ['ng1UIRouterProvider', getTransitionsProvider]);
+	// $templateFactory service
+	angular.module('ui.router.util').factory('$templateFactory', ['ng1UIRouter', function () { return new templateFactory_1.TemplateFactory(); }]);
+	// The $view service
+	angular.module('ui.router').factory('$view', function () { return router.viewService; });
+	// The old $resolve service
+	angular.module('ui.router').factory('$resolve', resolveService_1.resolveFactory);
+	// $trace service
+	angular.module("ui.router").service("$trace", function () { return trace_1.trace; });
+	watchDigests.$inject = ['$rootScope'];
+	function watchDigests($rootScope) {
+	    $rootScope.$watch(function () { trace_1.trace.approximateDigests++; });
+	}
+	exports.watchDigests = watchDigests;
+	angular.module("ui.router").run(watchDigests);
+	exports.getLocals = function (ctx) {
+	    var tokens = ctx.getTokens().filter(predicates_1.isString);
+	    var tuples = tokens.map(function (key) { return [key, ctx.getResolvable(key).data]; });
+	    return tuples.reduce(common_1.applyPairs, {});
+	};
+	/** Injectable services */
+	/**
+	 * An injectable service object which has the current state parameters
+	 *
+	 * This angular service (singleton object) holds the current state parameters.
+	 * The values in `$stateParams` are not updated until *after* a [[Transition]] successfully completes.
+	 *
+	 * This object can be injected into other services.
+	 *
+	 * @example
+	 * ```js
+	 *
+	 * SomeService.$inject = ['$http', '$stateParams'];
+	 * function SomeService($http, $stateParams) {
+	 *   return {
+	 *     getUser: function() {
+	 *       return $http.get('/api/users/' + $stateParams.username);
+	 *     }
+	 *   }
+	 * };
+	 * angular.service('SomeService', SomeService);
+	 * ```
+	 *
+	 * ### Deprecation warning:
+	 *
+	 * When `$stateParams` is injected into transition hooks, resolves and view controllers, they receive a different
+	 * object than this global service object.  In those cases, the injected object has the parameter values for the
+	 * *pending* Transition.
+	 *
+	 * Because of these confusing details, this service is deprecated.
+	 *
+	 * @deprecated Instead of using `$stateParams, inject the current [[Transition]] as `$transition$` and use [[Transition.params]]
+	 * ```js
+	 * MyController.$inject = ['$transition$'];
+	 * function MyController($transition$) {
+	 *   var username = $transition$.params().username;
+	 *   // .. do something with username
+	 * }
+	 * ```
+	 */
+	var $stateParams;
+	/**
+	 * An injectable service primarily used to register transition hooks
+	 *
+	 * This angular service exposes the [[TransitionService]] singleton, which is primarily used to add transition hooks.
+	 *
+	 * The same object is also exposed as [[$transitionsProvider]] for injection during angular config time.
+	 */
+	var $transitions;
+	/**
+	 * A config-time injectable provider primarily used to register transition hooks
+	 *
+	 * This angular provider exposes the [[TransitionService]] singleton, which is primarily used to add transition hooks.
+	 *
+	 * The same object is also exposed as [[$transitions]] for injection at runtime.
+	 */
+	var $transitionsProvider;
+	/**
+	 * An injectable service used to query for current state information.
+	 *
+	 * This angular service exposes the [[StateService]] singleton.
+	 */
+	var $state;
+	/**
+	 * A config-time injectable provider used to register states.
+	 *
+	 * This angular service exposes the [[StateProvider]] singleton.
+	 */
+	var $stateProvider;
+	/**
+	 * A config-time injectable provider used to manage the URL.
+	 *
+	 * This angular service exposes the [[UrlRouterProvider]] singleton.
+	 */
+	var $urlRouterProvider;
+	/**
+	 * An injectable service used to configure URL redirects.
+	 *
+	 * This angular service exposes the [[UrlRouter]] singleton.
+	 */
+	var $urlRouter;
+	/**
+	 * An injectable service used to configure the URL.
+	 *
+	 * This service is used to set url mapping options, and create [[UrlMatcher]] objects.
+	 *
+	 * This angular service exposes the [[UrlMatcherFactory]] singleton.
+	 * The singleton is also exposed at config-time as the [[$urlMatcherFactoryProvider]].
+	 */
+	var $urlMatcherFactory;
+	/**
+	 * An injectable service used to configure the URL.
+	 *
+	 * This service is used to set url mapping options, and create [[UrlMatcher]] objects.
+	 *
+	 * This angular service exposes the [[UrlMatcherFactory]] singleton at config-time.
+	 * The singleton is also exposed at runtime as the [[$urlMatcherFactory]].
+	 */
+	var $urlMatcherFactoryProvider;
+
+
+/***/ },
+/* 54 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module ng1 */ /** */
+	var stateObject_1 = __webpack_require__(42);
+	var node_1 = __webpack_require__(21);
+	var resolveContext_1 = __webpack_require__(17);
+	var common_1 = __webpack_require__(3);
+	var stateBuilder_1 = __webpack_require__(40);
+	/**
+	 * Implementation of the legacy `$resolve` service for angular 1.
+	 */
+	var $resolve = {
+	    /**
+	     * Asynchronously injects a resolve block.
+	     *
+	     * This emulates most of the behavior of the ui-router 0.2.x $resolve.resolve() service API.
+	     *
+	     * Given an object `invocables`, where keys are strings and values are injectable functions,
+	     * injects each function, and waits for the resulting promise to resolve.
+	     * When all resulting promises are resolved, returns the results as an object.
+	     *
+	     * @example
+	     * ```js
+	     *
+	     * let invocables = {
+	     *   foo: [ '$http', ($http) =>
+	     *            $http.get('/api/foo').then(resp => resp.data) ],
+	     *   bar: [ 'foo', '$http', (foo, $http) =>
+	     *            $http.get('/api/bar/' + foo.barId).then(resp => resp.data) ]
+	     * }
+	     * $resolve.resolve(invocables)
+	     *     .then(results => console.log(results.foo, results.bar))
+	     * // Logs foo and bar:
+	     * // { id: 123, barId: 456, fooData: 'foo data' }
+	     * // { id: 456, barData: 'bar data' }
+	     * ```
+	     *
+	     * @param invocables an object which looks like an [[StateDefinition.resolve]] object; keys are resolve names and values are injectable functions
+	     * @param locals key/value pre-resolved data (locals)
+	     * @param parent a promise for a "parent resolve"
+	     */
+	    resolve: function (invocables, locals, parent) {
+	        if (locals === void 0) { locals = {}; }
+	        var parentNode = new node_1.PathNode(new stateObject_1.State({ params: {}, resolvables: [] }));
+	        var node = new node_1.PathNode(new stateObject_1.State({ params: {}, resolvables: [] }));
+	        var context = new resolveContext_1.ResolveContext([parentNode, node]);
+	        context.addResolvables(stateBuilder_1.resolvablesBuilder({ resolve: invocables }), node.state);
+	        var resolveData = function (parentLocals) {
+	            var rewrap = function (_locals) { return stateBuilder_1.resolvablesBuilder({ resolve: common_1.map(_locals, function (local) { return function () { return local; }; }) }); };
+	            context.addResolvables(rewrap(parentLocals), parentNode.state);
+	            context.addResolvables(rewrap(locals), node.state);
+	            var tuples2ObjR = function (acc, tuple) {
+	                acc[tuple.token] = tuple.value;
+	                return acc;
+	            };
+	            return context.resolvePath().then(function (results) { return results.reduce(tuples2ObjR, {}); });
+	        };
+	        return parent ? parent.then(resolveData) : resolveData({});
+	    }
+	};
+	/** @hidden */
+	exports.resolveFactory = function () { return $resolve; };
+
+
+/***/ },
+/* 55 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	var common_1 = __webpack_require__(3);
+	var strings_1 = __webpack_require__(9);
+	var view_1 = __webpack_require__(37);
+	var predicates_1 = __webpack_require__(4);
+	var coreservices_1 = __webpack_require__(6);
+	var trace_1 = __webpack_require__(12);
+	var templateFactory_1 = __webpack_require__(56);
+	var resolveContext_1 = __webpack_require__(17);
+	var resolvable_1 = __webpack_require__(19);
+	exports.ng1ViewConfigFactory = function (path, view) { return new Ng1ViewConfig(path, view); };
+	/**
+	 * This is a [[StateBuilder.builder]] function for angular1 `views`.
+	 *
+	 * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder
+	 * handles the `views` property with logic specific to angular-ui-router (ng1).
+	 *
+	 * If no `views: {}` property exists on the [[StateDeclaration]], then it creates the `views` object
+	 * and applies the state-level configuration to a view named `$default`.
+	 */
+	function ng1ViewsBuilder(state) {
+	    var tplKeys = ['templateProvider', 'templateUrl', 'template', 'notify', 'async'], ctrlKeys = ['controller', 'controllerProvider', 'controllerAs', 'resolveAs'], compKeys = ['component', 'bindings'], nonCompKeys = tplKeys.concat(ctrlKeys), allKeys = compKeys.concat(nonCompKeys);
+	    var views = {}, viewsObject = state.views || { "$default": common_1.pick(state, allKeys) };
+	    common_1.forEach(viewsObject, function (config, name) {
+	        // Account for views: { "": { template... } }
+	        name = name || "$default";
+	        // Account for views: { header: "headerComponent" }
+	        if (predicates_1.isString(config))
+	            config = { component: config };
+	        if (!Object.keys(config).length)
+	            return;
+	        // Configure this view for routing to an angular 1.5+ style .component (or any directive, really)
+	        if (config.component) {
+	            if (nonCompKeys.map(function (key) { return predicates_1.isDefined(config[key]); }).reduce(common_1.anyTrueR, false)) {
+	                throw new Error("Cannot combine: " + compKeys.join("|") + " with: " + nonCompKeys.join("|") + " in stateview: 'name@" + state.name + "'");
+	            }
+	            // Dynamically build a template like "<component-name input1='::$resolve.foo'></component-name>"
+	            config.templateProvider = ['$injector', function ($injector) {
+	                    var resolveFor = function (key) { return config.bindings && config.bindings[key] || key; };
+	                    var prefix = angular.version.minor >= 3 ? "::" : "";
+	                    var attributeTpl = function (input) {
+	                        var attrName = strings_1.kebobString(input.name);
+	                        var resolveName = resolveFor(input.name);
+	                        if (input.type === '@')
+	                            return attrName + "='{{" + prefix + "$resolve." + resolveName + "}}'";
+	                        return attrName + "='" + prefix + "$resolve." + resolveName + "'";
+	                    };
+	                    var attrs = getComponentInputs($injector, config.component).map(attributeTpl).join(" ");
+	                    var kebobName = strings_1.kebobString(config.component);
+	                    return "<" + kebobName + " " + attrs + "></" + kebobName + ">";
+	                }];
+	        }
+	        config.resolveAs = config.resolveAs || '$resolve';
+	        config.$type = "ng1";
+	        config.$context = state;
+	        config.$name = name;
+	        var normalized = view_1.ViewService.normalizeUIViewTarget(config.$context, config.$name);
+	        config.$uiViewName = normalized.uiViewName;
+	        config.$uiViewContextAnchor = normalized.uiViewContextAnchor;
+	        views[name] = config;
+	    });
+	    return views;
+	}
+	exports.ng1ViewsBuilder = ng1ViewsBuilder;
+	// for ng 1.2 style, process the scope: { input: "=foo" }
+	// for ng 1.3 through ng 1.5, process the component's bindToController: { input: "=foo" } object
+	var scopeBindings = function (bindingsObj) { return Object.keys(bindingsObj || {})
+	    .map(function (key) { return [key, /^([=<@])[?]?(.*)/.exec(bindingsObj[key])]; }) // [ 'input', [ '=foo', '=', 'foo' ] ]
+	    .filter(function (tuple) { return predicates_1.isDefined(tuple) && predicates_1.isDefined(tuple[1]); }) // skip malformed values
+	    .map(function (tuple) { return ({ name: tuple[1][2] || tuple[0], type: tuple[1][1] }); }); }; // { name: ('foo' || 'input'), type: '=' }
+	// Given a directive definition, find its object input attributes
+	// Use different properties, depending on the type of directive (component, bindToController, normal)
+	var getBindings = function (def) {
+	    if (predicates_1.isObject(def.bindToController))
+	        return scopeBindings(def.bindToController);
+	    return scopeBindings(def.scope);
+	};
+	// Gets all the directive(s)' inputs ('@', '=', and '<')
+	function getComponentInputs($injector, name) {
+	    var cmpDefs = $injector.get(name + "Directive"); // could be multiple
+	    if (!cmpDefs || !cmpDefs.length)
+	        throw new Error("Unable to find component named '" + name + "'");
+	    return cmpDefs.map(getBindings).reduce(common_1.unnestR, []);
+	}
+	var id = 0;
+	var Ng1ViewConfig = (function () {
+	    function Ng1ViewConfig(path, viewDecl) {
+	        this.path = path;
+	        this.viewDecl = viewDecl;
+	        this.$id = id++;
+	        this.loaded = false;
+	    }
+	    Ng1ViewConfig.prototype.load = function () {
+	        var _this = this;
+	        var $q = coreservices_1.services.$q;
+	        if (!this.hasTemplate())
+	            throw new Error("No template configuration specified for '" + this.viewDecl.$uiViewName + "@" + this.viewDecl.$uiViewContextAnchor + "'");
+	        var context = new resolveContext_1.ResolveContext(this.path);
+	        var params = this.path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {});
+	        var promises = {
+	            template: $q.when(this.getTemplate(params, new templateFactory_1.TemplateFactory(), context)),
+	            controller: $q.when(this.getController(context))
+	        };
+	        return $q.all(promises).then(function (results) {
+	            trace_1.trace.traceViewServiceEvent("Loaded", _this);
+	            _this.controller = results.controller;
+	            _this.template = results.template;
+	        });
+	    };
+	    /**
+	     * Checks a view configuration to ensure that it specifies a template.
+	     *
+	     * @return {boolean} Returns `true` if the configuration contains a valid template, otherwise `false`.
+	     */
+	    Ng1ViewConfig.prototype.hasTemplate = function () {
+	        return !!(this.viewDecl.template || this.viewDecl.templateUrl || this.viewDecl.templateProvider);
+	    };
+	    Ng1ViewConfig.prototype.getTemplate = function (params, $factory, context) {
+	        return $factory.fromConfig(this.viewDecl, params, context);
+	    };
+	    /**
+	     * Gets the controller for a view configuration.
+	     *
+	     * @returns {Function|Promise.<Function>} Returns a controller, or a promise that resolves to a controller.
+	     */
+	    Ng1ViewConfig.prototype.getController = function (context) {
+	        var provider = this.viewDecl.controllerProvider;
+	        if (!predicates_1.isInjectable(provider))
+	            return this.viewDecl.controller;
+	        var deps = coreservices_1.services.$injector.annotate(provider);
+	        var providerFn = predicates_1.isArray(provider) ? common_1.tail(provider) : provider;
+	        var resolvable = new resolvable_1.Resolvable("", providerFn, deps);
+	        return resolvable.get(context);
+	    };
+	    return Ng1ViewConfig;
+	}());
+	exports.Ng1ViewConfig = Ng1ViewConfig;
+
+
+/***/ },
+/* 56 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/** @module view */ /** for typedoc */
+	var predicates_1 = __webpack_require__(4);
+	var coreservices_1 = __webpack_require__(6);
+	var common_1 = __webpack_require__(3);
+	var resolvable_1 = __webpack_require__(19);
+	/**
+	 * Service which manages loading of templates from a ViewConfig.
+	 */
+	var TemplateFactory = (function () {
+	    function TemplateFactory() {
+	    }
+	    /**
+	     * Creates a template from a configuration object.
+	     *
+	     * @param config Configuration object for which to load a template.
+	     * The following properties are search in the specified order, and the first one
+	     * that is defined is used to create the template:
+	     *
+	     * @param params  Parameters to pass to the template function.
+	     * @param context The resolve context associated with the template's view
+	     *
+	     * @return {string|object}  The template html as a string, or a promise for
+	     * that string,or `null` if no template is configured.
+	     */
+	    TemplateFactory.prototype.fromConfig = function (config, params, context) {
+	        return (predicates_1.isDefined(config.template) ? this.fromString(config.template, params) :
+	            predicates_1.isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :
+	                predicates_1.isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, context) :
+	                    null);
+	    };
+	    ;
+	    /**
+	     * Creates a template from a string or a function returning a string.
+	     *
+	     * @param template html template as a string or function that returns an html template as a string.
+	     * @param params Parameters to pass to the template function.
+	     *
+	     * @return {string|object} The template html as a string, or a promise for that
+	     * string.
+	     */
+	    TemplateFactory.prototype.fromString = function (template, params) {
+	        return predicates_1.isFunction(template) ? template(params) : template;
+	    };
+	    ;
+	    /**
+	     * Loads a template from the a URL via `$http` and `$templateCache`.
+	     *
+	     * @param {string|Function} url url of the template to load, or a function
+	     * that returns a url.
+	     * @param {Object} params Parameters to pass to the url function.
+	     * @return {string|Promise.<string>} The template html as a string, or a promise
+	     * for that string.
+	     */
+	    TemplateFactory.prototype.fromUrl = function (url, params) {
+	        if (predicates_1.isFunction(url))
+	            url = url(params);
+	        if (url == null)
+	            return null;
+	        return coreservices_1.services.template.get(url);
+	    };
+	    ;
+	    /**
+	     * Creates a template by invoking an injectable provider function.
+	     *
+	     * @param provider Function to invoke via `locals`
+	     * @param {Function} injectFn a function used to invoke the template provider
+	     * @return {string|Promise.<string>} The template html as a string, or a promise
+	     * for that string.
+	     */
+	    TemplateFactory.prototype.fromProvider = function (provider, params, context) {
+	        var deps = coreservices_1.services.$injector.annotate(provider);
+	        var providerFn = predicates_1.isArray(provider) ? common_1.tail(provider) : provider;
+	        var resolvable = new resolvable_1.Resolvable("", providerFn, deps);
+	        return resolvable.get(context);
+	    };
+	    ;
+	    return TemplateFactory;
+	}());
+	exports.TemplateFactory = TemplateFactory;
+
+
+/***/ },
+/* 57 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	var coreservices_1 = __webpack_require__(6);
+	var services_1 = __webpack_require__(53);
+	var resolveContext_1 = __webpack_require__(17);
+	var common_1 = __webpack_require__(3);
+	/**
+	 * This is a [[StateBuilder.builder]] function for angular1 `onEnter`, `onExit`,
+	 * `onRetain` callback hooks on a [[Ng1StateDeclaration]].
+	 *
+	 * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder
+	 * ensures that those hooks are injectable for angular-ui-router (ng1).
+	 */
+	exports.getStateHookBuilder = function (hookName) {
+	    return function stateHookBuilder(state, parentFn) {
+	        var hook = state[hookName];
+	        function decoratedNg1Hook(trans, state) {
+	            var resolveContext = new resolveContext_1.ResolveContext(trans.treeChanges().to);
+	            return coreservices_1.services.$injector.invoke(hook, this, common_1.extend({ $state$: state }, services_1.getLocals(resolveContext)));
+	        }
+	        return hook ? decoratedNg1Hook : undefined;
+	    };
+	};
+
+
+/***/ },
+/* 58 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	/**
+	 * These are the UI-Router angular 1 directives.
+	 *
+	 * These directives are used in templates to create viewports and navigate to states
+	 *
+	 * @preferred @module ng1_directives
+	 */ /** for typedoc */
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var hof_1 = __webpack_require__(5);
+	/** @hidden */
+	function parseStateRef(ref, current) {
+	    var preparsed = ref.match(/^\s*({[^}]*})\s*$/), parsed;
+	    if (preparsed)
+	        ref = current + '(' + preparsed[1] + ')';
+	    parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/);
+	    if (!parsed || parsed.length !== 4)
+	        throw new Error("Invalid state ref '" + ref + "'");
+	    return { state: parsed[1], paramExpr: parsed[3] || null };
+	}
+	/** @hidden */
+	function stateContext(el) {
+	    var $uiView = el.parent().inheritedData('$uiView');
+	    var path = hof_1.parse('$cfg.path')($uiView);
+	    return path ? common_1.tail(path).state.name : undefined;
+	}
+	/** @hidden */
+	function getTypeInfo(el) {
+	    // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
+	    var isSvg = Object.prototype.toString.call(el.prop('href')) === '[object SVGAnimatedString]';
+	    var isForm = el[0].nodeName === "FORM";
+	    return {
+	        attr: isForm ? "action" : (isSvg ? 'xlink:href' : 'href'),
+	        isAnchor: el.prop("tagName").toUpperCase() === "A",
+	        clickable: !isForm
+	    };
+	}
+	/** @hidden */
+	function clickHook(el, $state, $timeout, type, current) {
+	    return function (e) {
+	        var button = e.which || e.button, target = current();
+	        if (!(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || el.attr('target'))) {
+	            // HACK: This is to allow ng-clicks to be processed before the transition is initiated:
+	            var transition = $timeout(function () {
+	                $state.go(target.state, target.params, target.options);
+	            });
+	            e.preventDefault();
+	            // if the state has no URL, ignore one preventDefault from the <a> directive.
+	            var ignorePreventDefaultCount = type.isAnchor && !target.href ? 1 : 0;
+	            e.preventDefault = function () {
+	                if (ignorePreventDefaultCount-- <= 0)
+	                    $timeout.cancel(transition);
+	            };
+	        }
+	    };
+	}
+	/** @hidden */
+	function defaultOpts(el, $state) {
+	    return { relative: stateContext(el) || $state.$current, inherit: true };
+	}
+	/**
+	 * `ui-sref`: A directive for linking to a state
+	 *
+	 * A directive that binds a link (`<a>` tag) to a state.
+	 * If the state has an associated URL, the directive will automatically generate and
+	 * update the `href` attribute via the [[StateService.href]]  method.
+	 * Clicking the link will trigger a state transition with optional parameters.
+	 *
+	 * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be
+	 * handled natively by the browser.
+	 *
+	 * You can also use relative state paths within ui-sref, just like the relative
+	 * paths passed to `$state.go()`.
+	 * You just need to be aware that the path is relative to the state that the link lives in.
+	 * In other words, the state that created the view containing the link.
+	 *
+	 * You can specify options to pass to [[StateService.go]] using the `ui-sref-opts` attribute.
+	 * Options are restricted to `location`, `inherit`, and `reload`.
+	 *
+	 * Here's an example of how you'd use ui-sref and how it would compile.
+	 * If you have the following template:
+	 *
+	 * @example
+	 * ```html
+	 *
+	 * <pre>
+	 * <a ui-sref="home">Home</a> | <a ui-sref="about">About</a> | <a ui-sref="{page: 2}">Next page</a>
+	 *
+	 * <ul>
+	 *     <li ng-repeat="contact in contacts">
+	 *         <a ui-sref="contacts.detail({ id: contact.id })">{{ contact.name }}</a>
+	 *     </li>
+	 * </ul>
+	 * </pre>
+	 * ```
+	 *
+	 * Then the compiled html would be (assuming Html5Mode is off and current state is contacts):
+	 *
+	 * ```html
+	 *
+	 * <pre>
+	 * <a href="#/home" ui-sref="home">Home</a> | <a href="#/about" ui-sref="about">About</a> | <a href="#/contacts?page=2" ui-sref="{page: 2}">Next page</a>
+	 *
+	 * <ul>
+	 *     <li ng-repeat="contact in contacts">
+	 *         <a href="#/contacts/1" ui-sref="contacts.detail({ id: contact.id })">Joe</a>
+	 *     </li>
+	 *     <li ng-repeat="contact in contacts">
+	 *         <a href="#/contacts/2" ui-sref="contacts.detail({ id: contact.id })">Alice</a>
+	 *     </li>
+	 *     <li ng-repeat="contact in contacts">
+	 *         <a href="#/contacts/3" ui-sref="contacts.detail({ id: contact.id })">Bob</a>
+	 *     </li>
+	 * </ul>
+	 *
+	 * <a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>
+	 * </pre>
+	 * ```
+	 *
+	 * @param {string} ui-sref 'stateName' can be any valid absolute or relative state
+	 * @param {Object} ui-sref-opts options to pass to [[StateService.go]]
+	 */
+	var uiSref = ['$state', '$timeout',
+	    function $StateRefDirective($state, $timeout) {
+	        return {
+	            restrict: 'A',
+	            require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
+	            link: function (scope, element, attrs, uiSrefActive) {
+	                var ref = parseStateRef(attrs.uiSref, $state.current.name);
+	                var def = { state: ref.state, href: null, params: null, options: null };
+	                var type = getTypeInfo(element);
+	                var active = uiSrefActive[1] || uiSrefActive[0];
+	                var unlinkInfoFn = null;
+	                def.options = common_1.extend(defaultOpts(element, $state), attrs.uiSrefOpts ? scope.$eval(attrs.uiSrefOpts) : {});
+	                var update = function (val) {
+	                    if (val)
+	                        def.params = angular.copy(val);
+	                    def.href = $state.href(ref.state, def.params, def.options);
+	                    if (unlinkInfoFn)
+	                        unlinkInfoFn();
+	                    if (active)
+	                        unlinkInfoFn = active.$$addStateInfo(ref.state, def.params);
+	                    if (def.href !== null)
+	                        attrs.$set(type.attr, def.href);
+	                };
+	                if (ref.paramExpr) {
+	                    scope.$watch(ref.paramExpr, function (val) { if (val !== def.params)
+	                        update(val); }, true);
+	                    def.params = angular.copy(scope.$eval(ref.paramExpr));
+	                }
+	                update();
+	                if (!type.clickable)
+	                    return;
+	                element.bind("click", clickHook(element, $state, $timeout, type, function () { return def; }));
+	            }
+	        };
+	    }];
+	/**
+	 * `ui-state`: A dynamic version of `ui-sref`
+	 *
+	 * Much like ui-sref, but will accept named $scope properties to evaluate for a state definition,
+	 * params and override options.
+	 *
+	 * @example
+	 * ```html
+	 *
+	 * <li ng-repeat="nav in navlinks">
+	 *   <a ui-state="nav.statename">{{nav.description}}</a>
+	 * </li>
+	 *
+	 * @param {string} ui-state 'stateName' can be any valid absolute or relative state
+	 * @param {Object} ui-state-params params to pass to [[StateService.href]]
+	 * @param {Object} ui-state-opts options to pass to [[StateService.go]]
+	 */
+	var uiState = ['$state', '$timeout',
+	    function $StateRefDynamicDirective($state, $timeout) {
+	        return {
+	            restrict: 'A',
+	            require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
+	            link: function (scope, element, attrs, uiSrefActive) {
+	                var type = getTypeInfo(element);
+	                var active = uiSrefActive[1] || uiSrefActive[0];
+	                var group = [attrs.uiState, attrs.uiStateParams || null, attrs.uiStateOpts || null];
+	                var watch = '[' + group.map(function (val) { return val || 'null'; }).join(', ') + ']';
+	                var def = { state: null, params: null, options: null, href: null };
+	                var unlinkInfoFn = null;
+	                function runStateRefLink(group) {
+	                    def.state = group[0];
+	                    def.params = group[1];
+	                    def.options = group[2];
+	                    def.href = $state.href(def.state, def.params, def.options);
+	                    if (unlinkInfoFn)
+	                        unlinkInfoFn();
+	                    if (active)
+	                        unlinkInfoFn = active.$$addStateInfo(def.state, def.params);
+	                    if (def.href)
+	                        attrs.$set(type.attr, def.href);
+	                }
+	                scope.$watch(watch, runStateRefLink, true);
+	                runStateRefLink(scope.$eval(watch));
+	                if (!type.clickable)
+	                    return;
+	                element.bind("click", clickHook(element, $state, $timeout, type, function () { return def; }));
+	            }
+	        };
+	    }];
+	/**
+	 * `ui-sref-active` and `ui-sref-active-eq`: A directive that adds a CSS class when a `ui-sref` is active
+	 *
+	 * A directive working alongside ui-sref to add classes to an element when the
+	 * related ui-sref directive's state is active, and removing them when it is inactive.
+	 * The primary use-case is to simplify the special appearance of navigation menus
+	 * relying on `ui-sref`, by having the "active" state's menu button appear different,
+	 * distinguishing it from the inactive menu items.
+	 *
+	 * ui-sref-active can live on the same element as ui-sref or on a parent element. The first
+	 * ui-sref-active found at the same level or above the ui-sref will be used.
+	 *
+	 * Will activate when the ui-sref's target state or any child state is active. If you
+	 * need to activate only when the ui-sref target state is active and *not* any of
+	 * it's children, then you will use ui-sref-active-eq
+	 *
+	 * Given the following template:
+	 * @example
+	 * ```html
+	 *
+	 * <pre>
+	 * <ul>
+	 *   <li ui-sref-active="active" class="item">
+	 *     <a href ui-sref="app.user({user: 'bilbobaggins'})">@bilbobaggins</a>
+	 *   </li>
+	 * </ul>
+	 * </pre>
+	 * ```
+	 *
+	 *
+	 * When the app state is "app.user" (or any children states), and contains the state parameter "user" with value "bilbobaggins",
+	 * the resulting HTML will appear as (note the 'active' class):
+	 *
+	 * ```html
+	 *
+	 * <pre>
+	 * <ul>
+	 *   <li ui-sref-active="active" class="item active">
+	 *     <a ui-sref="app.user({user: 'bilbobaggins'})" href="/users/bilbobaggins">@bilbobaggins</a>
+	 *   </li>
+	 * </ul>
+	 * </pre>
+	 * ```
+	 *
+	 * The class name is interpolated **once** during the directives link time (any further changes to the
+	 * interpolated value are ignored).
+	 *
+	 * Multiple classes may be specified in a space-separated format:
+	 *
+	 * ```html
+	 * <pre>
+	 * <ul>
+	 *   <li ui-sref-active='class1 class2 class3'>
+	 *     <a ui-sref="app.user">link</a>
+	 *   </li>
+	 * </ul>
+	 * </pre>
+	 * ```
+	 *
+	 * It is also possible to pass ui-sref-active an expression that evaluates
+	 * to an object hash, whose keys represent active class names and whose
+	 * values represent the respective state names/globs.
+	 * ui-sref-active will match if the current active state **includes** any of
+	 * the specified state names/globs, even the abstract ones.
+	 *
+	 * Given the following template, with "admin" being an abstract state:
+	 * @example
+	 * ```html
+	 *
+	 * <pre>
+	 * <div ui-sref-active="{'active': 'admin.*'}">
+	 *   <a ui-sref-active="active" ui-sref="admin.roles">Roles</a>
+	 * </div>
+	 * </pre>
+	 * ```
+	 *
+	 * When the current state is "admin.roles" the "active" class will be applied
+	 * to both the <div> and <a> elements. It is important to note that the state
+	 * names/globs passed to ui-sref-active shadow the state provided by ui-sref.
+	 */
+	var uiSrefActive = ['$state', '$stateParams', '$interpolate', '$transitions',
+	    function $StateRefActiveDirective($state, $stateParams, $interpolate, $transitions) {
+	        return {
+	            restrict: "A",
+	            controller: ['$scope', '$element', '$attrs', '$timeout', function ($scope, $element, $attrs, $timeout) {
+	                    var states = [], activeClasses = {}, activeEqClass, uiSrefActive;
+	                    // There probably isn't much point in $observing this
+	                    // uiSrefActive and uiSrefActiveEq share the same directive object with some
+	                    // slight difference in logic routing
+	                    activeEqClass = $interpolate($attrs.uiSrefActiveEq || '', false)($scope);
+	                    try {
+	                        uiSrefActive = $scope.$eval($attrs.uiSrefActive);
+	                    }
+	                    catch (e) {
+	                    }
+	                    uiSrefActive = uiSrefActive || $interpolate($attrs.uiSrefActive || '', false)($scope);
+	                    if (predicates_1.isObject(uiSrefActive)) {
+	                        common_1.forEach(uiSrefActive, function (stateOrName, activeClass) {
+	                            if (predicates_1.isString(stateOrName)) {
+	                                var ref = parseStateRef(stateOrName, $state.current.name);
+	                                addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);
+	                            }
+	                        });
+	                    }
+	                    // Allow uiSref to communicate with uiSrefActive[Equals]
+	                    this.$$addStateInfo = function (newState, newParams) {
+	                        // we already got an explicit state provided by ui-sref-active, so we
+	                        // shadow the one that comes from ui-sref
+	                        if (predicates_1.isObject(uiSrefActive) && states.length > 0) {
+	                            return;
+	                        }
+	                        var deregister = addState(newState, newParams, uiSrefActive);
+	                        update();
+	                        return deregister;
+	                    };
+	                    $scope.$on('$stateChangeSuccess', update);
+	                    $scope.$on('$destroy', $transitions.onStart({}, function (trans) { return trans.promise.then(update) && null; }));
+	                    function addState(stateName, stateParams, activeClass) {
+	                        var state = $state.get(stateName, stateContext($element));
+	                        var stateHash = createStateHash(stateName, stateParams);
+	                        var stateInfo = {
+	                            state: state || { name: stateName },
+	                            params: stateParams,
+	                            hash: stateHash
+	                        };
+	                        states.push(stateInfo);
+	                        activeClasses[stateHash] = activeClass;
+	                        return function removeState() {
+	                            var idx = states.indexOf(stateInfo);
+	                            if (idx !== -1)
+	                                states.splice(idx, 1);
+	                        };
+	                    }
+	                    /**
+	                     * @param {string} state
+	                     * @param {Object|string} [params]
+	                     * @return {string}
+	                     */
+	                    function createStateHash(state, params) {
+	                        if (!predicates_1.isString(state)) {
+	                            throw new Error('state should be a string');
+	                        }
+	                        if (predicates_1.isObject(params)) {
+	                            return state + common_1.toJson(params);
+	                        }
+	                        params = $scope.$eval(params);
+	                        if (predicates_1.isObject(params)) {
+	                            return state + common_1.toJson(params);
+	                        }
+	                        return state;
+	                    }
+	                    // Update route state
+	                    function update() {
+	                        for (var i = 0; i < states.length; i++) {
+	                            if (anyMatch(states[i].state, states[i].params)) {
+	                                addClass($element, activeClasses[states[i].hash]);
+	                            }
+	                            else {
+	                                removeClass($element, activeClasses[states[i].hash]);
+	                            }
+	                            if (exactMatch(states[i].state, states[i].params)) {
+	                                addClass($element, activeEqClass);
+	                            }
+	                            else {
+	                                removeClass($element, activeEqClass);
+	                            }
+	                        }
+	                    }
+	                    function addClass(el, className) { $timeout(function () { el.addClass(className); }); }
+	                    function removeClass(el, className) { el.removeClass(className); }
+	                    function anyMatch(state, params) { return $state.includes(state.name, params); }
+	                    function exactMatch(state, params) { return $state.is(state.name, params); }
+	                    update();
+	                }]
+	        };
+	    }];
+	angular.module('ui.router.state')
+	    .directive('uiSref', uiSref)
+	    .directive('uiSrefActive', uiSrefActive)
+	    .directive('uiSrefActiveEq', uiSrefActive)
+	    .directive('uiState', uiState);
+
+
+/***/ },
+/* 59 */
+/***/ function(module, exports) {
+
+	/** @module state */ /** for typedoc */
+	"use strict";
+	/**
+	 * @ngdoc filter
+	 * @name ui.router.state.filter:isState
+	 *
+	 * @requires ui.router.state.$state
+	 *
+	 * @description
+	 * Translates to {@link ui.router.state.$state#methods_is $state.is("stateName")}.
+	 */
+	$IsStateFilter.$inject = ['$state'];
+	function $IsStateFilter($state) {
+	    var isFilter = function (state, params, options) {
+	        return $state.is(state, params, options);
+	    };
+	    isFilter.$stateful = true;
+	    return isFilter;
+	}
+	exports.$IsStateFilter = $IsStateFilter;
+	/**
+	 * @ngdoc filter
+	 * @name ui.router.state.filter:includedByState
+	 *
+	 * @requires ui.router.state.$state
+	 *
+	 * @description
+	 * Translates to {@link ui.router.state.$state#methods_includes $state.includes('fullOrPartialStateName')}.
+	 */
+	$IncludedByStateFilter.$inject = ['$state'];
+	function $IncludedByStateFilter($state) {
+	    var includesFilter = function (state, params, options) {
+	        return $state.includes(state, params, options);
+	    };
+	    includesFilter.$stateful = true;
+	    return includesFilter;
+	}
+	exports.$IncludedByStateFilter = $IncludedByStateFilter;
+	angular.module('ui.router.state')
+	    .filter('isState', $IsStateFilter)
+	    .filter('includedByState', $IncludedByStateFilter);
+
+
+/***/ },
+/* 60 */
+/***/ function(module, exports, __webpack_require__) {
+
+	/** @module ng1_directives */ /** for typedoc */
+	"use strict";
+	var common_1 = __webpack_require__(3);
+	var predicates_1 = __webpack_require__(4);
+	var trace_1 = __webpack_require__(12);
+	var views_1 = __webpack_require__(55);
+	var hof_1 = __webpack_require__(5);
+	var resolveContext_1 = __webpack_require__(17);
+	var strings_1 = __webpack_require__(9);
+	var services_1 = __webpack_require__(53);
+	/**
+	 * `ui-view`: A viewport directive which is filled in by a view from the active state.
+	 *
+	 * @param {string=} name A view name. The name should be unique amongst the other views in the
+	 * same state. You can have views of the same name that live in different states.
+	 *
+	 * @param {string=} autoscroll It allows you to set the scroll behavior of the browser window
+	 * when a view is populated. By default, $anchorScroll is overridden by ui-router's custom scroll
+	 * service, {@link ui.router.state.$uiViewScroll}. This custom service let's you
+	 * scroll ui-view elements into view when they are populated during a state activation.
+	 *
+	 * *Note: To revert back to old [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll)
+	 * functionality, call `$uiViewScrollProvider.useAnchorScroll()`.*
+	 *
+	 * @param {string=} onload Expression to evaluate whenever the view updates.
+	 *
+	 * A view can be unnamed or named.
+	 * @example
+	 * ```html
+	 *
+	 * <!-- Unnamed -->
+	 * <div ui-view></div>
+	 *
+	 * <!-- Named -->
+	 * <div ui-view="viewName"></div>
+	 * ```
+	 *
+	 * You can only have one unnamed view within any template (or root html). If you are only using a
+	 * single view and it is unnamed then you can populate it like so:
+	 * ```
+	 *
+	 * <div ui-view></div>
+	 * $stateProvider.state("home", {
+	 *   template: "<h1>HELLO!</h1>"
+	 * })
+	 * ```
+	 *
+	 * The above is a convenient shortcut equivalent to specifying your view explicitly with the {@link ui.router.state.$stateProvider#views `views`}
+	 * config property, by name, in this case an empty name:
+	 * ```js
+	 *
+	 * $stateProvider.state("home", {
+	 *   views: {
+	 *     "": {
+	 *       template: "<h1>HELLO!</h1>"
+	 *     }
+	 *   }
+	 * })
+	 * ```
+	 *
+	 * But typically you'll only use the views property if you name your view or have more than one view
+	 * in the same template. There's not really a compelling reason to name a view if its the only one,
+	 * but you could if you wanted, like so:
+	 *
+	 * ```html
+	 *
+	 * <div ui-view="main"></div>
+	 * ```
+	 *
+	 * ```js
+	 *
+	 * $stateProvider.state("home", {
+	 *   views: {
+	 *     "main": {
+	 *       template: "<h1>HELLO!</h1>"
+	 *     }
+	 *   }
+	 * })
+	 * ```
+	 *
+	 * Really though, you'll use views to set up multiple views:
+	 * ```html
+	 *
+	 * <div ui-view></div>
+	 * <div ui-view="chart"></div>
+	 * <div ui-view="data"></div>
+	 * ```
+	 *
+	 * ```js
+	 * $stateProvider.state("home", {
+	 *   views: {
+	 *     "": {
+	 *       template: "<h1>HELLO!</h1>"
+	 *     },
+	 *     "chart": {
+	 *       template: "<chart_thing/>"
+	 *     },
+	 *     "data": {
+	 *       template: "<data_thing/>"
+	 *     }
+	 *   }
+	 * })
+	 * ```
+	 *
+	 * Examples for `autoscroll`:
+	 *
+	 * ```html
+	 *
+	 * <!-- If autoscroll present with no expression,
+	 *      then scroll ui-view into view -->
+	 * <ui-view autoscroll/>
+	 *
+	 * <!-- If autoscroll present with valid expression,
+	 *      then scroll ui-view into view if expression evaluates to true -->
+	 * <ui-view autoscroll='true'/>
+	 * <ui-view autoscroll='false'/>
+	 * <ui-view autoscroll='scopeVariable'/>
+	 * ```
+	 *
+	 * Resolve data:
+	 *
+	 * The resolved data from the state's `resolve` block is placed on the scope as `$resolve` (this
+	 * can be customized using [[ViewDeclaration.resolveAs]]).  This can be then accessed from the template.
+	 *
+	 * Note that when `controllerAs` is being used, `$resolve` is set on the controller instance *after* the
+	 * controller is instantiated.  The `$onInit()` hook can be used to perform initialization code which
+	 * depends on `$resolve` data.
+	 *
+	 * @example
+	 * ```js
+	 *
+	 * $stateProvider.state('home', {
+	 *   template: '<my-component user="$resolve.user"></my-component>',
+	 *   resolve: {
+	 *     user: function(UserService) { return UserService.fetchUser(); }
+	 *   }
+	 * });
+	 * ```
+	 */
+	var uiView = ['$view', '$animate', '$uiViewScroll', '$interpolate', '$q',
+	    function $ViewDirective($view, $animate, $uiViewScroll, $interpolate, $q) {
+	        function getRenderer(attrs, scope) {
+	            return {
+	                enter: function (element, target, cb) {
+	                    if (angular.version.minor > 2) {
+	                        $animate.enter(element, null, target).then(cb);
+	                    }
+	                    else {
+	                        $animate.enter(element, null, target, cb);
+	                    }
+	                },
+	                leave: function (element, cb) {
+	                    if (angular.version.minor > 2) {
+	                        $animate.leave(element).then(cb);
+	                    }
+	                    else {
+	                        $animate.leave(element, cb);
+	                    }
+	                }
+	            };
+	        }
+	        function configsEqual(config1, config2) {
+	            return config1 === config2;
+	        }
+	        var rootData = {
+	            $cfg: { viewDecl: { $context: $view.rootContext() } },
+	            $uiView: {}
+	        };
+	        var directive = {
+	            count: 0,
+	            restrict: 'ECA',
+	            terminal: true,
+	            priority: 400,
+	            transclude: 'element',
+	            compile: function (tElement, tAttrs, $transclude) {
+	                return function (scope, $element, attrs) {
+	                    var previousEl, currentEl, currentScope, unregister, onloadExp = attrs.onload || '', autoScrollExp = attrs.autoscroll, renderer = getRenderer(attrs, scope), viewConfig = undefined, inherited = $element.inheritedData('$uiView') || rootData, name = $interpolate(attrs.uiView || attrs.name || '')(scope) || '$default';
+	                    var activeUIView = {
+	                        $type: 'ng1',
+	                        id: directive.count++,
+	                        name: name,
+	                        fqn: inherited.$uiView.fqn ? inherited.$uiView.fqn + "." + name : name,
+	                        config: null,
+	                        configUpdated: configUpdatedCallback,
+	                        get creationContext() {
+	                            return hof_1.parse('$cfg.viewDecl.$context')(inherited);
+	                        }
+	                    };
+	                    trace_1.trace.traceUIViewEvent("Linking", activeUIView);
+	                    function configUpdatedCallback(config) {
+	                        if (config && !(config instanceof views_1.Ng1ViewConfig))
+	                            return;
+	                        if (configsEqual(viewConfig, config))
+	                            return;
+	                        trace_1.trace.traceUIViewConfigUpdated(activeUIView, config && config.viewDecl && config.viewDecl.$context);
+	                        viewConfig = config;
+	                        updateView(config);
+	                    }
+	                    $element.data('$uiView', { $uiView: activeUIView });
+	                    updateView();
+	                    unregister = $view.registerUIView(activeUIView);
+	                    scope.$on("$destroy", function () {
+	                        trace_1.trace.traceUIViewEvent("Destroying/Unregistering", activeUIView);
+	                        unregister();
+	                    });
+	                    function cleanupLastView() {
+	                        if (previousEl) {
+	                            trace_1.trace.traceUIViewEvent("Removing (previous) el", previousEl.data('$uiView'));
+	                            previousEl.remove();
+	                            previousEl = null;
+	                        }
+	                        if (currentScope) {
+	                            trace_1.trace.traceUIViewEvent("Destroying scope", activeUIView);
+	                            currentScope.$destroy();
+	                            currentScope = null;
+	                        }
+	                        if (currentEl) {
+	                            var _viewData_1 = currentEl.data('$uiView');
+	                            trace_1.trace.traceUIViewEvent("Animate out", _viewData_1);
+	                            renderer.leave(currentEl, function () {
+	                                _viewData_1.$$animLeave.resolve();
+	                                previousEl = null;
+	                            });
+	                            previousEl = currentEl;
+	                            currentEl = null;
+	                        }
+	                    }
+	                    function updateView(config) {
+	                        var newScope = scope.$new();
+	                        trace_1.trace.traceUIViewScopeCreated(activeUIView, newScope);
+	                        var animEnter = $q.defer(), animLeave = $q.defer();
+	                        var $uiViewData = {
+	                            $cfg: config,
+	                            $uiView: activeUIView,
+	                            $animEnter: animEnter.promise,
+	                            $animLeave: animLeave.promise,
+	                            $$animLeave: animLeave
+	                        };
+	                        var cloned = $transclude(newScope, function (clone) {
+	                            renderer.enter(clone.data('$uiView', $uiViewData), $element, function onUIViewEnter() {
+	                                animEnter.resolve();
+	                                if (currentScope)
+	                                    currentScope.$emit('$viewContentAnimationEnded');
+	                                if (predicates_1.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) {
+	                                    $uiViewScroll(clone);
+	                                }
+	                            });
+	                            cleanupLastView();
+	                        });
+	                        currentEl = cloned;
+	                        currentScope = newScope;
+	                        /**
+	                         * @ngdoc event
+	                         * @name ui.router.state.directive:ui-view#$viewContentLoaded
+	                         * @eventOf ui.router.state.directive:ui-view
+	                         * @eventType emits on ui-view directive scope
+	                         * @description           *
+	                         * Fired once the view is **loaded**, *after* the DOM is rendered.
+	                         *
+	                         * @param {Object} event Event object.
+	                         */
+	                        currentScope.$emit('$viewContentLoaded', config || viewConfig);
+	                        currentScope.$eval(onloadExp);
+	                    }
+	                };
+	            }
+	        };
+	        return directive;
+	    }];
+	$ViewDirectiveFill.$inject = ['$compile', '$controller', '$transitions', '$view', '$timeout'];
+	/** @hidden */
+	function $ViewDirectiveFill($compile, $controller, $transitions, $view, $timeout) {
+	    var getControllerAs = hof_1.parse('viewDecl.controllerAs');
+	    var getResolveAs = hof_1.parse('viewDecl.resolveAs');
+	    return {
+	        restrict: 'ECA',
+	        priority: -400,
+	        compile: function (tElement) {
+	            var initial = tElement.html();
+	            return function (scope, $element) {
+	                var data = $element.data('$uiView');
+	                if (!data)
+	                    return;
+	                var cfg = data.$cfg || { viewDecl: {} };
+	                $element.html(cfg.template || initial);
+	                trace_1.trace.traceUIViewFill(data.$uiView, $element.html());
+	                var link = $compile($element.contents());
+	                var controller = cfg.controller;
+	                var controllerAs = getControllerAs(cfg);
+	                var resolveAs = getResolveAs(cfg);
+	                var resolveCtx = cfg.path && new resolveContext_1.ResolveContext(cfg.path);
+	                var locals = resolveCtx && services_1.getLocals(resolveCtx);
+	                scope[resolveAs] = locals;
+	                if (controller) {
+	                    var controllerInstance = $controller(controller, common_1.extend({}, locals, { $scope: scope, $element: $element }));
+	                    if (controllerAs) {
+	                        scope[controllerAs] = controllerInstance;
+	                        scope[controllerAs][resolveAs] = locals;
+	                    }
+	                    // TODO: Use $view service as a central point for registering component-level hooks
+	                    // Then, when a component is created, tell the $view service, so it can invoke hooks
+	                    // $view.componentLoaded(controllerInstance, { $scope: scope, $element: $element });
+	                    // scope.$on('$destroy', () => $view.componentUnloaded(controllerInstance, { $scope: scope, $element: $element }));
+	                    $element.data('$ngControllerController', controllerInstance);
+	                    $element.children().data('$ngControllerController', controllerInstance);
+	                    registerControllerCallbacks($transitions, controllerInstance, scope, cfg);
+	                }
+	                // Wait for the component to appear in the DOM
+	                if (predicates_1.isString(cfg.viewDecl.component)) {
+	                    var cmp_1 = cfg.viewDecl.component;
+	                    var kebobName_1 = strings_1.kebobString(cmp_1);
+	                    var getComponentController = function () {
+	                        var directiveEl = [].slice.call($element[0].children)
+	                            .filter(function (el) { return el && el.tagName && el.tagName.toLowerCase() === kebobName_1; });
+	                        return directiveEl && angular.element(directiveEl).data("$" + cmp_1 + "Controller");
+	                    };
+	                    var deregisterWatch_1 = scope.$watch(getComponentController, function (ctrlInstance) {
+	                        if (!ctrlInstance)
+	                            return;
+	                        registerControllerCallbacks($transitions, ctrlInstance, scope, cfg);
+	                        deregisterWatch_1();
+	                    });
+	                }
+	                link(scope);
+	            };
+	        }
+	    };
+	}
+	/** @hidden */
+	var hasComponentImpl = typeof angular.module('ui.router')['component'] === 'function';
+	/** @hidden TODO: move these callbacks to $view and/or `/hooks/components.ts` or something */
+	function registerControllerCallbacks($transitions, controllerInstance, $scope, cfg) {
+	    // Call $onInit() ASAP
+	    if (predicates_1.isFunction(controllerInstance.$onInit) && !(cfg.viewDecl.component && hasComponentImpl))
+	        controllerInstance.$onInit();
+	    var viewState = common_1.tail(cfg.path).state.self;
+	    var hookOptions = { bind: controllerInstance };
+	    // Add component-level hook for onParamsChange
+	    if (predicates_1.isFunction(controllerInstance.uiOnParamsChanged)) {
+	        var resolveContext = new resolveContext_1.ResolveContext(cfg.path);
+	        var viewCreationTrans_1 = resolveContext.getResolvable('$transition$').data;
+	        // Fire callback on any successful transition
+	        var paramsUpdated = function ($transition$) {
+	            // Exit early if the $transition$ is the same as the view was created within.
+	            // Exit early if the $transition$ will exit the state the view is for.
+	            if ($transition$ === viewCreationTrans_1 || $transition$.exiting().indexOf(viewState) !== -1)
+	                return;
+	            var toParams = $transition$.params("to");
+	            var fromParams = $transition$.params("from");
+	            var toSchema = $transition$.treeChanges().to.map(function (node) { return node.paramSchema; }).reduce(common_1.unnestR, []);
+	            var fromSchema = $transition$.treeChanges().from.map(function (node) { return node.paramSchema; }).reduce(common_1.unnestR, []);
+	            // Find the to params that have different values than the from params
+	            var changedToParams = toSchema.filter(function (param) {
+	                var idx = fromSchema.indexOf(param);
+	                return idx === -1 || !fromSchema[idx].type.equals(toParams[param.id], fromParams[param.id]);
+	            });
+	            // Only trigger callback if a to param has changed or is new
+	            if (changedToParams.length) {
+	                var changedKeys_1 = changedToParams.map(function (x) { return x.id; });
+	                // Filter the params to only changed/new to params.  `$transition$.params()` may be used to get all params.
+	                controllerInstance.uiOnParamsChanged(common_1.filter(toParams, function (val, key) { return changedKeys_1.indexOf(key) !== -1; }), $transition$);
+	            }
+	        };
+	        $scope.$on('$destroy', $transitions.onSuccess({}, paramsUpdated, hookOptions));
+	    }
+	    // Add component-level hook for uiCanExit
+	    if (predicates_1.isFunction(controllerInstance.uiCanExit)) {
+	        var criteria = { exiting: viewState.name };
+	        $scope.$on('$destroy', $transitions.onBefore(criteria, controllerInstance.uiCanExit, hookOptions));
+	    }
+	}
+	angular.module('ui.router.state').directive('uiView', uiView);
+	angular.module('ui.router.state').directive('uiView', $ViewDirectiveFill);
+
+
+/***/ },
+/* 61 */
+/***/ function(module, exports) {
+
+	"use strict";
+	/**
+	 * @ngdoc object
+	 * @name ui.router.state.$uiViewScrollProvider
+	 *
+	 * @description
+	 * Provider that returns the {@link ui.router.state.$uiViewScroll} service function.
+	 */
+	function $ViewScrollProvider() {
+	    var useAnchorScroll = false;
+	    /**
+	     * @ngdoc function
+	     * @name ui.router.state.$uiViewScrollProvider#useAnchorScroll
+	     * @methodOf ui.router.state.$uiViewScrollProvider
+	     *
+	     * @description
+	     * Reverts back to using the core [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll) service for
+	     * scrolling based on the url anchor.
+	     */
+	    this.useAnchorScroll = function () {
+	        useAnchorScroll = true;
+	    };
+	    /**
+	     * @ngdoc object
+	     * @name ui.router.state.$uiViewScroll
+	     *
+	     * @requires $anchorScroll
+	     * @requires $timeout
+	     *
+	     * @description
+	     * When called with a jqLite element, it scrolls the element into view (after a
+	     * `$timeout` so the DOM has time to refresh).
+	     *
+	     * If you prefer to rely on `$anchorScroll` to scroll the view to the anchor,
+	     * this can be enabled by calling {@link ui.router.state.$uiViewScrollProvider#methods_useAnchorScroll `$uiViewScrollProvider.useAnchorScroll()`}.
+	     */
+	    this.$get = ['$anchorScroll', '$timeout', function ($anchorScroll, $timeout) {
+	            if (useAnchorScroll) {
+	                return $anchorScroll;
+	            }
+	            return function ($element) {
+	                return $timeout(function () {
+	                    $element[0].scrollIntoView();
+	                }, 0, false);
+	            };
+	        }];
+	}
+	angular.module('ui.router.state').provider('$uiViewScroll', $ViewScrollProvider);
+
+
+/***/ }
+/******/ ])
+});
+;
+//# sourceMappingURL=angular-ui-router.js.map
+
+/***/ },
+/* 4 */
+/***/ function(module, exports, __webpack_require__) {
+
+"use strict";
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+"use strict";
+exports.__esModule = true;
+var self;
+var ElineSide = (function () {
+    function ElineSide(XosSidePanel, XosModelStore, $http, $log, toastr) {
+        this.XosSidePanel = XosSidePanel;
+        this.XosModelStore = XosModelStore;
+        this.$http = $http;
+        this.$log = $log;
+        this.toastr = toastr;
+        self = this;
+    }
+    ElineSide.prototype.saveEline = function (item) {
+        var _this = this;
+        var path = item.path;
+        delete item.path;
+        item.$save().then(function (res) {
+            item.path = path;
+            _this.toastr.success(item.name + " successfully saved!");
+        })["catch"](function (error) {
+            _this.toastr.error("Error while saving " + item.name + ": " + error.specific_error);
+        });
+    };
+    ElineSide.prototype.deleteEline = function (item) {
+        var _this = this;
+        var name = item.name;
+        item.$delete().then(function (res) {
+            _this.toastr.success(name + " successfully deleted!");
+        })["catch"](function (error) {
+            _this.toastr.error("Error while deleting " + name + ": " + error.specific_error);
+        });
+    };
+    return ElineSide;
+}());
+ElineSide.$inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr'];
+exports.elineSide = {
+    template: __webpack_require__(11),
+    controllerAs: 'vm',
+    controller: ElineSide,
+    bindings: {
+        eng: '='
+    }
+};
+
+
+/***/ },
+/* 5 */
+/***/ function(module, exports, __webpack_require__) {
+
+"use strict";
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+"use strict";
+exports.__esModule = true;
+var _ = __webpack_require__(13);
+var self;
+var EngMap = (function () {
+    function EngMap(NgMap, XosModelStore, AppConfig, $resource, XosSidePanel, XosModelDiscoverer, ModelRest, MapConfig) {
+        this.NgMap = NgMap;
+        this.XosModelStore = XosModelStore;
+        this.AppConfig = AppConfig;
+        this.$resource = $resource;
+        this.XosSidePanel = XosSidePanel;
+        this.XosModelDiscoverer = XosModelDiscoverer;
+        this.ModelRest = ModelRest;
+        this.MapConfig = MapConfig;
+        this.unis = [];
+        this.elines = [];
+        this.cpilatlng = new Map();
+        this.paths = [];
+        this.bwps = [];
+        this.panelOpen = false;
+        this.createMode = false;
+        this.canCreateEline = true;
+        this.mapStyles = [{ 'featureType': 'administrative', 'elementType': 'labels.text.fill', 'stylers': [{ 'color': '#444444' }] }, { 'featureType': 'landscape', 'elementType': 'all', 'stylers': [{ 'color': '#f2f2f2' }] }, { 'featureType': 'poi', 'elementType': 'all', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'road', 'elementType': 'all', 'stylers': [{ 'saturation': -100 }, { 'lightness': 45 }] }, { 'featureType': 'road.highway', 'elementType': 'all', 'stylers': [{ 'visibility': 'simplified' }] }, { 'featureType': 'road.arterial', 'elementType': 'labels.icon', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'transit', 'elementType': 'all', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'water', 'elementType': 'all', 'stylers': [{ 'color': '#9ce1fc' }, { 'visibility': 'on' }] }];
+        self = this;
+    }
+    EngMap.prototype.$onInit = function () {
+        var _this = this;
+        this.NgMap.getMap().then(function (map) {
+            _this.map = map;
+            _this.uniSubscription = _this.XosModelStore.query('UserNetworkInterface', '/vnaas/usernetworkinterfaces/').subscribe(function (res) {
+                _this.unis = res;
+                _this.renderMap(map);
+            });
+            _this.elineSubscription = _this.XosModelStore.query('ELine', '/vnaas/elines/').subscribe(function (res) {
+                _this.elines = res;
+                _this.createPaths();
+                _this.renderMap(map);
+            });
+            _this.bwpSubscription = _this.XosModelStore.query('BandwidthProfile', '/vnaas/bandwidthprofiles/').subscribe(function (res) {
+                _this.bwps = res;
+            });
+        });
+    };
+    EngMap.prototype.$onDestroy = function () {
+        if (this.uniSubscription) {
+            this.uniSubscription.unsubscribe();
+        }
+    };
+    EngMap.prototype.renderMap = function (map) {
+        var bounds = new google.maps.LatLngBounds();
+        for (var i = 0; i < self.unis.length; i++) {
+            self.unis[i].eline_start = false;
+            var curr = JSON.parse(self.unis[i].latlng);
+            this.cpilatlng.set(self.unis[i].cpe_id, curr);
+            var latlng = new google.maps.LatLng(curr[0], curr[1]);
+            bounds.extend(latlng);
+        }
+        map.setCenter(bounds.getCenter());
+        map.fitBounds(bounds);
+    };
+    EngMap.prototype.createPaths = function () {
+        var _this = this;
+        this.elines.forEach(function (eline) {
+            var latlng_start = _this.cpilatlng.get(eline.connect_point_1_id);
+            var latlng_end = _this.cpilatlng.get(eline.connect_point_2_id);
+            eline.path = [latlng_start, latlng_end];
+        });
+    };
+    EngMap.prototype.colorLine = function (eline_status) {
+        var status = parseInt(eline_status, 10);
+        switch (status) {
+            case 0:
+                return '#f39c12';
+            case 1:
+                return '#2ecc71';
+            default:
+                return '#e74c3c';
+        }
+    };
+    EngMap.prototype.showUni = function (e, uni) {
+        self.current_uni = uni;
+        self.map.showInfoWindow('uni-info', this);
+    };
+    // do not display backend status or ID in create mode
+    EngMap.prototype.elinePanel = function (e, eline, exists) {
+        self.panelOpen = !self.panelOpen;
+        if (exists) {
+            self.eline = _.find(self.elines, { id: eline.id });
+        }
+        self.XosSidePanel.toggleComponent('elineSide', { eline: self.eline, bwplist: self.bwps, eng: self }, false);
+        if (!self.panelOpen && self.createMode) {
+            self.createMode = false;
+            self.canCreateEline = true;
+            self.current_uni.eline_start = false;
+        }
+    };
+    EngMap.prototype.createConnection = function (uni) {
+        return function () {
+            self.canCreateEline = false;
+            self.createMode = true;
+            uni.eline_start = true;
+            self.current_uni = uni;
+            self.eline = {
+                name: uni.name,
+                uni1name: uni.name,
+                connect_point_1_id: uni.cpe_id
+            };
+            self.elinePanel({}, self.eline, false);
+        };
+    };
+    EngMap.prototype.finishConnection = function (uni) {
+        self.eline.connect_point_2_id = uni.cpe_id;
+        if (self.eline.name === self.eline.uni1name) {
+            self.eline.name = self.eline.name + uni.name;
+        }
+        delete self.eline.uni1name;
+        var resource = this.ModelRest.getResource('/vnaas/elines/');
+        var res = new resource({});
+        for (var attr in self.eline) {
+            if (true) {
+                res[attr] = self.eline[attr];
+            }
+        }
+        self.eline = res;
+    };
+    return EngMap;
+}());
+EngMap.$inject = [
+    'NgMap',
+    'XosModelStore',
+    'AppConfig',
+    '$resource',
+    'XosSidePanel',
+    'XosModelDiscoverer',
+    'ModelRest',
+    'MapConfig',
+];
+exports.EngMap = EngMap;
+exports.engMap = {
+    template: __webpack_require__(12),
+    controllerAs: 'vm',
+    controller: EngMap
+};
+
+
+/***/ },
+/* 6 */
+/***/ function(module, exports) {
+
+"use strict";
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+"use strict";
+exports.__esModule = true;
+exports["default"] = routesConfig;
+function routesConfig($stateProvider, $locationProvider) {
+    $locationProvider.html5Mode(false).hashPrefix('');
+    $stateProvider
+        .state('xos.vnaasgui', {
+        url: 'vnaasgui',
+        parent: 'xos',
+        component: 'engMap'
+    });
+}
+
+
+/***/ },
+/* 7 */
+/***/ function(module, exports, __webpack_require__) {
+
+(function(root, factory) {
+if (true) {
+module.exports = factory(__webpack_require__(0));
+} else if (typeof define === "function" && define.amd) {
+define(['angular'], factory);
+} else{
+factory(root.angular);
+}
+}(this, function(angular) {
+/**
+ * AngularJS Google Maps Ver. 1.18.3
+ *
+ * The MIT License (MIT)
+ * 
+ * Copyright (c) 2014, 2015, 1016 Allen Kim
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+angular.module('ngMap', []);
+
+/**
+ * @ngdoc controller
+ * @name MapController
+ */
+(function() {
+  'use strict';
+  var Attr2MapOptions;
+
+  var __MapController = function(
+      $scope, $element, $attrs, $parse, $interpolate, _Attr2MapOptions_, NgMap, NgMapPool, escapeRegExp
+    ) {
+    Attr2MapOptions = _Attr2MapOptions_;
+    var vm = this;
+    var exprStartSymbol = $interpolate.startSymbol();
+    var exprEndSymbol = $interpolate.endSymbol();
+
+    vm.mapOptions; /** @memberof __MapController */
+    vm.mapEvents;  /** @memberof __MapController */
+    vm.eventListeners;  /** @memberof __MapController */
+
+    /**
+     * Add an object to the collection of group
+     * @memberof __MapController
+     * @function addObject
+     * @param groupName the name of collection that object belongs to
+     * @param obj  an object to add into a collection, i.e. marker, shape
+     */
+    vm.addObject = function(groupName, obj) {
+      if (vm.map) {
+        vm.map[groupName] = vm.map[groupName] || {};
+        var len = Object.keys(vm.map[groupName]).length;
+        vm.map[groupName][obj.id || len] = obj;
+
+        if (vm.map instanceof google.maps.Map) {
+          //infoWindow.setMap works like infoWindow.open
+          if (groupName != "infoWindows" && obj.setMap) {
+            obj.setMap && obj.setMap(vm.map);
+          }
+          if (obj.centered && obj.position) {
+            vm.map.setCenter(obj.position);
+          }
+          (groupName == 'markers') && vm.objectChanged('markers');
+          (groupName == 'customMarkers') && vm.objectChanged('customMarkers');
+        }
+      }
+    };
+
+    /**
+     * Delete an object from the collection and remove from map
+     * @memberof __MapController
+     * @function deleteObject
+     * @param {Array} objs the collection of objects. i.e., map.markers
+     * @param {Object} obj the object to be removed. i.e., marker
+     */
+    vm.deleteObject = function(groupName, obj) {
+      /* delete from group */
+      if (obj.map) {
+        var objs = obj.map[groupName];
+        for (var name in objs) {
+          if (objs[name] === obj) {
+            void 0;
+            google.maps.event.clearInstanceListeners(obj);
+            delete objs[name];
+          }
+        }
+
+        /* delete from map */
+        obj.map && obj.setMap && obj.setMap(null);
+
+        (groupName == 'markers') && vm.objectChanged('markers');
+        (groupName == 'customMarkers') && vm.objectChanged('customMarkers');
+      }
+    };
+
+    /**
+     * @memberof __MapController
+     * @function observeAttrSetObj
+     * @param {Hash} orgAttrs attributes before its initialization
+     * @param {Hash} attrs    attributes after its initialization
+     * @param {Object} obj    map object that an action is to be done
+     * @description watch changes of attribute values and
+     * do appropriate action based on attribute name
+     */
+    vm.observeAttrSetObj = function(orgAttrs, attrs, obj) {
+      if (attrs.noWatcher) {
+        return false;
+      }
+      var attrsToObserve = Attr2MapOptions.getAttrsToObserve(orgAttrs);
+      for (var i=0; i<attrsToObserve.length; i++) {
+        var attrName = attrsToObserve[i];
+        attrs.$observe(attrName, NgMap.observeAndSet(attrName, obj));
+      }
+    };
+
+    /**
+     * @memberof __MapController
+     * @function zoomToIncludeMarkers
+     */
+    vm.zoomToIncludeMarkers = function() {
+      // Only fit to bounds if we have any markers
+      // object.keys is supported in all major browsers (IE9+)
+      if ((vm.map.markers != null && Object.keys(vm.map.markers).length > 0) || (vm.map.customMarkers != null && Object.keys(vm.map.customMarkers).length > 0)) {
+        var bounds = new google.maps.LatLngBounds();
+        for (var k1 in vm.map.markers) {
+          bounds.extend(vm.map.markers[k1].getPosition());
+        }
+        for (var k2 in vm.map.customMarkers) {
+          bounds.extend(vm.map.customMarkers[k2].getPosition());
+        }
+    	  if (vm.mapOptions.maximumZoom) {
+    		  vm.enableMaximumZoomCheck = true; //enable zoom check after resizing for markers
+    	  }
+        vm.map.fitBounds(bounds);
+      }
+    };
+
+    /**
+     * @memberof __MapController
+     * @function objectChanged
+     * @param {String} group name of group e.g., markers
+     */
+    vm.objectChanged = function(group) {
+      if ( vm.map &&
+        (group == 'markers' || group == 'customMarkers') &&
+        vm.map.zoomToIncludeMarkers == 'auto'
+      ) {
+        vm.zoomToIncludeMarkers();
+      }
+    };
+
+    /**
+     * @memberof __MapController
+     * @function initializeMap
+     * @description
+     *  . initialize Google map on <div> tag
+     *  . set map options, events, and observers
+     *  . reset zoom to include all (custom)markers
+     */
+    vm.initializeMap = function() {
+      var mapOptions = vm.mapOptions,
+          mapEvents = vm.mapEvents;
+
+      var lazyInitMap = vm.map; //prepared for lazy init
+      vm.map = NgMapPool.getMapInstance($element[0]);
+      NgMap.setStyle($element[0]);
+
+      // set objects for lazyInit
+      if (lazyInitMap) {
+
+        /**
+         * rebuild mapOptions for lazyInit
+         * because attributes values might have been changed
+         */
+        var filtered = Attr2MapOptions.filter($attrs);
+        var options = Attr2MapOptions.getOptions(filtered);
+        var controlOptions = Attr2MapOptions.getControlOptions(filtered);
+        mapOptions = angular.extend(options, controlOptions);
+        void 0;
+
+        for (var group in lazyInitMap) {
+          var groupMembers = lazyInitMap[group]; //e.g. markers
+          if (typeof groupMembers == 'object') {
+            for (var id in groupMembers) {
+              vm.addObject(group, groupMembers[id]);
+            }
+          }
+        }
+        vm.map.showInfoWindow = vm.showInfoWindow;
+        vm.map.hideInfoWindow = vm.hideInfoWindow;
+      }
+
+      // set options
+      mapOptions.zoom = mapOptions.zoom || 15;
+      var center = mapOptions.center;
+      var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '.*' + escapeRegExp(exprEndSymbol));
+
+      if (!mapOptions.center ||
+        ((typeof center === 'string') && center.match(exprRegExp))
+      ) {
+        mapOptions.center = new google.maps.LatLng(0, 0);
+      } else if( (typeof center === 'string') && center.match(/^[0-9.-]*,[0-9.-]*$/) ){
+        var lat = parseFloat(center.split(',')[0]);
+        var lng = parseFloat(center.split(',')[1]);
+        mapOptions.center = new google.maps.LatLng(lat, lng);
+      } else if (!(center instanceof google.maps.LatLng)) {
+        var geoCenter = mapOptions.center;
+        delete mapOptions.center;
+        NgMap.getGeoLocation(geoCenter, mapOptions.geoLocationOptions).
+          then(function (latlng) {
+            vm.map.setCenter(latlng);
+            var geoCallback = mapOptions.geoCallback;
+            geoCallback && $parse(geoCallback)($scope);
+          }, function () {
+            if (mapOptions.geoFallbackCenter) {
+              vm.map.setCenter(mapOptions.geoFallbackCenter);
+            }
+          });
+      }
+      vm.map.setOptions(mapOptions);
+
+      // set events
+      for (var eventName in mapEvents) {
+        var event = mapEvents[eventName];
+        var listener = google.maps.event.addListener(vm.map, eventName, event);
+        vm.eventListeners[eventName] = listener;
+      }
+
+      // set observers
+      vm.observeAttrSetObj(orgAttrs, $attrs, vm.map);
+      vm.singleInfoWindow = mapOptions.singleInfoWindow;
+
+      google.maps.event.trigger(vm.map, 'resize');
+
+      google.maps.event.addListenerOnce(vm.map, "idle", function () {
+        NgMap.addMap(vm);
+        if (mapOptions.zoomToIncludeMarkers) {
+          vm.zoomToIncludeMarkers();
+        }
+        //TODO: it's for backward compatibiliy. will be removed
+        $scope.map = vm.map;
+        $scope.$emit('mapInitialized', vm.map);
+
+        //callback
+        if ($attrs.mapInitialized) {
+          $parse($attrs.mapInitialized)($scope, {map: vm.map});
+        }
+      });
+
+	  //add maximum zoom listeners if zoom-to-include-markers and and maximum-zoom are valid attributes
+	  if (mapOptions.zoomToIncludeMarkers && mapOptions.maximumZoom) {
+	    google.maps.event.addListener(vm.map, 'zoom_changed', function() {
+          if (vm.enableMaximumZoomCheck == true) {
+			vm.enableMaximumZoomCheck = false;
+	        google.maps.event.addListenerOnce(vm.map, 'bounds_changed', function() {
+		      vm.map.setZoom(Math.min(mapOptions.maximumZoom, vm.map.getZoom()));
+		    });
+	  	  }
+	    });
+	  }
+    };
+
+    $scope.google = google; //used by $scope.eval to avoid eval()
+
+    /**
+     * get map options and events
+     */
+    var orgAttrs = Attr2MapOptions.orgAttributes($element);
+    var filtered = Attr2MapOptions.filter($attrs);
+    var options = Attr2MapOptions.getOptions(filtered, {scope: $scope});
+    var controlOptions = Attr2MapOptions.getControlOptions(filtered);
+    var mapOptions = angular.extend(options, controlOptions);
+    var mapEvents = Attr2MapOptions.getEvents($scope, filtered);
+    void 0;
+    Object.keys(mapEvents).length && void 0;
+
+    vm.mapOptions = mapOptions;
+    vm.mapEvents = mapEvents;
+    vm.eventListeners = {};
+
+    if (options.lazyInit) { // allows controlled initialization
+      // parse angular expression for dynamic ids
+      if (!!$attrs.id &&
+      	  // starts with, at position 0
+	  $attrs.id.indexOf(exprStartSymbol, 0) === 0 &&
+	  // ends with
+	  $attrs.id.indexOf(exprEndSymbol, $attrs.id.length - exprEndSymbol.length) !== -1) {
+        var idExpression = $attrs.id.slice(2,-2);
+        var mapId = $parse(idExpression)($scope);
+      } else {
+        var mapId = $attrs.id;
+      }
+      vm.map = {id: mapId}; //set empty, not real, map
+      NgMap.addMap(vm);
+    } else {
+      vm.initializeMap();
+    }
+
+    //Trigger Resize
+    if(options.triggerResize) {
+      google.maps.event.trigger(vm.map, 'resize');
+    }
+
+    $element.bind('$destroy', function() {
+      NgMapPool.returnMapInstance(vm.map);
+      NgMap.deleteMap(vm);
+    });
+  }; // __MapController
+
+  __MapController.$inject = [
+    '$scope', '$element', '$attrs', '$parse', '$interpolate', 'Attr2MapOptions', 'NgMap', 'NgMapPool', 'escapeRegexpFilter'
+  ];
+  angular.module('ngMap').controller('__MapController', __MapController);
+})();
+
+/**
+ * @ngdoc directive
+ * @name bicycling-layer
+ * @param Attr2Options {service}
+ *   convert html attribute to Google map api options
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ *
+ *   <map zoom="13" center="34.04924594193164, -118.24104309082031">
+ *     <bicycling-layer></bicycling-layer>
+ *    </map>
+ */
+(function() {
+  'use strict';
+  var parser;
+
+  var linkFunc = function(scope, element, attrs, mapController) {
+    mapController = mapController[0]||mapController[1];
+    var orgAttrs = parser.orgAttributes(element);
+    var filtered = parser.filter(attrs);
+    var options = parser.getOptions(filtered, {scope: scope});
+    var events = parser.getEvents(scope, filtered);
+
+    void 0;
+
+    var layer = getLayer(options, events);
+    mapController.addObject('bicyclingLayers', layer);
+    mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers
+    element.bind('$destroy', function() {
+      mapController.deleteObject('bicyclingLayers', layer);
+    });
+  };
+
+  var getLayer = function(options, events) {
+    var layer = new google.maps.BicyclingLayer(options);
+    for (var eventName in events) {
+      google.maps.event.addListener(layer, eventName, events[eventName]);
+    }
+    return layer;
+  };
+
+  var bicyclingLayer= function(Attr2MapOptions) {
+    parser = Attr2MapOptions;
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+      link: linkFunc
+     };
+  };
+  bicyclingLayer.$inject = ['Attr2MapOptions'];
+
+  angular.module('ngMap').directive('bicyclingLayer', bicyclingLayer);
+})();
+
+/**
+ * @ngdoc directive
+ * @name custom-control
+ * @param Attr2Options {service} convert html attribute to Google map api options
+ * @param $compile {service} AngularJS $compile service
+ * @description
+ *   Build custom control and set to the map with position
+ *
+ *   Requires:  map directive
+ *
+ *   Restrict To:  Element
+ *
+ * @attr {String} position position of this control
+ *        i.e. TOP_RIGHT
+ * @attr {Number} index index of the control
+ * @example
+ *
+ * Example:
+ *  <map center="41.850033,-87.6500523" zoom="3">
+ *    <custom-control id="home" position="TOP_LEFT" index="1">
+ *      <div style="background-color: white;">
+ *        <b>Home</b>
+ *      </div>
+ *    </custom-control>
+ *  </map>
+ *
+ */
+(function() {
+  'use strict';
+  var parser, NgMap;
+
+  var linkFunc = function(scope, element, attrs, mapController, $transclude) {
+    mapController = mapController[0]||mapController[1];
+    var filtered = parser.filter(attrs);
+    var options = parser.getOptions(filtered, {scope: scope});
+    var events = parser.getEvents(scope, filtered);
+
+    /**
+     * build a custom control element
+     */
+    var customControlEl = element[0].parentElement.removeChild(element[0]);
+    var content = $transclude();
+    angular.element(customControlEl).append(content);
+
+    /**
+     * set events
+     */
+    for (var eventName in events) {
+      google.maps.event.addDomListener(customControlEl, eventName, events[eventName]);
+    }
+
+    mapController.addObject('customControls', customControlEl);
+    var position = options.position;
+    mapController.map.controls[google.maps.ControlPosition[position]].push(customControlEl);
+
+    element.bind('$destroy', function() {
+      mapController.deleteObject('customControls', customControlEl);
+    });
+  };
+
+  var customControl =  function(Attr2MapOptions, _NgMap_)  {
+    parser = Attr2MapOptions, NgMap = _NgMap_;
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+      link: linkFunc,
+      transclude: true
+    }; // return
+  };
+  customControl.$inject = ['Attr2MapOptions', 'NgMap'];
+
+  angular.module('ngMap').directive('customControl', customControl);
+})();
+
+/**
+ * @ngdoc directive
+ * @memberof ngmap
+ * @name custom-marker
+ * @param Attr2Options {service} convert html attribute to Google map api options
+ * @param $timeout {service} AngularJS $timeout
+ * @description
+ *   Marker with html
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @attr {String} position required, position on map
+ * @attr {Number} z-index optional
+ * @attr {Boolean} visible optional
+ * @example
+ *
+ * Example:
+ *   <map center="41.850033,-87.6500523" zoom="3">
+ *     <custom-marker position="41.850033,-87.6500523">
+ *       <div>
+ *         <b>Home</b>
+ *       </div>
+ *     </custom-marker>
+ *   </map>
+ *
+ */
+/* global document */
+(function() {
+  'use strict';
+  var parser, $timeout, $compile, NgMap;
+
+  var CustomMarker = function(options) {
+    options = options || {};
+
+    this.el = document.createElement('div');
+    this.el.style.display = 'inline-block';
+    this.el.style.visibility = "hidden";
+    this.visible = true;
+    for (var key in options) { /* jshint ignore:line */
+     this[key] = options[key];
+    }
+  };
+
+  var setCustomMarker = function() {
+
+    CustomMarker.prototype = new google.maps.OverlayView();
+
+    CustomMarker.prototype.setContent = function(html, scope) {
+      this.el.innerHTML = html;
+      this.el.style.position = 'absolute';
+      if (scope) {
+        $compile(angular.element(this.el).contents())(scope);
+      }
+    };
+
+    CustomMarker.prototype.getDraggable = function() {
+      return this.draggable;
+    };
+
+    CustomMarker.prototype.setDraggable = function(draggable) {
+      this.draggable = draggable;
+    };
+
+    CustomMarker.prototype.getPosition = function() {
+      return this.position;
+    };
+
+    CustomMarker.prototype.setPosition = function(position) {
+      position && (this.position = position); /* jshint ignore:line */
+      var _this = this;
+      if (this.getProjection() && typeof this.position.lng == 'function') {
+        void 0;
+        var setPosition = function() {
+          if (!_this.getProjection()) { return; }
+          var posPixel = _this.getProjection().fromLatLngToDivPixel(_this.position);
+          var x = Math.round(posPixel.x - (_this.el.offsetWidth/2));
+          var y = Math.round(posPixel.y - _this.el.offsetHeight - 10); // 10px for anchor
+          _this.el.style.left = x + "px";
+          _this.el.style.top = y + "px";
+          _this.el.style.visibility = "visible";
+        };
+        if (_this.el.offsetWidth && _this.el.offsetHeight) {
+          setPosition();
+        } else {
+          //delayed left/top calculation when width/height are not set instantly
+          $timeout(setPosition, 300);
+        }
+      }
+    };
+
+    CustomMarker.prototype.setZIndex = function(zIndex) {
+      zIndex && (this.zIndex = zIndex); /* jshint ignore:line */
+      this.el.style.zIndex = this.zIndex;
+    };
+
+    CustomMarker.prototype.getVisible = function() {
+      return this.visible;
+    };
+
+    CustomMarker.prototype.setVisible = function(visible) {
+      this.el.style.display = visible ? 'inline-block' : 'none';
+      this.visible = visible;
+    };
+
+    CustomMarker.prototype.addClass = function(className) {
+      var classNames = this.el.className.trim().split(' ');
+      (classNames.indexOf(className) == -1) && classNames.push(className); /* jshint ignore:line */
+      this.el.className = classNames.join(' ');
+    };
+
+    CustomMarker.prototype.removeClass = function(className) {
+      var classNames = this.el.className.split(' ');
+      var index = classNames.indexOf(className);
+      (index > -1) && classNames.splice(index, 1); /* jshint ignore:line */
+      this.el.className = classNames.join(' ');
+    };
+
+    CustomMarker.prototype.onAdd = function() {
+      this.getPanes().overlayMouseTarget.appendChild(this.el);
+    };
+
+    CustomMarker.prototype.draw = function() {
+      this.setPosition();
+      this.setZIndex(this.zIndex);
+      this.setVisible(this.visible);
+    };
+
+    CustomMarker.prototype.onRemove = function() {
+      this.el.parentNode.removeChild(this.el);
+      //this.el = null;
+    };
+  };
+
+  var linkFunc = function(orgHtml, varsToWatch) {
+    //console.log('orgHtml', orgHtml, 'varsToWatch', varsToWatch);
+
+    return function(scope, element, attrs, mapController) {
+      mapController = mapController[0]||mapController[1];
+      var orgAttrs = parser.orgAttributes(element);
+
+      var filtered = parser.filter(attrs);
+      var options = parser.getOptions(filtered, {scope: scope});
+      var events = parser.getEvents(scope, filtered);
+
+      /**
+       * build a custom marker element
+       */
+      element[0].style.display = 'none';
+      void 0;
+      var customMarker = new CustomMarker(options);
+
+      $timeout(function() { //apply contents, class, and location after it is compiled
+
+        scope.$watch('[' + varsToWatch.join(',') + ']', function() {
+          customMarker.setContent(orgHtml, scope);
+        }, true);
+
+        customMarker.setContent(element[0].innerHTML, scope);
+        var classNames = element[0].firstElementChild.className;
+        customMarker.addClass('custom-marker');
+        customMarker.addClass(classNames);
+        void 0;
+
+        if (!(options.position instanceof google.maps.LatLng)) {
+          NgMap.getGeoLocation(options.position).then(
+                function(latlng) {
+                  customMarker.setPosition(latlng);
+                }
+          );
+        }
+
+      });
+
+      void 0;
+      for (var eventName in events) { /* jshint ignore:line */
+        google.maps.event.addDomListener(
+          customMarker.el, eventName, events[eventName]);
+      }
+      mapController.addObject('customMarkers', customMarker);
+
+      //set observers
+      mapController.observeAttrSetObj(orgAttrs, attrs, customMarker);
+
+      element.bind('$destroy', function() {
+        //Is it required to remove event listeners when DOM is removed?
+        mapController.deleteObject('customMarkers', customMarker);
+      });
+
+    }; // linkFunc
+  };
+
+
+  var customMarkerDirective = function(
+      _$timeout_, _$compile_, $interpolate, Attr2MapOptions, _NgMap_, escapeRegExp
+    )  {
+    parser = Attr2MapOptions;
+    $timeout = _$timeout_;
+    $compile = _$compile_;
+    NgMap = _NgMap_;
+
+    var exprStartSymbol = $interpolate.startSymbol();
+    var exprEndSymbol = $interpolate.endSymbol();
+    var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '([^' + exprEndSymbol.substring(0, 1) + ']+)' + escapeRegExp(exprEndSymbol), 'g');
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+      compile: function(element) {
+        setCustomMarker();
+        element[0].style.display ='none';
+        var orgHtml = element.html();
+        var matches = orgHtml.match(exprRegExp);
+        var varsToWatch = [];
+        //filter out that contains '::', 'this.'
+        (matches || []).forEach(function(match) {
+          var toWatch = match.replace(exprStartSymbol,'').replace(exprEndSymbol,'');
+          if (match.indexOf('::') == -1 &&
+            match.indexOf('this.') == -1 &&
+            varsToWatch.indexOf(toWatch) == -1) {
+            varsToWatch.push(match.replace(exprStartSymbol,'').replace(exprEndSymbol,''));
+          }
+        });
+
+        return linkFunc(orgHtml, varsToWatch);
+      }
+    }; // return
+  };// function
+  customMarkerDirective.$inject =
+    ['$timeout', '$compile', '$interpolate', 'Attr2MapOptions', 'NgMap', 'escapeRegexpFilter'];
+
+  angular.module('ngMap').directive('customMarker', customMarkerDirective);
+})();
+
+/**
+ * @ngdoc directive
+ * @name directions
+ * @description
+ *   Enable directions on map.
+ *   e.g., origin, destination, draggable, waypoints, etc
+ *
+ *   Requires:  map directive
+ *
+ *   Restrict To:  Element
+ *
+ * @attr {String} DirectionsRendererOptions
+ *   [Any DirectionsRendererOptions](https://developers.google.com/maps/documentation/javascript/reference#DirectionsRendererOptions)
+ * @attr {String} DirectionsRequestOptions
+ *   [Any DirectionsRequest options](https://developers.google.com/maps/documentation/javascript/reference#DirectionsRequest)
+ * @example
+ *  <map zoom="14" center="37.7699298, -122.4469157">
+ *    <directions
+ *      draggable="true"
+ *      panel="directions-panel"
+ *      travel-mode="{{travelMode}}"
+ *      waypoints="[{location:'kingston', stopover:true}]"
+ *      origin="{{origin}}"
+ *      destination="{{destination}}">
+ *    </directions>
+ *  </map>
+ */
+/* global document */
+(function() {
+  'use strict';
+  var NgMap, $timeout, NavigatorGeolocation;
+
+  var getDirectionsRenderer = function(options, events) {
+    if (options.panel) {
+      options.panel = document.getElementById(options.panel) ||
+        document.querySelector(options.panel);
+    }
+    var renderer = new google.maps.DirectionsRenderer(options);
+    for (var eventName in events) {
+      google.maps.event.addListener(renderer, eventName, events[eventName]);
+    }
+    return renderer;
+  };
+
+  var updateRoute = function(renderer, options) {
+    var directionsService = new google.maps.DirectionsService();
+
+    /* filter out valid keys only for DirectionsRequest object*/
+    var request = options;
+    request.travelMode = request.travelMode || 'DRIVING';
+    var validKeys = [
+      'origin', 'destination', 'travelMode', 'transitOptions', 'unitSystem',
+      'durationInTraffic', 'waypoints', 'optimizeWaypoints', 
+      'provideRouteAlternatives', 'avoidHighways', 'avoidTolls', 'region'
+    ];
+    for(var key in request){
+      (validKeys.indexOf(key) === -1) && (delete request[key]);
+    }
+
+    if(request.waypoints) {
+      // Check fo valid values
+      if(request.waypoints == "[]" || request.waypoints === "") {
+        delete request.waypoints;
+      }
+    }
+
+    var showDirections = function(request) {
+      directionsService.route(request, function(response, status) {
+        if (status == google.maps.DirectionsStatus.OK) {
+          $timeout(function() {
+            renderer.setDirections(response);
+          });
+        }
+      });
+    };
+
+    if (request.origin && request.destination) {
+      if (request.origin == 'current-location') {
+        NavigatorGeolocation.getCurrentPosition().then(function(ll) {
+          request.origin = new google.maps.LatLng(ll.coords.latitude, ll.coords.longitude);
+          showDirections(request);
+        });
+      } else if (request.destination == 'current-location') {
+        NavigatorGeolocation.getCurrentPosition().then(function(ll) {
+          request.destination = new google.maps.LatLng(ll.coords.latitude, ll.coords.longitude);
+          showDirections(request);
+        });
+      } else {
+        showDirections(request);
+      }
+    }
+  };
+
+  var directions = function(
+      Attr2MapOptions, _$timeout_, _NavigatorGeolocation_, _NgMap_) {
+    var parser = Attr2MapOptions;
+    NgMap = _NgMap_;
+    $timeout = _$timeout_;
+    NavigatorGeolocation = _NavigatorGeolocation_;
+
+    var linkFunc = function(scope, element, attrs, mapController) {
+      mapController = mapController[0]||mapController[1];
+
+      var orgAttrs = parser.orgAttributes(element);
+      var filtered = parser.filter(attrs);
+      var options = parser.getOptions(filtered, {scope: scope});
+      var events = parser.getEvents(scope, filtered);
+      var attrsToObserve = parser.getAttrsToObserve(orgAttrs);
+
+      var renderer = getDirectionsRenderer(options, events);
+      mapController.addObject('directionsRenderers', renderer);
+
+      attrsToObserve.forEach(function(attrName) {
+        (function(attrName) {
+          attrs.$observe(attrName, function(val) {
+            if (attrName == 'panel') {
+              $timeout(function(){
+                var panel =
+                  document.getElementById(val) || document.querySelector(val);
+                void 0;
+                panel && renderer.setPanel(panel);
+              });
+            } else if (options[attrName] !== val) { //apply only if changed
+              var optionValue = parser.toOptionValue(val, {key: attrName});
+              void 0;
+              options[attrName] = optionValue;
+              updateRoute(renderer, options);
+            }
+          });
+        })(attrName);
+      });
+
+      NgMap.getMap().then(function() {
+        updateRoute(renderer, options);
+      });
+      element.bind('$destroy', function() {
+        mapController.deleteObject('directionsRenderers', renderer);
+      });
+    };
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+      link: linkFunc
+    };
+  }; // var directions
+  directions.$inject =
+    ['Attr2MapOptions', '$timeout', 'NavigatorGeolocation', 'NgMap'];
+
+  angular.module('ngMap').directive('directions', directions);
+})();
+
+
+/**
+ * @ngdoc directive
+ * @name drawing-manager
+ * @param Attr2Options {service} convert html attribute to Google map api options
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ * Example:
+ *
+ *  <map zoom="13" center="37.774546, -122.433523" map-type-id="SATELLITE">
+ *    <drawing-manager
+ *      on-overlaycomplete="onMapOverlayCompleted()"
+ *      position="ControlPosition.TOP_CENTER"
+ *      drawingModes="POLYGON,CIRCLE"
+ *      drawingControl="true"
+ *      circleOptions="fillColor: '#FFFF00';fillOpacity: 1;strokeWeight: 5;clickable: false;zIndex: 1;editable: true;" >
+ *    </drawing-manager>
+ *  </map>
+ *
+ *  TODO: Add remove button.
+ *  currently, for our solution, we have the shapes/markers in our own
+ *  controller, and we use some css classes to change the shape button
+ *  to a remove button (<div>X</div>) and have the remove operation in our own controller.
+ */
+(function() {
+  'use strict';
+  angular.module('ngMap').directive('drawingManager', [
+    'Attr2MapOptions', function(Attr2MapOptions) {
+    var parser = Attr2MapOptions;
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var filtered = parser.filter(attrs);
+        var options = parser.getOptions(filtered, {scope: scope});
+        var controlOptions = parser.getControlOptions(filtered);
+        var events = parser.getEvents(scope, filtered);
+
+        /**
+         * set options
+         */
+        var drawingManager = new google.maps.drawing.DrawingManager({
+          drawingMode: options.drawingmode,
+          drawingControl: options.drawingcontrol,
+          drawingControlOptions: controlOptions.drawingControlOptions,
+          circleOptions:options.circleoptions,
+          markerOptions:options.markeroptions,
+          polygonOptions:options.polygonoptions,
+          polylineOptions:options.polylineoptions,
+          rectangleOptions:options.rectangleoptions
+        });
+
+        //Observers
+        attrs.$observe('drawingControlOptions', function (newValue) {
+          drawingManager.drawingControlOptions = parser.getControlOptions({drawingControlOptions: newValue}).drawingControlOptions;
+          drawingManager.setDrawingMode(null);
+          drawingManager.setMap(mapController.map);
+        });
+
+
+        /**
+         * set events
+         */
+        for (var eventName in events) {
+          google.maps.event.addListener(drawingManager, eventName, events[eventName]);
+        }
+
+        mapController.addObject('mapDrawingManager', drawingManager);
+
+        element.bind('$destroy', function() {
+          mapController.deleteObject('mapDrawingManager', drawingManager);
+        });
+      }
+    }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name dynamic-maps-engine-layer
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ * Example:
+ *   <map zoom="14" center="[59.322506, 18.010025]">
+ *     <dynamic-maps-engine-layer
+ *       layer-id="06673056454046135537-08896501997766553811">
+ *     </dynamic-maps-engine-layer>
+ *    </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('dynamicMapsEngineLayer', [
+    'Attr2MapOptions', function(Attr2MapOptions) {
+    var parser = Attr2MapOptions;
+
+    var getDynamicMapsEngineLayer = function(options, events) {
+      var layer = new google.maps.visualization.DynamicMapsEngineLayer(options);
+
+      for (var eventName in events) {
+        google.maps.event.addListener(layer, eventName, events[eventName]);
+      }
+
+      return layer;
+    };
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var filtered = parser.filter(attrs);
+        var options = parser.getOptions(filtered, {scope: scope});
+        var events = parser.getEvents(scope, filtered, events);
+
+        var layer = getDynamicMapsEngineLayer(options, events);
+        mapController.addObject('mapsEngineLayers', layer);
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name fusion-tables-layer
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ * Example:
+ *   <map zoom="11" center="41.850033, -87.6500523">
+ *     <fusion-tables-layer query="{
+ *       select: 'Geocodable address',
+ *       from: '1mZ53Z70NsChnBMm-qEYmSDOvLXgrreLTkQUvvg'}">
+ *     </fusion-tables-layer>
+ *   </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('fusionTablesLayer', [
+    'Attr2MapOptions', function(Attr2MapOptions) {
+    var parser = Attr2MapOptions;
+
+    var getLayer = function(options, events) {
+      var layer = new google.maps.FusionTablesLayer(options);
+
+      for (var eventName in events) {
+        google.maps.event.addListener(layer, eventName, events[eventName]);
+      }
+
+      return layer;
+    };
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var filtered = parser.filter(attrs);
+        var options = parser.getOptions(filtered, {scope: scope});
+        var events = parser.getEvents(scope, filtered, events);
+        void 0;
+
+        var layer = getLayer(options, events);
+        mapController.addObject('fusionTablesLayers', layer);
+        element.bind('$destroy', function() {
+          mapController.deleteObject('fusionTablesLayers', layer);
+        });
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name heatmap-layer
+ * @param Attr2Options {service} convert html attribute to Google map api options
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ *
+ * <map zoom="11" center="[41.875696,-87.624207]">
+ *   <heatmap-layer data="taxiData"></heatmap-layer>
+ * </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('heatmapLayer', [
+    'Attr2MapOptions', '$window', function(Attr2MapOptions, $window) {
+    var parser = Attr2MapOptions;
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var filtered = parser.filter(attrs);
+
+        /**
+         * set options
+         */
+        var options = parser.getOptions(filtered, {scope: scope});
+        options.data = $window[attrs.data] || scope[attrs.data];
+        if (options.data instanceof Array) {
+          options.data = new google.maps.MVCArray(options.data);
+        } else {
+          throw "invalid heatmap data";
+        }
+        var layer = new google.maps.visualization.HeatmapLayer(options);
+
+        /**
+         * set events
+         */
+        var events = parser.getEvents(scope, filtered);
+        void 0;
+
+        mapController.addObject('heatmapLayers', layer);
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name info-window
+ * @param Attr2MapOptions {service}
+ *   convert html attribute to Google map api options
+ * @param $compile {service} $compile service
+ * @description
+ *  Defines infoWindow and provides compile method
+ *
+ *  Requires:  map directive
+ *
+ *  Restrict To:  Element
+ *
+ *  NOTE: this directive should **NOT** be used with `ng-repeat`
+ *  because InfoWindow itself is a template, and a template must be
+ *  reused by each marker, thus, should not be redefined repeatedly
+ *  by `ng-repeat`.
+ *
+ * @attr {Boolean} visible
+ *   Indicates to show it when map is initialized
+ * @attr {Boolean} visible-on-marker
+ *   Indicates to show it on a marker when map is initialized
+ * @attr {Expression} geo-callback
+ *   if position is an address, the expression is will be performed
+ *   when geo-lookup is successful. e.g., geo-callback="showDetail()"
+ * @attr {String} &lt;InfoWindowOption> Any InfoWindow options,
+ *   https://developers.google.com/maps/documentation/javascript/reference?csw=1#InfoWindowOptions
+ * @attr {String} &lt;InfoWindowEvent> Any InfoWindow events,
+ *   https://developers.google.com/maps/documentation/javascript/reference
+ * @example
+ * Usage:
+ *   <map MAP_ATTRIBUTES>
+ *    <info-window id="foo" ANY_OPTIONS ANY_EVENTS"></info-window>
+ *   </map>
+ *
+ * Example:
+ *  <map center="41.850033,-87.6500523" zoom="3">
+ *    <info-window id="1" position="41.850033,-87.6500523" >
+ *      <div ng-non-bindable>
+ *        Chicago, IL<br/>
+ *        LatLng: {{chicago.lat()}}, {{chicago.lng()}}, <br/>
+ *        World Coordinate: {{worldCoordinate.x}}, {{worldCoordinate.y}}, <br/>
+ *        Pixel Coordinate: {{pixelCoordinate.x}}, {{pixelCoordinate.y}}, <br/>
+ *        Tile Coordinate: {{tileCoordinate.x}}, {{tileCoordinate.y}} at Zoom Level {{map.getZoom()}}
+ *      </div>
+ *    </info-window>
+ *  </map>
+ */
+/* global google */
+(function() {
+  'use strict';
+
+  var infoWindow = function(Attr2MapOptions, $compile, $q, $templateRequest, $timeout, $parse, NgMap)  {
+    var parser = Attr2MapOptions;
+
+    var getInfoWindow = function(options, events, element) {
+      var infoWindow;
+
+      /**
+       * set options
+       */
+      if (options.position && !(options.position instanceof google.maps.LatLng)) {
+        delete options.position;
+      }
+      infoWindow = new google.maps.InfoWindow(options);
+
+      /**
+       * set events
+       */
+      for (var eventName in events) {
+        if (eventName) {
+          google.maps.event.addListener(infoWindow, eventName, events[eventName]);
+        }
+      }
+
+      /**
+       * set template and template-related functions
+       * it must have a container element with ng-non-bindable
+       */
+      var templatePromise = $q(function(resolve) {
+        if (angular.isString(element)) {
+          $templateRequest(element).then(function (requestedTemplate) {
+            resolve(angular.element(requestedTemplate).wrap('<div>').parent());
+          }, function(message) {
+            throw "info-window template request failed: " + message;
+          });
+        }
+        else {
+          resolve(element);
+        }
+      }).then(function(resolvedTemplate) {
+        var template = resolvedTemplate.html().trim();
+        if (angular.element(template).length != 1) {
+          throw "info-window working as a template must have a container";
+        }
+        infoWindow.__template = template.replace(/\s?ng-non-bindable[='"]+/,"");
+      });
+
+      infoWindow.__open = function(map, scope, anchor) {
+        templatePromise.then(function() {
+          $timeout(function() {
+            anchor && (scope.anchor = anchor);
+            var el = $compile(infoWindow.__template)(scope);
+            infoWindow.setContent(el[0]);
+            scope.$apply();
+            if (anchor && anchor.getPosition) {
+              infoWindow.open(map, anchor);
+            } else if (anchor && anchor instanceof google.maps.LatLng) {
+              infoWindow.open(map);
+              infoWindow.setPosition(anchor);
+            } else {
+              infoWindow.open(map);
+            }
+            var infoWindowContainerEl = infoWindow.content.parentElement.parentElement.parentElement;
+            infoWindowContainerEl.className = "ng-map-info-window";
+          });
+        });
+      };
+
+      return infoWindow;
+    };
+
+    var linkFunc = function(scope, element, attrs, mapController) {
+      mapController = mapController[0]||mapController[1];
+
+      element.css('display','none');
+
+      var orgAttrs = parser.orgAttributes(element);
+      var filtered = parser.filter(attrs);
+      var options = parser.getOptions(filtered, {scope: scope});
+      var events = parser.getEvents(scope, filtered);
+
+      var infoWindow = getInfoWindow(options, events, options.template || element);
+      var address;
+      if (options.position && !(options.position instanceof google.maps.LatLng)) {
+        address = options.position;
+      }
+      if (address) {
+        NgMap.getGeoLocation(address).then(function(latlng) {
+          infoWindow.setPosition(latlng);
+          infoWindow.__open(mapController.map, scope, latlng);
+          var geoCallback = attrs.geoCallback;
+          geoCallback && $parse(geoCallback)(scope);
+        });
+      }
+
+      mapController.addObject('infoWindows', infoWindow);
+      mapController.observeAttrSetObj(orgAttrs, attrs, infoWindow);
+
+      mapController.showInfoWindow =
+      mapController.map.showInfoWindow = mapController.showInfoWindow ||
+        function(p1, p2, p3) { //event, id, marker
+          var id = typeof p1 == 'string' ? p1 : p2;
+          var marker = typeof p1 == 'string' ? p2 : p3;
+          if (typeof marker == 'string') {
+            //Check if markers if defined to avoid odd 'undefined' errors
+            if (
+              typeof mapController.map.markers != "undefined"
+              && typeof mapController.map.markers[marker] != "undefined") {
+                marker = mapController.map.markers[marker];
+            } else if (
+              //additionally check if that marker is a custom marker
+              typeof mapController.map.customMarkers !== "undefined"
+              && typeof mapController.map.customMarkers[marker] !== "undefined") {
+                marker = mapController.map.customMarkers[marker];
+            } else {
+              //Better error output if marker with that id is not defined
+              throw new Error("Cant open info window for id " + marker + ". Marker or CustomMarker is not defined")
+            }
+          }
+
+          var infoWindow = mapController.map.infoWindows[id];
+          var anchor = marker ? marker : (this.getPosition ? this : null);
+          infoWindow.__open(mapController.map, scope, anchor);
+          if(mapController.singleInfoWindow) {
+            if(mapController.lastInfoWindow) {
+              scope.hideInfoWindow(mapController.lastInfoWindow);
+            }
+            mapController.lastInfoWindow = id;
+          }
+        };
+
+      mapController.hideInfoWindow =
+      mapController.map.hideInfoWindow = mapController.hideInfoWindow ||
+        function(p1, p2) {
+          var id = typeof p1 == 'string' ? p1 : p2;
+          var infoWindow = mapController.map.infoWindows[id];
+          infoWindow.close();
+        };
+
+      //TODO DEPRECATED
+      scope.showInfoWindow = mapController.map.showInfoWindow;
+      scope.hideInfoWindow = mapController.map.hideInfoWindow;
+
+      var map = infoWindow.mapId ? {id:infoWindow.mapId} : 0;
+      NgMap.getMap(map).then(function(map) {
+        infoWindow.visible && infoWindow.__open(map, scope);
+        if (infoWindow.visibleOnMarker) {
+          var markerId = infoWindow.visibleOnMarker;
+          infoWindow.__open(map, scope, map.markers[markerId]);
+        }
+      });
+
+    }; //link
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+      link: linkFunc
+    };
+
+  }; // infoWindow
+  infoWindow.$inject =
+    ['Attr2MapOptions', '$compile', '$q', '$templateRequest', '$timeout', '$parse', 'NgMap'];
+
+  angular.module('ngMap').directive('infoWindow', infoWindow);
+})();
+
+/**
+ * @ngdoc directive
+ * @name kml-layer
+ * @param Attr2MapOptions {service} convert html attribute to Google map api options
+ * @description
+ *   renders Kml layer on a map
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @attr {Url} url url of the kml layer
+ * @attr {KmlLayerOptions} KmlLayerOptions
+ *   (https://developers.google.com/maps/documentation/javascript/reference#KmlLayerOptions) 
+ * @attr {String} &lt;KmlLayerEvent> Any KmlLayer events,
+ *   https://developers.google.com/maps/documentation/javascript/reference
+ * @example
+ * Usage:
+ *   <map MAP_ATTRIBUTES>
+ *    <kml-layer ANY_KML_LAYER ANY_KML_LAYER_EVENTS"></kml-layer>
+ *   </map>
+ *
+ * Example:
+ *
+ * <map zoom="11" center="[41.875696,-87.624207]">
+ *   <kml-layer url="https://gmaps-samples.googlecode.com/svn/trunk/ggeoxml/cta.kml" >
+ *   </kml-layer>
+ * </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('kmlLayer', [
+    'Attr2MapOptions', function(Attr2MapOptions) {
+    var parser = Attr2MapOptions;
+
+    var getKmlLayer = function(options, events) {
+      var kmlLayer = new google.maps.KmlLayer(options);
+      for (var eventName in events) {
+        google.maps.event.addListener(kmlLayer, eventName, events[eventName]);
+      }
+      return kmlLayer;
+    };
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var orgAttrs = parser.orgAttributes(element);
+        var filtered = parser.filter(attrs);
+        var options = parser.getOptions(filtered, {scope: scope});
+        var events = parser.getEvents(scope, filtered);
+        void 0;
+
+        var kmlLayer = getKmlLayer(options, events);
+        mapController.addObject('kmlLayers', kmlLayer);
+        mapController.observeAttrSetObj(orgAttrs, attrs, kmlLayer);  //observers
+        element.bind('$destroy', function() {
+          mapController.deleteObject('kmlLayers', kmlLayer);
+        });
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name map-data
+ * @param Attr2MapOptions {service}
+ *   convert html attribute to Google map api options
+ * @description
+ *   set map data
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @wn {String} method-name, run map.data[method-name] with attribute value
+ * @example
+ * Example:
+ *
+ *  <map zoom="11" center="[41.875696,-87.624207]">
+ *    <map-data load-geo-json="https://storage.googleapis.com/maps-devrel/google.json"></map-data>
+ *   </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('mapData', [
+    'Attr2MapOptions', 'NgMap', function(Attr2MapOptions, NgMap) {
+    var parser = Attr2MapOptions;
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0] || mapController[1];
+        var filtered = parser.filter(attrs);
+        var options = parser.getOptions(filtered, {scope: scope});
+        var events = parser.getEvents(scope, filtered, events);
+
+        void 0;
+        NgMap.getMap(mapController.map.id).then(function(map) {
+          //options
+          for (var key in options) {
+            var val = options[key];
+            if (typeof scope[val] === "function") {
+              map.data[key](scope[val]);
+            } else {
+              map.data[key](val);
+            }
+          }
+
+          //events
+          for (var eventName in events) {
+            map.data.addListener(eventName, events[eventName]);
+          }
+        });
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name map-lazy-load
+ * @param Attr2Options {service} convert html attribute to Google map api options
+ * @description
+ *  Requires: Delay the initialization of map directive
+ *    until the map is ready to be rendered
+ *  Restrict To: Attribute
+ *
+ * @attr {String} map-lazy-load
+ *    Maps api script source file location.
+ *    Example:
+ *      'https://maps.google.com/maps/api/js'
+ * @attr {String} map-lazy-load-params
+ *   Maps api script source file location via angular scope variable.
+ *   Also requires the map-lazy-load attribute to be present in the directive.
+ *   Example: In your controller, set
+ *     $scope.googleMapsURL = 'https://maps.google.com/maps/api/js?v=3.20&client=XXXXXenter-api-key-hereXXXX'
+ *
+ * @example
+ * Example:
+ *
+ *   <div map-lazy-load="http://maps.google.com/maps/api/js">
+ *     <map center="Brampton" zoom="10">
+ *       <marker position="Brampton"></marker>
+ *     </map>
+ *   </div>
+ *
+ *   <div map-lazy-load="http://maps.google.com/maps/api/js"
+ *        map-lazy-load-params="{{googleMapsUrl}}">
+ *     <map center="Brampton" zoom="10">
+ *       <marker position="Brampton"></marker>
+ *     </map>
+ *   </div>
+ */
+/* global window, document */
+(function() {
+  'use strict';
+  var $timeout, $compile, src, savedHtml = [], elements = [];
+
+  var preLinkFunc = function(scope, element, attrs) {
+    var mapsUrl = attrs.mapLazyLoadParams || attrs.mapLazyLoad;
+
+    if(window.google === undefined || window.google.maps === undefined) {
+      elements.push({
+        scope: scope,
+        element: element,
+        savedHtml: savedHtml[elements.length],
+      });
+
+      window.lazyLoadCallback = function() {
+        void 0;
+        $timeout(function() { /* give some time to load */
+          elements.forEach(function(elm) {
+              elm.element.html(elm.savedHtml);
+              $compile(elm.element.contents())(elm.scope);
+          });
+        }, 100);
+      };
+
+      var scriptEl = document.createElement('script');
+      void 0;
+
+      scriptEl.src = mapsUrl +
+        (mapsUrl.indexOf('?') > -1 ? '&' : '?') +
+        'callback=lazyLoadCallback';
+
+        if (!document.querySelector('script[src="' + scriptEl.src + '"]')) {
+          document.body.appendChild(scriptEl);
+        }
+    } else {
+      element.html(savedHtml);
+      $compile(element.contents())(scope);
+    }
+  };
+
+  var compileFunc = function(tElement, tAttrs) {
+
+    (!tAttrs.mapLazyLoad) && void 0;
+    savedHtml.push(tElement.html());
+    src = tAttrs.mapLazyLoad;
+
+    /**
+     * if already loaded, stop processing it
+     */
+    if(window.google !== undefined && window.google.maps !== undefined) {
+      return false;
+    }
+
+    tElement.html('');  // will compile again after script is loaded
+
+    return {
+      pre: preLinkFunc
+    };
+  };
+
+  var mapLazyLoad = function(_$compile_, _$timeout_) {
+    $compile = _$compile_, $timeout = _$timeout_;
+    return {
+      compile: compileFunc
+    };
+  };
+  mapLazyLoad.$inject = ['$compile','$timeout'];
+
+  angular.module('ngMap').directive('mapLazyLoad', mapLazyLoad);
+})();
+
+/**
+ * @ngdoc directive
+ * @name map-type
+ * @param Attr2MapOptions {service} 
+ *   convert html attribute to Google map api options
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ * Example:
+ *
+ *   <map zoom="13" center="34.04924594193164, -118.24104309082031">
+ *     <map-type name="coordinate" object="coordinateMapType"></map-type>
+ *   </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('mapType', ['$parse', 'NgMap',
+    function($parse, NgMap) {
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var mapTypeName = attrs.name, mapTypeObject;
+        if (!mapTypeName) {
+          throw "invalid map-type name";
+        }
+        mapTypeObject = $parse(attrs.object)(scope);
+        if (!mapTypeObject) {
+          throw "invalid map-type object";
+        }
+
+        NgMap.getMap().then(function(map) {
+          map.mapTypes.set(mapTypeName, mapTypeObject);
+        });
+        mapController.addObject('mapTypes', mapTypeObject);
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @memberof ngMap
+ * @name ng-map
+ * @param Attr2Options {service}
+ *  convert html attribute to Google map api options
+ * @description
+ * Implementation of {@link __MapController}
+ * Initialize a Google map within a `<div>` tag
+ *   with given options and register events
+ *
+ * @attr {Expression} map-initialized
+ *   callback function when map is initialized
+ *   e.g., map-initialized="mycallback(map)"
+ * @attr {Expression} geo-callback if center is an address or current location,
+ *   the expression is will be executed when geo-lookup is successful.
+ *   e.g., geo-callback="showMyStoreInfo()"
+ * @attr {Array} geo-fallback-center
+ *   The center of map incase geolocation failed. i.e. [0,0]
+ * @attr {Object} geo-location-options
+ *  The navigator geolocation options.
+ *  e.g., { maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }.
+ *  If none specified, { timeout: 5000 }.
+ *  If timeout not specified, timeout: 5000 added
+ * @attr {Boolean} zoom-to-include-markers
+ *  When true, map boundary will be changed automatially
+ *  to include all markers when initialized
+ * @attr {Boolean} default-style
+ *  When false, the default styling,
+ *  `display:block;height:300px`, will be ignored.
+ * @attr {String} &lt;MapOption> Any Google map options,
+ *  https://developers.google.com/maps/documentation/javascript/reference?csw=1#MapOptions
+ * @attr {String} &lt;MapEvent> Any Google map events,
+ *  https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/map_events.html
+ * @attr {Boolean} single-info-window
+ *  When true the map will only display one info window at the time,
+ *  if not set or false,
+ *  everytime an info window is open it will be displayed with the othe one.
+ * @attr {Boolean} trigger-resize
+ *  Default to false.  Set to true to trigger resize of the map.  Needs to be done anytime you resize the map
+ * @example
+ * Usage:
+ *   <map MAP_OPTIONS_OR_MAP_EVENTS ..>
+ *     ... Any children directives
+ *   </map>
+ *
+ * Example:
+ *   <map center="[40.74, -74.18]" on-click="doThat()">
+ *   </map>
+ *
+ *   <map geo-fallback-center="[40.74, -74.18]" zoom-to-inlude-markers="true">
+ *   </map>
+ */
+(function () {
+  'use strict';
+
+  var mapDirective = function () {
+    return {
+      restrict: 'AE',
+      controller: '__MapController',
+      controllerAs: 'ngmap'
+    };
+  };
+
+  angular.module('ngMap').directive('map', [mapDirective]);
+  angular.module('ngMap').directive('ngMap', [mapDirective]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name maps-engine-layer
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ * Example:
+ *  <map zoom="14" center="[59.322506, 18.010025]">
+ *    <maps-engine-layer layer-id="06673056454046135537-08896501997766553811">
+ *    </maps-engine-layer>
+ *  </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('mapsEngineLayer', ['Attr2MapOptions', function(Attr2MapOptions) {
+    var parser = Attr2MapOptions;
+
+    var getMapsEngineLayer = function(options, events) {
+      var layer = new google.maps.visualization.MapsEngineLayer(options);
+
+      for (var eventName in events) {
+        google.maps.event.addListener(layer, eventName, events[eventName]);
+      }
+
+      return layer;
+    };
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var filtered = parser.filter(attrs);
+        var options = parser.getOptions(filtered, {scope: scope});
+        var events = parser.getEvents(scope, filtered, events);
+        void 0;
+
+        var layer = getMapsEngineLayer(options, events);
+        mapController.addObject('mapsEngineLayers', layer);
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name marker
+ * @param Attr2Options {service} convert html attribute to Google map api options
+ * @param NavigatorGeolocation It is used to find the current location
+ * @description
+ *  Draw a Google map marker on a map with given options and register events
+ *
+ *  Requires:  map directive
+ *
+ *  Restrict To:  Element
+ *
+ * @attr {String} position address, 'current', or [latitude, longitude]
+ *  example:
+ *    '1600 Pennsylvania Ave, 20500  Washingtion DC',
+ *    'current position',
+ *    '[40.74, -74.18]'
+ * @attr {Boolean} centered if set, map will be centered with this marker
+ * @attr {Expression} geo-callback if position is an address,
+ *   the expression is will be performed when geo-lookup is successful.
+ *   e.g., geo-callback="showStoreInfo()"
+ * @attr {Boolean} no-watcher if true, no attribute observer is added.
+ *   Useful for many ng-repeat
+ * @attr {String} &lt;MarkerOption>
+ *   [Any Marker options](https://developers.google.com/maps/documentation/javascript/reference?csw=1#MarkerOptions)
+ * @attr {String} &lt;MapEvent>
+ *   [Any Marker events](https://developers.google.com/maps/documentation/javascript/reference)
+ * @example
+ * Usage:
+ *   <map MAP_ATTRIBUTES>
+ *    <marker ANY_MARKER_OPTIONS ANY_MARKER_EVENTS"></MARKER>
+ *   </map>
+ *
+ * Example:
+ *   <map center="[40.74, -74.18]">
+ *    <marker position="[40.74, -74.18]" on-click="myfunc()"></div>
+ *   </map>
+ *
+ *   <map center="the cn tower">
+ *    <marker position="the cn tower" on-click="myfunc()"></div>
+ *   </map>
+ */
+/* global google */
+(function() {
+  'use strict';
+  var parser, $parse, NgMap;
+
+  var getMarker = function(options, events) {
+    var marker;
+
+    if (NgMap.defaultOptions.marker) {
+      for (var key in NgMap.defaultOptions.marker) {
+        if (typeof options[key] == 'undefined') {
+          void 0;
+          options[key] = NgMap.defaultOptions.marker[key];
+        }
+      }
+    }
+
+    if (!(options.position instanceof google.maps.LatLng)) {
+      options.position = new google.maps.LatLng(0,0);
+    }
+    marker = new google.maps.Marker(options);
+
+    /**
+     * set events
+     */
+    if (Object.keys(events).length > 0) {
+      void 0;
+    }
+    for (var eventName in events) {
+      if (eventName) {
+        google.maps.event.addListener(marker, eventName, events[eventName]);
+      }
+    }
+
+    return marker;
+  };
+
+  var linkFunc = function(scope, element, attrs, mapController) {
+    mapController = mapController[0]||mapController[1];
+
+    var orgAttrs = parser.orgAttributes(element);
+    var filtered = parser.filter(attrs);
+    var markerOptions = parser.getOptions(filtered, scope, {scope: scope});
+    var markerEvents = parser.getEvents(scope, filtered);
+    void 0;
+
+    var address;
+    if (!(markerOptions.position instanceof google.maps.LatLng)) {
+      address = markerOptions.position;
+    }
+    var marker = getMarker(markerOptions, markerEvents);
+    mapController.addObject('markers', marker);
+    if (address) {
+      NgMap.getGeoLocation(address).then(function(latlng) {
+        marker.setPosition(latlng);
+        markerOptions.centered && marker.map.setCenter(latlng);
+        var geoCallback = attrs.geoCallback;
+        geoCallback && $parse(geoCallback)(scope);
+      });
+    }
+
+    //set observers
+    mapController.observeAttrSetObj(orgAttrs, attrs, marker); /* observers */
+
+    element.bind('$destroy', function() {
+      mapController.deleteObject('markers', marker);
+    });
+  };
+
+  var marker = function(Attr2MapOptions, _$parse_, _NgMap_) {
+    parser = Attr2MapOptions;
+    $parse = _$parse_;
+    NgMap = _NgMap_;
+
+    return {
+      restrict: 'E',
+      require: ['^?map','?^ngMap'],
+      link: linkFunc
+    };
+  };
+
+  marker.$inject = ['Attr2MapOptions', '$parse', 'NgMap'];
+  angular.module('ngMap').directive('marker', marker);
+
+})();
+
+/**
+ * @ngdoc directive
+ * @name overlay-map-type
+ * @param Attr2MapOptions {service} convert html attribute to Google map api options
+ * @param $window {service}
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ * Example:
+ *
+ * <map zoom="13" center="34.04924594193164, -118.24104309082031">
+ *   <overlay-map-type index="0" object="coordinateMapType"></map-type>
+ * </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('overlayMapType', [
+    'NgMap', function(NgMap) {
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var initMethod = attrs.initMethod || "insertAt";
+        var overlayMapTypeObject = scope[attrs.object];
+
+        NgMap.getMap().then(function(map) {
+          if (initMethod == "insertAt") {
+            var index = parseInt(attrs.index, 10);
+            map.overlayMapTypes.insertAt(index, overlayMapTypeObject);
+          } else if (initMethod == "push") {
+            map.overlayMapTypes.push(overlayMapTypeObject);
+          }
+        });
+        mapController.addObject('overlayMapTypes', overlayMapTypeObject);
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name places-auto-complete
+ * @param Attr2MapOptions {service} convert html attribute to Google map api options
+ * @description
+ *   Provides address auto complete feature to an input element
+ *   Requires: input tag
+ *   Restrict To: Attribute
+ *
+ * @attr {AutoCompleteOptions}
+ *   [Any AutocompleteOptions](https://developers.google.com/maps/documentation/javascript/3.exp/reference#AutocompleteOptions)
+ *
+ * @example
+ * Example:
+ *   <script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
+ *   <input places-auto-complete types="['geocode']" on-place-changed="myCallback(place)" component-restrictions="{country:'au'}"/>
+ */
+/* global google */
+(function() {
+  'use strict';
+
+  var placesAutoComplete = function(Attr2MapOptions, $timeout) {
+    var parser = Attr2MapOptions;
+
+    var linkFunc = function(scope, element, attrs, ngModelCtrl) {
+      if (attrs.placesAutoComplete ==='false') {
+        return false;
+      }
+      var filtered = parser.filter(attrs);
+      var options = parser.getOptions(filtered, {scope: scope});
+      var events = parser.getEvents(scope, filtered);
+      var autocomplete = new google.maps.places.Autocomplete(element[0], options);
+      for (var eventName in events) {
+        google.maps.event.addListener(autocomplete, eventName, events[eventName]);
+      }
+
+      var updateModel = function() {
+        $timeout(function(){
+          ngModelCtrl && ngModelCtrl.$setViewValue(element.val());
+        },100);
+      };
+      google.maps.event.addListener(autocomplete, 'place_changed', updateModel);
+      element[0].addEventListener('change', updateModel);
+
+      attrs.$observe('types', function(val) {
+        if (val) {
+          var optionValue = parser.toOptionValue(val, {key: 'types'});
+          autocomplete.setTypes(optionValue);
+        }
+      });
+	  
+	  attrs.$observe('componentRestrictions', function (val) {
+		 if (val) {
+		   autocomplete.setComponentRestrictions(scope.$eval(val));
+		 }
+	   });
+    };
+	
+    return {
+      restrict: 'A',
+      require: '?ngModel',
+      link: linkFunc
+    };
+  };
+
+  placesAutoComplete.$inject = ['Attr2MapOptions', '$timeout'];
+  angular.module('ngMap').directive('placesAutoComplete', placesAutoComplete);
+})();
+
+/**
+ * @ngdoc directive
+ * @name shape
+ * @param Attr2MapOptions {service} convert html attribute to Google map api options
+ * @description
+ *   Initialize a Google map shape in map with given options and register events
+ *   The shapes are:
+ *     . circle
+ *     . polygon
+ *     . polyline
+ *     . rectangle
+ *     . groundOverlay(or image)
+ *
+ *   Requires:  map directive
+ *
+ *   Restrict To:  Element
+ *
+ * @attr {Boolean} centered if set, map will be centered with this marker
+ * @attr {Expression} geo-callback if shape is a circle and the center is
+ *   an address, the expression is will be performed when geo-lookup
+ *   is successful. e.g., geo-callback="showDetail()"
+ * @attr {String} &lt;OPTIONS>
+ *   For circle, [any circle options](https://developers.google.com/maps/documentation/javascript/reference#CircleOptions)
+ *   For polygon, [any polygon options](https://developers.google.com/maps/documentation/javascript/reference#PolygonOptions)
+ *   For polyline, [any polyline options](https://developers.google.com/maps/documentation/javascript/reference#PolylineOptions)
+ *   For rectangle, [any rectangle options](https://developers.google.com/maps/documentation/javascript/reference#RectangleOptions)
+ *   For image, [any groundOverlay options](https://developers.google.com/maps/documentation/javascript/reference#GroundOverlayOptions)
+ * @attr {String} &lt;MapEvent> [Any Shape events](https://developers.google.com/maps/documentation/javascript/reference)
+ * @example
+ * Usage:
+ *   <map MAP_ATTRIBUTES>
+ *    <shape name=SHAPE_NAME ANY_SHAPE_OPTIONS ANY_SHAPE_EVENTS"></MARKER>
+ *   </map>
+ *
+ * Example:
+ *
+ *   <map zoom="11" center="[40.74, -74.18]">
+ *     <shape id="polyline" name="polyline" geodesic="true"
+ *       stroke-color="#FF0000" stroke-opacity="1.0" stroke-weight="2"
+ *       path="[[40.74,-74.18],[40.64,-74.10],[40.54,-74.05],[40.44,-74]]" >
+ *     </shape>
+ *   </map>
+ *
+ *   <map zoom="11" center="[40.74, -74.18]">
+ *     <shape id="polygon" name="polygon" stroke-color="#FF0000"
+ *       stroke-opacity="1.0" stroke-weight="2"
+ *       paths="[[40.74,-74.18],[40.64,-74.18],[40.84,-74.08],[40.74,-74.18]]" >
+ *     </shape>
+ *   </map>
+ *
+ *   <map zoom="11" center="[40.74, -74.18]">
+ *     <shape id="rectangle" name="rectangle" stroke-color='#FF0000'
+ *       stroke-opacity="0.8" stroke-weight="2"
+ *       bounds="[[40.74,-74.18], [40.78,-74.14]]" editable="true" >
+ *     </shape>
+ *   </map>
+ *
+ *   <map zoom="11" center="[40.74, -74.18]">
+ *     <shape id="circle" name="circle" stroke-color='#FF0000'
+ *       stroke-opacity="0.8"stroke-weight="2"
+ *       center="[40.70,-74.14]" radius="4000" editable="true" >
+ *     </shape>
+ *   </map>
+ *
+ *   <map zoom="11" center="[40.74, -74.18]">
+ *     <shape id="image" name="image"
+ *       url="https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg"
+ *       bounds="[[40.71,-74.22],[40.77,-74.12]]" opacity="0.7"
+ *       clickable="true">
+ *     </shape>
+ *   </map>
+ *
+ *  For full-working example, please visit
+ *    [shape example](https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/shape.html)
+ */
+/* global google */
+(function() {
+  'use strict';
+
+  var getShape = function(options, events) {
+    var shape;
+
+    var shapeName = options.name;
+    delete options.name;  //remove name bcoz it's not for options
+    void 0;
+
+    /**
+     * set options
+     */
+    switch(shapeName) {
+      case "circle":
+        if (!(options.center instanceof google.maps.LatLng)) {
+          options.center = new google.maps.LatLng(0,0);
+        } 
+        shape = new google.maps.Circle(options);
+        break;
+      case "polygon":
+        shape = new google.maps.Polygon(options);
+        break;
+      case "polyline":
+        shape = new google.maps.Polyline(options);
+        break;
+      case "rectangle":
+        shape = new google.maps.Rectangle(options);
+        break;
+      case "groundOverlay":
+      case "image":
+        var url = options.url;
+        var opts = {opacity: options.opacity, clickable: options.clickable, id:options.id};
+        shape = new google.maps.GroundOverlay(url, options.bounds, opts);
+        break;
+    }
+
+    /**
+     * set events
+     */
+    for (var eventName in events) {
+      if (events[eventName]) {
+        google.maps.event.addListener(shape, eventName, events[eventName]);
+      }
+    }
+    return shape;
+  };
+
+  var shape = function(Attr2MapOptions, $parse, NgMap) {
+    var parser = Attr2MapOptions;
+
+    var linkFunc = function(scope, element, attrs, mapController) {
+      mapController = mapController[0]||mapController[1];
+
+      var orgAttrs = parser.orgAttributes(element);
+      var filtered = parser.filter(attrs);
+      var shapeOptions = parser.getOptions(filtered, {scope: scope});
+      var shapeEvents = parser.getEvents(scope, filtered);
+
+      var address, shapeType;
+      shapeType = shapeOptions.name;
+      if (!(shapeOptions.center instanceof google.maps.LatLng)) {
+        address = shapeOptions.center;
+      }
+      var shape = getShape(shapeOptions, shapeEvents);
+      mapController.addObject('shapes', shape);
+
+      if (address && shapeType == 'circle') {
+        NgMap.getGeoLocation(address).then(function(latlng) {
+          shape.setCenter(latlng);
+          shape.centered && shape.map.setCenter(latlng);
+          var geoCallback = attrs.geoCallback;
+          geoCallback && $parse(geoCallback)(scope);
+        });
+      }
+
+      //set observers
+      mapController.observeAttrSetObj(orgAttrs, attrs, shape);
+      element.bind('$destroy', function() {
+        mapController.deleteObject('shapes', shape);
+      });
+    };
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+      link: linkFunc
+     }; // return
+  };
+  shape.$inject = ['Attr2MapOptions', '$parse', 'NgMap'];
+
+  angular.module('ngMap').directive('shape', shape);
+
+})();
+
+/**
+ * @ngdoc directive
+ * @name streetview-panorama
+ * @param Attr2MapOptions {service} convert html attribute to Google map api options
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @attr container Optional, id or css selector, if given, streetview will be in the given html element
+ * @attr {String} &lt;StreetViewPanoramaOption>
+ *   [Any Google StreetViewPanorama options](https://developers.google.com/maps/documentation/javascript/reference?csw=1#StreetViewPanoramaOptions)
+ * @attr {String} &lt;StreetViewPanoramaEvent>
+ *   [Any Google StreetViewPanorama events](https://developers.google.com/maps/documentation/javascript/reference#StreetViewPanorama)
+ *
+ * @example
+ *   <map zoom="11" center="[40.688738,-74.043871]" >
+ *     <street-view-panorama
+ *       click-to-go="true"
+ *       disable-default-ui="true"
+ *       disable-double-click-zoom="true"
+ *       enable-close-button="true"
+ *       pano="my-pano"
+ *       position="40.688738,-74.043871"
+ *       pov="{heading:0, pitch: 90}"
+ *       scrollwheel="false"
+ *       visible="true">
+ *     </street-view-panorama>
+ *   </map>
+ */
+/* global google, document */
+(function() {
+  'use strict';
+
+  var streetViewPanorama = function(Attr2MapOptions, NgMap) {
+    var parser = Attr2MapOptions;
+
+    var getStreetViewPanorama = function(map, options, events) {
+      var svp, container;
+      if (options.container) {
+        container = document.getElementById(options.container);
+        container = container || document.querySelector(options.container);
+      }
+      if (container) {
+        svp = new google.maps.StreetViewPanorama(container, options);
+      } else {
+        svp = map.getStreetView();
+        svp.setOptions(options);
+      }
+
+      for (var eventName in events) {
+        eventName &&
+          google.maps.event.addListener(svp, eventName, events[eventName]);
+      }
+      return svp;
+    };
+
+    var linkFunc = function(scope, element, attrs) {
+      var filtered = parser.filter(attrs);
+      var options = parser.getOptions(filtered, {scope: scope});
+      var controlOptions = parser.getControlOptions(filtered);
+      var svpOptions = angular.extend(options, controlOptions);
+
+      var svpEvents = parser.getEvents(scope, filtered);
+      void 0;
+
+      NgMap.getMap().then(function(map) {
+        var svp = getStreetViewPanorama(map, svpOptions, svpEvents);
+
+        map.setStreetView(svp);
+        (!svp.getPosition()) && svp.setPosition(map.getCenter());
+        google.maps.event.addListener(svp, 'position_changed', function() {
+          if (svp.getPosition() !== map.getCenter()) {
+            map.setCenter(svp.getPosition());
+          }
+        });
+        //needed for geo-callback
+        var listener =
+          google.maps.event.addListener(map, 'center_changed', function() {
+            svp.setPosition(map.getCenter());
+            google.maps.event.removeListener(listener);
+          });
+      });
+
+    }; //link
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+      link: linkFunc
+    };
+
+  };
+  streetViewPanorama.$inject = ['Attr2MapOptions', 'NgMap'];
+
+  angular.module('ngMap').directive('streetViewPanorama', streetViewPanorama);
+})();
+
+/**
+ * @ngdoc directive
+ * @name traffic-layer
+ * @param Attr2MapOptions {service} convert html attribute to Google map api options
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ * Example:
+ *
+ *   <map zoom="13" center="34.04924594193164, -118.24104309082031">
+ *     <traffic-layer></traffic-layer>
+ *    </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('trafficLayer', [
+    'Attr2MapOptions', function(Attr2MapOptions) {
+    var parser = Attr2MapOptions;
+
+    var getLayer = function(options, events) {
+      var layer = new google.maps.TrafficLayer(options);
+      for (var eventName in events) {
+        google.maps.event.addListener(layer, eventName, events[eventName]);
+      }
+      return layer;
+    };
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var orgAttrs = parser.orgAttributes(element);
+        var filtered = parser.filter(attrs);
+        var options = parser.getOptions(filtered, {scope: scope});
+        var events = parser.getEvents(scope, filtered);
+        void 0;
+
+        var layer = getLayer(options, events);
+        mapController.addObject('trafficLayers', layer);
+        mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers
+        element.bind('$destroy', function() {
+          mapController.deleteObject('trafficLayers', layer);
+        });
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc directive
+ * @name transit-layer
+ * @param Attr2MapOptions {service} convert html attribute to Google map api options
+ * @description
+ *   Requires:  map directive
+ *   Restrict To:  Element
+ *
+ * @example
+ * Example:
+ *
+ *  <map zoom="13" center="34.04924594193164, -118.24104309082031">
+ *    <transit-layer></transit-layer>
+ *  </map>
+ */
+(function() {
+  'use strict';
+
+  angular.module('ngMap').directive('transitLayer', [
+    'Attr2MapOptions', function(Attr2MapOptions) {
+    var parser = Attr2MapOptions;
+
+    var getLayer = function(options, events) {
+      var layer = new google.maps.TransitLayer(options);
+      for (var eventName in events) {
+        google.maps.event.addListener(layer, eventName, events[eventName]);
+      }
+      return layer;
+    };
+
+    return {
+      restrict: 'E',
+      require: ['?^map','?^ngMap'],
+
+      link: function(scope, element, attrs, mapController) {
+        mapController = mapController[0]||mapController[1];
+
+        var orgAttrs = parser.orgAttributes(element);
+        var filtered = parser.filter(attrs);
+        var options = parser.getOptions(filtered, {scope: scope});
+        var events = parser.getEvents(scope, filtered);
+        void 0;
+
+        var layer = getLayer(options, events);
+        mapController.addObject('transitLayers', layer);
+        mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers
+        element.bind('$destroy', function() {
+          mapController.deleteObject('transitLayers', layer);
+        });
+      }
+     }; // return
+  }]);
+})();
+
+/**
+ * @ngdoc filter
+ * @name camel-case
+ * @description
+ *   Converts string to camel cased
+ */
+(function() {
+  'use strict';
+
+  var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
+  var MOZ_HACK_REGEXP = /^moz([A-Z])/;
+
+  var camelCaseFilter = function() {
+    return function(name) {
+      return name.
+        replace(SPECIAL_CHARS_REGEXP,
+          function(_, separator, letter, offset) {
+            return offset ? letter.toUpperCase() : letter;
+        }).
+        replace(MOZ_HACK_REGEXP, 'Moz$1');
+    };
+  };
+
+  angular.module('ngMap').filter('camelCase', camelCaseFilter);
+})();
+
+/**
+ * @ngdoc filter
+ * @name escape-regex
+ * @description
+ *   Escapes all regex special characters in a string
+ */
+(function() {
+  'use strict';
+
+
+
+  var escapeRegexpFilter = function() {
+    return function(string) {
+			return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+		};
+  };
+
+  angular.module('ngMap').filter('escapeRegexp', escapeRegexpFilter);
+})();
+
+/**
+ * @ngdoc filter
+ * @name jsonize
+ * @description
+ *   Converts json-like string to json string
+ */
+(function() {
+  'use strict';
+
+  var jsonizeFilter = function() {
+    return function(str) {
+      try {       // if parsable already, return as it is
+        JSON.parse(str);
+        return str;
+      } catch(e) { // if not parsable, change little
+        return str
+          // wrap keys without quote with valid double quote
+          .replace(/([\$\w]+)\s*:/g,
+            function(_, $1) {
+              return '"'+$1+'":';
+            }
+          )
+          // replacing single quote wrapped ones to double quote
+          .replace(/'([^']+)'/g,
+            function(_, $1) {
+              return '"'+$1+'"';
+            }
+          )
+          .replace(/''/g, '""');
+      }
+    };
+  };
+
+  angular.module('ngMap').filter('jsonize', jsonizeFilter);
+})();
+
+/**
+ * @ngdoc service
+ * @name Attr2MapOptions
+ * @description
+ *   Converts tag attributes to options used by google api v3 objects
+ */
+/* global google */
+(function() {
+  'use strict';
+
+  //i.e. "2015-08-12T06:12:40.858Z"
+  var isoDateRE =
+    /^(\d{4}\-\d\d\-\d\d([tT][\d:\.]*)?)([zZ]|([+\-])(\d\d):?(\d\d))?$/;
+
+  var Attr2MapOptions = function(
+      $parse, $timeout, $log, $interpolate, NavigatorGeolocation, GeoCoder,
+      camelCaseFilter, jsonizeFilter, escapeRegExp
+    ) {
+
+    var exprStartSymbol = $interpolate.startSymbol();
+    var exprEndSymbol = $interpolate.endSymbol();
+
+    /**
+     * Returns the attributes of an element as hash
+     * @memberof Attr2MapOptions
+     * @param {HTMLElement} el html element
+     * @returns {Hash} attributes
+     */
+    var orgAttributes = function(el) {
+      (el.length > 0) && (el = el[0]);
+      var orgAttributes = {};
+      for (var i=0; i<el.attributes.length; i++) {
+        var attr = el.attributes[i];
+        orgAttributes[attr.name] = attr.value;
+      }
+      return orgAttributes;
+    };
+
+    var getJSON = function(input) {
+      var re =/^[\+\-]?[0-9\.]+,[ ]*\ ?[\+\-]?[0-9\.]+$/; //lat,lng
+      if (input.match(re)) {
+        input = "["+input+"]";
+      }
+      return JSON.parse(jsonizeFilter(input));
+    };
+    
+    var getLatLng = function(input) {
+      var output = input;
+      if (input[0].constructor == Array) { 
+        if ((input[0][0].constructor == Array && input[0][0].length == 2) || input[0][0].constructor == Object) {
+            var preoutput;
+            var outputArray = [];
+            for (var i = 0; i < input.length; i++) {
+                preoutput = input[i].map(function(el){
+                    return new google.maps.LatLng(el[0], el[1]);
+                });
+                outputArray.push(preoutput);
+            }
+            output = outputArray;
+        } else {
+            output = input.map(function(el) {
+                return new google.maps.LatLng(el[0], el[1]);
+            });
+        }
+      } else if (!isNaN(parseFloat(input[0])) && isFinite(input[0])) {
+        output = new google.maps.LatLng(output[0], output[1]);
+      }
+      return output;
+    };
+
+    var toOptionValue = function(input, options) {
+      var output;
+      try { // 1. Number?
+        output = getNumber(input);
+      } catch(err) {
+        try { // 2. JSON?
+          var output = getJSON(input);
+          if (output instanceof Array) {
+            if (output[0].constructor == Object) {
+              output = output;
+            } else if (output[0] instanceof Array) {
+              if (output[0][0].constructor == Object) {
+                output = output;
+              } else {
+                output = getLatLng(output);
+              }
+            } else {
+                output = getLatLng(output);
+            }
+          }
+          // JSON is an object (not array or null)
+          else if (output === Object(output)) {
+            // check for nested hashes and convert to Google API options
+            var newOptions = options;
+            newOptions.doNotConverStringToNumber = true;
+            output = getOptions(output, newOptions);
+          }
+        } catch(err2) {
+          // 3. Google Map Object function Expression. i.e. LatLng(80,-49)
+          if (input.match(/^[A-Z][a-zA-Z0-9]+\(.*\)$/)) {
+            try {
+              var exp = "new google.maps."+input;
+              output = eval(exp); /* jshint ignore:line */
+            } catch(e) {
+              output = input;
+            }
+          // 4. Google Map Object constant Expression. i.e. MayTypeId.HYBRID
+          } else if (input.match(/^([A-Z][a-zA-Z0-9]+)\.([A-Z]+)$/)) {
+            try {
+              var matches = input.match(/^([A-Z][a-zA-Z0-9]+)\.([A-Z]+)$/);
+              output = google.maps[matches[1]][matches[2]];
+            } catch(e) {
+              output = input;
+            }
+          // 5. Google Map Object constant Expression. i.e. HYBRID
+          } else if (input.match(/^[A-Z]+$/)) {
+            try {
+              var capitalizedKey = options.key.charAt(0).toUpperCase() +
+                options.key.slice(1);
+              if (options.key.match(/temperatureUnit|windSpeedUnit|labelColor/)) {
+                capitalizedKey = capitalizedKey.replace(/s$/,"");
+                output = google.maps.weather[capitalizedKey][input];
+              } else {
+                output = google.maps[capitalizedKey][input];
+              }
+            } catch(e) {
+              output = input;
+            }
+          // 6. Date Object as ISO String
+          } else if (input.match(isoDateRE)) {
+            try {
+              output = new Date(input);
+            } catch(e) {
+              output = input;
+            }
+          // 7. evaluate dynamically bound values
+        } else if (input.match(new RegExp('^' + escapeRegExp(exprStartSymbol))) && options.scope) {
+            try {
+              var expr = input.replace(new RegExp(escapeRegExp(exprStartSymbol)),'').replace(new RegExp(escapeRegExp(exprEndSymbol), 'g'),'');
+              output = options.scope.$eval(expr);
+            } catch (err) {
+              output = input;
+            }
+          } else {
+            output = input;
+          }
+        } // catch(err2)
+      } // catch(err)
+
+      // convert output more for center and position
+      if (
+        (options.key == 'center' || options.key == 'position') &&
+        output instanceof Array
+      ) {
+        output = new google.maps.LatLng(output[0], output[1]);
+      }
+
+      // convert output more for shape bounds
+      if (options.key == 'bounds' && output instanceof Array) {
+        output = new google.maps.LatLngBounds(output[0], output[1]);
+      }
+
+      // convert output more for shape icons
+      if (options.key == 'icons' && output instanceof Array) {
+
+        for (var i=0; i<output.length; i++) {
+          var el = output[i];
+          if (el.icon.path.match(/^[A-Z_]+$/)) {
+            el.icon.path =  google.maps.SymbolPath[el.icon.path];
+          }
+        }
+      }
+
+      // convert output more for marker icon
+      if (options.key == 'icon' && output instanceof Object) {
+        if ((""+output.path).match(/^[A-Z_]+$/)) {
+          output.path = google.maps.SymbolPath[output.path];
+        }
+        for (var key in output) { //jshint ignore:line
+          var arr = output[key];
+          if (key == "anchor" || key == "origin" || key == "labelOrigin") {
+            output[key] = new google.maps.Point(arr[0], arr[1]);
+          } else if (key == "size" || key == "scaledSize") {
+            output[key] = new google.maps.Size(arr[0], arr[1]);
+          }
+        }
+      }
+
+      return output;
+    };
+
+    var getAttrsToObserve = function(attrs) {
+      var attrsToObserve = [];
+      var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '.*' + escapeRegExp(exprEndSymbol), 'g');
+
+      if (!attrs.noWatcher) {
+        for (var attrName in attrs) { //jshint ignore:line
+          var attrValue = attrs[attrName];
+          if (attrValue && attrValue.match(exprRegExp)) { // if attr value is {{..}}
+            attrsToObserve.push(camelCaseFilter(attrName));
+          }
+        }
+      }
+
+      return attrsToObserve;
+    };
+
+    /**
+     * filters attributes by skipping angularjs methods $.. $$..
+     * @memberof Attr2MapOptions
+     * @param {Hash} attrs tag attributes
+     * @returns {Hash} filterd attributes
+     */
+    var filter = function(attrs) {
+      var options = {};
+      for(var key in attrs) {
+        if (key.match(/^\$/) || key.match(/^ng[A-Z]/)) {
+          void(0);
+        } else {
+          options[key] = attrs[key];
+        }
+      }
+      return options;
+    };
+
+    /**
+     * converts attributes hash to Google Maps API v3 options
+     * ```
+     *  . converts numbers to number
+     *  . converts class-like string to google maps instance
+     *    i.e. `LatLng(1,1)` to `new google.maps.LatLng(1,1)`
+     *  . converts constant-like string to google maps constant
+     *    i.e. `MapTypeId.HYBRID` to `google.maps.MapTypeId.HYBRID`
+     *    i.e. `HYBRID"` to `google.maps.MapTypeId.HYBRID`
+     * ```
+     * @memberof Attr2MapOptions
+     * @param {Hash} attrs tag attributes
+     * @param {Hash} options
+     * @returns {Hash} options converted attributess
+     */
+    var getOptions = function(attrs, params) {
+      params = params || {};
+      var options = {};
+      for(var key in attrs) {
+        if (attrs[key] || attrs[key] === 0) {
+          if (key.match(/^on[A-Z]/)) { //skip events, i.e. on-click
+            continue;
+          } else if (key.match(/ControlOptions$/)) { // skip controlOptions
+            continue;
+          } else {
+            // nested conversions need to be typechecked
+            // (non-strings are fully converted)
+            if (typeof attrs[key] !== 'string') {
+              options[key] = attrs[key];
+            } else {
+              if (params.doNotConverStringToNumber &&
+                attrs[key].match(/^[0-9]+$/)
+              ) {
+                options[key] = attrs[key];
+              } else {
+                options[key] = toOptionValue(attrs[key], {key: key, scope: params.scope});
+              }
+            }
+          }
+        } // if (attrs[key])
+      } // for(var key in attrs)
+      return options;
+    };
+
+    /**
+     * converts attributes hash to scope-specific event function
+     * @memberof Attr2MapOptions
+     * @param {scope} scope angularjs scope
+     * @param {Hash} attrs tag attributes
+     * @returns {Hash} events converted events
+     */
+    var getEvents = function(scope, attrs) {
+      var events = {};
+      var toLowercaseFunc = function($1){
+        return "_"+$1.toLowerCase();
+      };
+      var EventFunc = function(attrValue) {
+        // funcName(argsStr)
+        var matches = attrValue.match(/([^\(]+)\(([^\)]*)\)/);
+        var funcName = matches[1];
+        var argsStr = matches[2].replace(/event[ ,]*/,'');  //remove string 'event'
+        var argsExpr = $parse("["+argsStr+"]"); //for perf when triggering event
+        return function(event) {
+          var args = argsExpr(scope); //get args here to pass updated model values
+          function index(obj,i) {return obj[i];}
+          var f = funcName.split('.').reduce(index, scope);
+          f && f.apply(this, [event].concat(args));
+          $timeout( function() {
+            scope.$apply();
+          });
+        };
+      };
+
+      for(var key in attrs) {
+        if (attrs[key]) {
+          if (!key.match(/^on[A-Z]/)) { //skip if not events
+            continue;
+          }
+
+          //get event name as underscored. i.e. zoom_changed
+          var eventName = key.replace(/^on/,'');
+          eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1);
+          eventName = eventName.replace(/([A-Z])/g, toLowercaseFunc);
+
+          var attrValue = attrs[key];
+          events[eventName] = new EventFunc(attrValue);
+        }
+      }
+      return events;
+    };
+
+    /**
+     * control means map controls, i.e streetview, pan, etc, not a general control
+     * @memberof Attr2MapOptions
+     * @param {Hash} filtered filtered tag attributes
+     * @returns {Hash} Google Map options
+     */
+    var getControlOptions = function(filtered) {
+      var controlOptions = {};
+      if (typeof filtered != 'object') {
+        return false;
+      }
+
+      for (var attr in filtered) {
+        if (filtered[attr]) {
+          if (!attr.match(/(.*)ControlOptions$/)) {
+            continue; // if not controlOptions, skip it
+          }
+
+          //change invalid json to valid one, i.e. {foo:1} to {"foo": 1}
+          var orgValue = filtered[attr];
+          var newValue = orgValue.replace(/'/g, '"');
+          newValue = newValue.replace(/([^"]+)|("[^"]+")/g, function($0, $1, $2) {
+            if ($1) {
+              return $1.replace(/([a-zA-Z0-9]+?):/g, '"$1":');
+            } else {
+              return $2;
+            }
+          });
+          try {
+            var options = JSON.parse(newValue);
+            for (var key in options) { //assign the right values
+              if (options[key]) {
+                var value = options[key];
+                if (typeof value === 'string') {
+                  value = value.toUpperCase();
+                } else if (key === "mapTypeIds") {
+                  value = value.map( function(str) {
+                    if (str.match(/^[A-Z]+$/)) { // if constant
+                      return google.maps.MapTypeId[str.toUpperCase()];
+                    } else { // else, custom map-type
+                      return str;
+                    }
+                  });
+                }
+
+                if (key === "style") {
+                  var str = attr.charAt(0).toUpperCase() + attr.slice(1);
+                  var objName = str.replace(/Options$/,'')+"Style";
+                  options[key] = google.maps[objName][value];
+                } else if (key === "position") {
+                  options[key] = google.maps.ControlPosition[value];
+                } else {
+                  options[key] = value;
+                }
+              }
+            }
+            controlOptions[attr] = options;
+          } catch (e) {
+            void 0;
+          }
+        }
+      } // for
+
+      return controlOptions;
+    };
+
+    return {
+      filter: filter,
+      getOptions: getOptions,
+      getEvents: getEvents,
+      getControlOptions: getControlOptions,
+      toOptionValue: toOptionValue,
+      getAttrsToObserve: getAttrsToObserve,
+      orgAttributes: orgAttributes
+    }; // return
+
+  };
+  Attr2MapOptions.$inject= [
+    '$parse', '$timeout', '$log', '$interpolate', 'NavigatorGeolocation', 'GeoCoder',
+    'camelCaseFilter', 'jsonizeFilter', 'escapeRegexpFilter'
+  ];
+
+  angular.module('ngMap').service('Attr2MapOptions', Attr2MapOptions);
+})();
+
+/**
+ * @ngdoc service
+ * @name GeoCoder
+ * @description
+ *   Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)
+ *   service for Google Geocoder service
+ */
+(function() {
+  'use strict';
+  var $q;
+  /**
+   * @memberof GeoCoder
+   * @param {Hash} options
+   *   https://developers.google.com/maps/documentation/geocoding/#geocoding
+   * @example
+   * ```
+   *   GeoCoder.geocode({address: 'the cn tower'}).then(function(result) {
+   *     //... do something with result
+   *   });
+   * ```
+   * @returns {HttpPromise} Future object
+   */
+  var geocodeFunc = function(options) {
+    var deferred = $q.defer();
+    var geocoder = new google.maps.Geocoder();
+    geocoder.geocode(options, function (results, status) {
+      if (status == google.maps.GeocoderStatus.OK) {
+        deferred.resolve(results);
+      } else {
+        deferred.reject(status);
+      }
+    });
+    return deferred.promise;
+  };
+
+  var GeoCoder = function(_$q_) {
+    $q = _$q_;
+    return {
+      geocode : geocodeFunc
+    };
+  };
+  GeoCoder.$inject = ['$q'];
+
+  angular.module('ngMap').service('GeoCoder', GeoCoder);
+})();
+
+/**
+ * @ngdoc service
+ * @name GoogleMapsApi
+ * @description
+ *   Load Google Maps API Service
+ */
+(function() {
+  'use strict';
+  var $q;
+  var $timeout;
+
+  var GoogleMapsApi = function(_$q_, _$timeout_) {
+    $q = _$q_;
+    $timeout = _$timeout_;
+
+    return {
+
+      /**
+       * Load google maps into document by creating a script tag
+       * @memberof GoogleMapsApi
+       * @param {string} mapsUrl
+       * @example
+       *   GoogleMapsApi.load(myUrl).then(function() {
+       *     console.log('google map has been loaded')
+       *   });
+       */
+      load: function (mapsUrl) {
+
+        var deferred = $q.defer();
+
+        if (window.google === undefined || window.google.maps === undefined) {
+
+          window.lazyLoadCallback = function() {
+            $timeout(function() { /* give some time to load */
+              deferred.resolve(window.google)
+            }, 100);
+          };
+
+          var scriptEl = document.createElement('script');
+          scriptEl.src = mapsUrl +
+            (mapsUrl.indexOf('?') > -1 ? '&' : '?') +
+            'callback=lazyLoadCallback';
+
+          if (!document.querySelector('script[src="' + scriptEl.src + '"]')) {
+            document.body.appendChild(scriptEl);
+          }
+        } else {
+          deferred.resolve(window.google)
+        }
+
+        return deferred.promise;
+      }
+
+    }
+  }
+  GoogleMapsApi.$inject = ['$q', '$timeout'];
+
+  angular.module('ngMap').service('GoogleMapsApi', GoogleMapsApi);
+})();
+
+
+
+/**
+ * @ngdoc service
+ * @name NavigatorGeolocation
+ * @description
+ *  Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)
+ *  service for navigator.geolocation methods
+ */
+/* global google */
+(function() {
+  'use strict';
+  var $q;
+
+  /**
+   * @memberof NavigatorGeolocation
+   * @param {Object} geoLocationOptions the navigator geolocations options.
+   *  i.e. { maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }.
+   *  If none specified, { timeout: 5000 }. 
+   *  If timeout not specified, timeout: 5000 added
+   * @param {function} success success callback function
+   * @param {function} failure failure callback function
+   * @example
+   * ```
+   *  NavigatorGeolocation.getCurrentPosition()
+   *    .then(function(position) {
+   *      var lat = position.coords.latitude, lng = position.coords.longitude;
+   *      .. do something lat and lng
+   *    });
+   * ```
+   * @returns {HttpPromise} Future object
+   */
+  var getCurrentPosition = function(geoLocationOptions) {
+    var deferred = $q.defer();
+    if (navigator.geolocation) {
+
+      if (geoLocationOptions === undefined) {
+        geoLocationOptions = { timeout: 5000 };
+      }
+      else if (geoLocationOptions.timeout === undefined) {
+        geoLocationOptions.timeout = 5000;
+      }
+
+      navigator.geolocation.getCurrentPosition(
+        function(position) {
+          deferred.resolve(position);
+        }, function(evt) {
+          void 0;
+          deferred.reject(evt);
+        },
+        geoLocationOptions
+      );
+    } else {
+      deferred.reject("Browser Geolocation service failed.");
+    }
+    return deferred.promise;
+  };
+
+  var NavigatorGeolocation = function(_$q_) {
+    $q = _$q_;
+    return {
+      getCurrentPosition: getCurrentPosition
+    };
+  };
+  NavigatorGeolocation.$inject = ['$q'];
+
+  angular.module('ngMap').
+    service('NavigatorGeolocation', NavigatorGeolocation);
+})();
+
+/**
+ * @ngdoc factory
+ * @name NgMapPool
+ * @description
+ *   Provide map instance to avoid memory leak
+ */
+(function() {
+  'use strict';
+  /**
+   * @memberof NgMapPool
+   * @desc map instance pool
+   */
+  var mapInstances = [];
+  var $window, $document, $timeout;
+
+  var add = function(el) {
+    var mapDiv = $document.createElement("div");
+    mapDiv.style.width = "100%";
+    mapDiv.style.height = "100%";
+    el.appendChild(mapDiv);
+    var map = new $window.google.maps.Map(mapDiv, {});
+    mapInstances.push(map);
+    return map;
+  };
+
+  var findById = function(el, id) {
+    var notInUseMap;
+    for (var i=0; i<mapInstances.length; i++) {
+      var map = mapInstances[i];
+      if (map.id == id && !map.inUse) {
+        var mapDiv = map.getDiv();
+        el.appendChild(mapDiv);
+        notInUseMap = map;
+        break;
+      }
+    }
+    return notInUseMap;
+  };
+
+  var findUnused = function(el) { //jshint ignore:line
+    var notInUseMap;
+    for (var i=0; i<mapInstances.length; i++) {
+      var map = mapInstances[i];
+      if (map.id) {
+        continue;
+      }
+      if (!map.inUse) {
+        var mapDiv = map.getDiv();
+        el.appendChild(mapDiv);
+        notInUseMap = map;
+        break;
+      }
+    }
+    return notInUseMap;
+  };
+
+  /**
+   * @memberof NgMapPool
+   * @function getMapInstance
+   * @param {HtmlElement} el map container element
+   * @return map instance for the given element
+   */
+  var getMapInstance = function(el) {
+    var map = findById(el, el.id) || findUnused(el);
+    if (!map) {
+      map = add(el);
+    } else {
+      /* firing map idle event, which is used by map controller */
+      $timeout(function() {
+        google.maps.event.trigger(map, 'idle');
+      }, 100);
+    }
+    map.inUse = true;
+    return map;
+  };
+
+  /**
+   * @memberof NgMapPool
+   * @function returnMapInstance
+   * @param {Map} an instance of google.maps.Map
+   * @desc sets the flag inUse of the given map instance to false, so that it 
+   * can be reused later
+   */
+  var returnMapInstance = function(map) {
+    map.inUse = false;
+  };
+  
+  /**
+   * @memberof NgMapPool
+   * @function resetMapInstances
+   * @desc resets mapInstance array
+   */
+  var resetMapInstances = function() {
+    for(var i = 0;i < mapInstances.length;i++) {
+        mapInstances[i] = null;
+    }
+    mapInstances = [];
+  };
+  
+  /**
+   * @memberof NgMapPool
+   * @function deleteMapInstance
+   * @desc delete a mapInstance
+   */
+  var deleteMapInstance= function(mapId) {
+	  for( var i=0; i<mapInstances.length; i++ ) {
+		  if( (mapInstances[i] !== null) && (mapInstances[i].id == mapId)) {
+			  mapInstances[i]= null;
+			  mapInstances.splice( i, 1 );
+		  }
+	  }
+  };
+
+  var NgMapPool = function(_$document_, _$window_, _$timeout_) {
+    $document = _$document_[0], $window = _$window_, $timeout = _$timeout_;
+
+    return {
+	  mapInstances: mapInstances,
+      resetMapInstances: resetMapInstances,
+      getMapInstance: getMapInstance,
+      returnMapInstance: returnMapInstance,
+      deleteMapInstance: deleteMapInstance
+    };
+  };
+
+  NgMapPool.$inject = [ '$document', '$window', '$timeout'];
+
+  angular.module('ngMap').factory('NgMapPool', NgMapPool);
+
+})();
+
+/**
+ * @ngdoc provider
+ * @name NgMap
+ * @description
+ *  common utility service for ng-map
+ */
+(function() {
+  'use strict';
+  var $window, $document, $q;
+  var NavigatorGeolocation, Attr2MapOptions, GeoCoder, camelCaseFilter, NgMapPool;
+
+  var mapControllers = {};
+
+  var getStyle = function(el, styleProp) {
+    var y;
+    if (el.currentStyle) {
+      y = el.currentStyle[styleProp];
+    } else if ($window.getComputedStyle) {
+      y = $document.defaultView.
+        getComputedStyle(el, null).
+        getPropertyValue(styleProp);
+    }
+    return y;
+  };
+
+  /**
+   * @memberof NgMap
+   * @function initMap
+   * @param id optional, id of the map. default 0
+   */
+  var initMap = function(id) {
+    var ctrl = mapControllers[id || 0];
+    if (!(ctrl.map instanceof google.maps.Map)) {
+      ctrl.initializeMap();
+      return ctrl.map;
+    } else {
+      void 0;
+    }
+  };
+
+  /**
+   * @memberof NgMap
+   * @function getMap
+   * @param {String} optional, id e.g., 'foo'
+   * @returns promise
+   */
+  var getMap = function(id, options) {
+    options = options || {};
+    id = typeof id === 'object' ? id.id : id;
+
+    var deferred = $q.defer();
+    var timeout = options.timeout || 10000;
+
+    function waitForMap(timeElapsed){
+      var keys = Object.keys(mapControllers);
+      var theFirstController = mapControllers[keys[0]];
+      if(id && mapControllers[id]){
+        deferred.resolve(mapControllers[id].map);
+      } else if (!id && theFirstController && theFirstController.map) {
+        deferred.resolve(theFirstController.map);
+      } else if (timeElapsed > timeout) {
+        deferred.reject('could not find map');
+      } else {
+        $window.setTimeout( function(){
+          waitForMap(timeElapsed+100);
+        }, 100);
+      }
+    }
+    waitForMap(0);
+
+    return deferred.promise;
+  };
+
+  /**
+   * @memberof NgMap
+   * @function addMap
+   * @param mapController {__MapContoller} a map controller
+   * @returns promise
+   */
+  var addMap = function(mapCtrl) {
+    if (mapCtrl.map) {
+      var len = Object.keys(mapControllers).length;
+      mapControllers[mapCtrl.map.id || len] = mapCtrl;
+    }
+  };
+
+  /**
+   * @memberof NgMap
+   * @function deleteMap
+   * @param mapController {__MapContoller} a map controller
+   */
+  var deleteMap = function(mapCtrl) {
+    var len = Object.keys(mapControllers).length - 1;
+    var mapId = mapCtrl.map.id || len;
+    if (mapCtrl.map) {
+      for (var eventName in mapCtrl.eventListeners) {
+        void 0;
+        var listener = mapCtrl.eventListeners[eventName];
+        google.maps.event.removeListener(listener);
+      }
+      if (mapCtrl.map.controls) {
+        mapCtrl.map.controls.forEach(function(ctrl) {
+          ctrl.clear();
+        });
+      }
+    }
+
+    //Remove Heatmap Layers
+    if (mapCtrl.map.heatmapLayers) {
+      Object.keys(mapCtrl.map.heatmapLayers).forEach(function (layer) {
+        mapCtrl.deleteObject('heatmapLayers', mapCtrl.map.heatmapLayers[layer]);
+      });
+    }
+
+    NgMapPool.deleteMapInstance(mapId);
+
+    delete mapControllers[mapId];
+  };
+
+  /**
+   * @memberof NgMap
+   * @function getGeoLocation
+   * @param {String} address
+   * @param {Hash} options geo options
+   * @returns promise
+   */
+  var getGeoLocation = function(string, options) {
+    var deferred = $q.defer();
+    if (!string || string.match(/^current/i)) { // current location
+      NavigatorGeolocation.getCurrentPosition(options).then(
+        function(position) {
+          var lat = position.coords.latitude;
+          var lng = position.coords.longitude;
+          var latLng = new google.maps.LatLng(lat,lng);
+          deferred.resolve(latLng);
+        },
+        function(error) {
+          deferred.reject(error);
+        }
+      );
+    } else {
+      GeoCoder.geocode({address: string}).then(
+        function(results) {
+          deferred.resolve(results[0].geometry.location);
+        },
+        function(error) {
+          deferred.reject(error);
+        }
+      );
+      // var geocoder = new google.maps.Geocoder();
+      // geocoder.geocode(options, function (results, status) {
+      //   if (status == google.maps.GeocoderStatus.OK) {
+      //     deferred.resolve(results);
+      //   } else {
+      //     deferred.reject(status);
+      //   }
+      // });
+    }
+
+    return deferred.promise;
+  };
+
+  /**
+   * @memberof NgMap
+   * @function observeAndSet
+   * @param {String} attrName attribute name
+   * @param {Object} object A Google maps object to be changed
+   * @returns attribue observe function
+   */
+  var observeAndSet = function(attrName, object) {
+    void 0;
+    return function(val) {
+      if (val) {
+        var setMethod = camelCaseFilter('set-'+attrName);
+        var optionValue = Attr2MapOptions.toOptionValue(val, {key: attrName});
+        if (object[setMethod]) { //if set method does exist
+          void 0;
+          /* if an location is being observed */
+          if (attrName.match(/center|position/) &&
+            typeof optionValue == 'string') {
+            getGeoLocation(optionValue).then(function(latlng) {
+              object[setMethod](latlng);
+            });
+          } else {
+            object[setMethod](optionValue);
+          }
+        }
+      }
+    };
+  };
+
+  /**
+   * @memberof NgMap
+   * @function setStyle
+   * @param {HtmlElement} map contriner element
+   * @desc set display, width, height of map container element
+   */
+  var setStyle = function(el) {
+    //if style is not given to the map element, set display and height
+    var defaultStyle = el.getAttribute('default-style');
+    if (defaultStyle == "true") {
+      el.style.display = 'block';
+      el.style.height = '300px';
+    } else {
+      if (getStyle(el, 'display') != "block") {
+        el.style.display = 'block';
+      }
+      if (getStyle(el, 'height').match(/^(0|auto)/)) {
+        el.style.height = '300px';
+      }
+    }
+  };
+
+  angular.module('ngMap').provider('NgMap', function() {
+    var defaultOptions = {};
+
+    /**
+     * @memberof NgMap
+     * @function setDefaultOptions
+     * @param {Hash} options
+     * @example
+     *  app.config(function(NgMapProvider) {
+     *    NgMapProvider.setDefaultOptions({
+     *      marker: {
+     *        optimized: false
+     *      }
+     *    });
+     *  });
+     */
+    this.setDefaultOptions = function(options) {
+      defaultOptions = options;
+    };
+
+    var NgMap = function(
+        _$window_, _$document_, _$q_,
+        _NavigatorGeolocation_, _Attr2MapOptions_,
+        _GeoCoder_, _camelCaseFilter_, _NgMapPool_
+      ) {
+      $window = _$window_;
+      $document = _$document_[0];
+      $q = _$q_;
+      NavigatorGeolocation = _NavigatorGeolocation_;
+      Attr2MapOptions = _Attr2MapOptions_;
+      GeoCoder = _GeoCoder_;
+      camelCaseFilter = _camelCaseFilter_;
+      NgMapPool = _NgMapPool_;
+
+      return {
+        defaultOptions: defaultOptions,
+        addMap: addMap,
+        deleteMap: deleteMap,
+        getMap: getMap,
+        initMap: initMap,
+        setStyle: setStyle,
+        getGeoLocation: getGeoLocation,
+        observeAndSet: observeAndSet
+      };
+    };
+    NgMap.$inject = [
+      '$window', '$document', '$q',
+      'NavigatorGeolocation', 'Attr2MapOptions',
+      'GeoCoder', 'camelCaseFilter', 'NgMapPool'
+    ];
+
+    this.$get = NgMap;
+  });
+})();
+
+/**
+ * @ngdoc service
+ * @name StreetView
+ * @description
+ *  Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)
+ *  service for [Google StreetViewService]
+ *  (https://developers.google.com/maps/documentation/javascript/streetview)
+ */
+(function() {
+  'use strict';
+  var $q;
+
+  /**
+   * Retrieves panorama id from the given map (and or position)
+   * @memberof StreetView
+   * @param {map} map Google map instance
+   * @param {LatLng} latlng Google LatLng instance
+   *   default: the center of the map
+   * @example
+   *   StreetView.getPanorama(map).then(function(panoId) {
+   *     $scope.panoId = panoId;
+   *   });
+   * @returns {HttpPromise} Future object
+   */
+  var getPanorama = function(map, latlng) {
+    latlng = latlng || map.getCenter();
+    var deferred = $q.defer();
+    var svs = new google.maps.StreetViewService();
+    svs.getPanoramaByLocation( (latlng||map.getCenter), 100,
+      function (data, status) {
+        // if streetView available
+        if (status === google.maps.StreetViewStatus.OK) {
+          deferred.resolve(data.location.pano);
+        } else {
+          // no street view available in this range, or some error occurred
+          deferred.resolve(false);
+          //deferred.reject('Geocoder failed due to: '+ status);
+        }
+      }
+    );
+    return deferred.promise;
+  };
+
+  /**
+   * Set panorama view on the given map with the panorama id
+   * @memberof StreetView
+   * @param {map} map Google map instance
+   * @param {String} panoId Panorama id fro getPanorama method
+   * @example
+   *   StreetView.setPanorama(map, panoId);
+   */
+  var setPanorama = function(map, panoId) {
+    var svp = new google.maps.StreetViewPanorama(
+      map.getDiv(), {enableCloseButton: true}
+    );
+    svp.setPano(panoId);
+  };
+
+  var StreetView = function(_$q_) {
+    $q = _$q_;
+
+    return {
+      getPanorama: getPanorama,
+      setPanorama: setPanorama
+    };
+  };
+  StreetView.$inject = ['$q'];
+
+  angular.module('ngMap').service('StreetView', StreetView);
+})();
+
+return 'ngMap';
+}));
+
+/***/ },
+/* 8 */
+/***/ function(module, exports) {
+
+/**
+ * @license AngularJS v1.6.3
+ * (c) 2010-2017 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular) {'use strict';
+
+/**
+ * @ngdoc module
+ * @name ngCookies
+ * @description
+ *
+ * # ngCookies
+ *
+ * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
+ *
+ *
+ * <div doc-module-components="ngCookies"></div>
+ *
+ * See {@link ngCookies.$cookies `$cookies`} for usage.
+ */
+
+
+angular.module('ngCookies', ['ng']).
+  info({ angularVersion: '1.6.3' }).
+  /**
+   * @ngdoc provider
+   * @name $cookiesProvider
+   * @description
+   * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service.
+   * */
+   provider('$cookies', [/** @this */function $CookiesProvider() {
+    /**
+     * @ngdoc property
+     * @name $cookiesProvider#defaults
+     * @description
+     *
+     * Object containing default options to pass when setting cookies.
+     *
+     * The object may have following properties:
+     *
+     * - **path** - `{string}` - The cookie will be available only for this path and its
+     *   sub-paths. By default, this is the URL that appears in your `<base>` tag.
+     * - **domain** - `{string}` - The cookie will be available only for this domain and
+     *   its sub-domains. For security reasons the user agent will not accept the cookie
+     *   if the current domain is not a sub-domain of this domain or equal to it.
+     * - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT"
+     *   or a Date object indicating the exact date/time this cookie will expire.
+     * - **secure** - `{boolean}` - If `true`, then the cookie will only be available through a
+     *   secured connection.
+     *
+     * Note: By default, the address that appears in your `<base>` tag will be used as the path.
+     * This is important so that cookies will be visible for all routes when html5mode is enabled.
+     *
+     * @example
+     *
+     * ```js
+     * angular.module('cookiesProviderExample', ['ngCookies'])
+     *   .config(['$cookiesProvider', function($cookiesProvider) {
+     *     // Setting default options
+     *     $cookiesProvider.defaults.domain = 'foo.com';
+     *     $cookiesProvider.defaults.secure = true;
+     *   }]);
+     * ```
+     **/
+    var defaults = this.defaults = {};
+
+    function calcOptions(options) {
+      return options ? angular.extend({}, defaults, options) : defaults;
+    }
+
+    /**
+     * @ngdoc service
+     * @name $cookies
+     *
+     * @description
+     * Provides read/write access to browser's cookies.
+     *
+     * <div class="alert alert-info">
+     * Up until Angular 1.3, `$cookies` exposed properties that represented the
+     * current browser cookie values. In version 1.4, this behavior has changed, and
+     * `$cookies` now provides a standard api of getters, setters etc.
+     * </div>
+     *
+     * Requires the {@link ngCookies `ngCookies`} module to be installed.
+     *
+     * @example
+     *
+     * ```js
+     * angular.module('cookiesExample', ['ngCookies'])
+     *   .controller('ExampleController', ['$cookies', function($cookies) {
+     *     // Retrieving a cookie
+     *     var favoriteCookie = $cookies.get('myFavorite');
+     *     // Setting a cookie
+     *     $cookies.put('myFavorite', 'oatmeal');
+     *   }]);
+     * ```
+     */
+    this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {
+      return {
+        /**
+         * @ngdoc method
+         * @name $cookies#get
+         *
+         * @description
+         * Returns the value of given cookie key
+         *
+         * @param {string} key Id to use for lookup.
+         * @returns {string} Raw cookie value.
+         */
+        get: function(key) {
+          return $$cookieReader()[key];
+        },
+
+        /**
+         * @ngdoc method
+         * @name $cookies#getObject
+         *
+         * @description
+         * Returns the deserialized value of given cookie key
+         *
+         * @param {string} key Id to use for lookup.
+         * @returns {Object} Deserialized cookie value.
+         */
+        getObject: function(key) {
+          var value = this.get(key);
+          return value ? angular.fromJson(value) : value;
+        },
+
+        /**
+         * @ngdoc method
+         * @name $cookies#getAll
+         *
+         * @description
+         * Returns a key value object with all the cookies
+         *
+         * @returns {Object} All cookies
+         */
+        getAll: function() {
+          return $$cookieReader();
+        },
+
+        /**
+         * @ngdoc method
+         * @name $cookies#put
+         *
+         * @description
+         * Sets a value for given cookie key
+         *
+         * @param {string} key Id for the `value`.
+         * @param {string} value Raw value to be stored.
+         * @param {Object=} options Options object.
+         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
+         */
+        put: function(key, value, options) {
+          $$cookieWriter(key, value, calcOptions(options));
+        },
+
+        /**
+         * @ngdoc method
+         * @name $cookies#putObject
+         *
+         * @description
+         * Serializes and sets a value for given cookie key
+         *
+         * @param {string} key Id for the `value`.
+         * @param {Object} value Value to be stored.
+         * @param {Object=} options Options object.
+         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
+         */
+        putObject: function(key, value, options) {
+          this.put(key, angular.toJson(value), options);
+        },
+
+        /**
+         * @ngdoc method
+         * @name $cookies#remove
+         *
+         * @description
+         * Remove given cookie
+         *
+         * @param {string} key Id of the key-value pair to delete.
+         * @param {Object=} options Options object.
+         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
+         */
+        remove: function(key, options) {
+          $$cookieWriter(key, undefined, calcOptions(options));
+        }
+      };
+    }];
+  }]);
+
+angular.module('ngCookies').
+/**
+ * @ngdoc service
+ * @name $cookieStore
+ * @deprecated
+ * sinceVersion="v1.4.0"
+ * Please use the {@link ngCookies.$cookies `$cookies`} service instead.
+ *
+ * @requires $cookies
+ *
+ * @description
+ * Provides a key-value (string-object) storage, that is backed by session cookies.
+ * Objects put or retrieved from this storage are automatically serialized or
+ * deserialized by angular's toJson/fromJson.
+ *
+ * Requires the {@link ngCookies `ngCookies`} module to be installed.
+ *
+ * @example
+ *
+ * ```js
+ * angular.module('cookieStoreExample', ['ngCookies'])
+ *   .controller('ExampleController', ['$cookieStore', function($cookieStore) {
+ *     // Put cookie
+ *     $cookieStore.put('myFavorite','oatmeal');
+ *     // Get cookie
+ *     var favoriteCookie = $cookieStore.get('myFavorite');
+ *     // Removing a cookie
+ *     $cookieStore.remove('myFavorite');
+ *   }]);
+ * ```
+ */
+ factory('$cookieStore', ['$cookies', function($cookies) {
+
+    return {
+      /**
+       * @ngdoc method
+       * @name $cookieStore#get
+       *
+       * @description
+       * Returns the value of given cookie key
+       *
+       * @param {string} key Id to use for lookup.
+       * @returns {Object} Deserialized cookie value, undefined if the cookie does not exist.
+       */
+      get: function(key) {
+        return $cookies.getObject(key);
+      },
+
+      /**
+       * @ngdoc method
+       * @name $cookieStore#put
+       *
+       * @description
+       * Sets a value for given cookie key
+       *
+       * @param {string} key Id for the `value`.
+       * @param {Object} value Value to be stored.
+       */
+      put: function(key, value) {
+        $cookies.putObject(key, value);
+      },
+
+      /**
+       * @ngdoc method
+       * @name $cookieStore#remove
+       *
+       * @description
+       * Remove given cookie
+       *
+       * @param {string} key Id of the key-value pair to delete.
+       */
+      remove: function(key) {
+        $cookies.remove(key);
+      }
+    };
+
+  }]);
+
+/**
+ * @name $$cookieWriter
+ * @requires $document
+ *
+ * @description
+ * This is a private service for writing cookies
+ *
+ * @param {string} name Cookie name
+ * @param {string=} value Cookie value (if undefined, cookie will be deleted)
+ * @param {Object=} options Object with options that need to be stored for the cookie.
+ */
+function $$CookieWriter($document, $log, $browser) {
+  var cookiePath = $browser.baseHref();
+  var rawDocument = $document[0];
+
+  function buildCookieString(name, value, options) {
+    var path, expires;
+    options = options || {};
+    expires = options.expires;
+    path = angular.isDefined(options.path) ? options.path : cookiePath;
+    if (angular.isUndefined(value)) {
+      expires = 'Thu, 01 Jan 1970 00:00:00 GMT';
+      value = '';
+    }
+    if (angular.isString(expires)) {
+      expires = new Date(expires);
+    }
+
+    var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);
+    str += path ? ';path=' + path : '';
+    str += options.domain ? ';domain=' + options.domain : '';
+    str += expires ? ';expires=' + expires.toUTCString() : '';
+    str += options.secure ? ';secure' : '';
+
+    // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
+    // - 300 cookies
+    // - 20 cookies per unique domain
+    // - 4096 bytes per cookie
+    var cookieLength = str.length + 1;
+    if (cookieLength > 4096) {
+      $log.warn('Cookie \'' + name +
+        '\' possibly not set or overflowed because it was too large (' +
+        cookieLength + ' > 4096 bytes)!');
+    }
+
+    return str;
+  }
+
+  return function(name, value, options) {
+    rawDocument.cookie = buildCookieString(name, value, options);
+  };
+}
+
+$$CookieWriter.$inject = ['$document', '$log', '$browser'];
+
+angular.module('ngCookies').provider('$$cookieWriter', /** @this */ function $$CookieWriterProvider() {
+  this.$get = $$CookieWriter;
+});
+
+
+})(window, window.angular);
+
+
+/***/ },
+/* 9 */
+/***/ function(module, exports) {
+
+/**
+ * @license AngularJS v1.6.3
+ * (c) 2010-2017 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular) {'use strict';
+
+var $resourceMinErr = angular.$$minErr('$resource');
+
+// Helper functions and regex to lookup a dotted path on an object
+// stopping at undefined/null.  The path must be composed of ASCII
+// identifiers (just like $parse)
+var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;
+
+function isValidDottedPath(path) {
+  return (path != null && path !== '' && path !== 'hasOwnProperty' &&
+      MEMBER_NAME_REGEX.test('.' + path));
+}
+
+function lookupDottedPath(obj, path) {
+  if (!isValidDottedPath(path)) {
+    throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
+  }
+  var keys = path.split('.');
+  for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) {
+    var key = keys[i];
+    obj = (obj !== null) ? obj[key] : undefined;
+  }
+  return obj;
+}
+
+/**
+ * Create a shallow copy of an object and clear other fields from the destination
+ */
+function shallowClearAndCopy(src, dst) {
+  dst = dst || {};
+
+  angular.forEach(dst, function(value, key) {
+    delete dst[key];
+  });
+
+  for (var key in src) {
+    if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
+      dst[key] = src[key];
+    }
+  }
+
+  return dst;
+}
+
+/**
+ * @ngdoc module
+ * @name ngResource
+ * @description
+ *
+ * # ngResource
+ *
+ * The `ngResource` module provides interaction support with RESTful services
+ * via the $resource service.
+ *
+ *
+ * <div doc-module-components="ngResource"></div>
+ *
+ * See {@link ngResource.$resourceProvider} and {@link ngResource.$resource} for usage.
+ */
+
+/**
+ * @ngdoc provider
+ * @name $resourceProvider
+ *
+ * @description
+ *
+ * Use `$resourceProvider` to change the default behavior of the {@link ngResource.$resource}
+ * service.
+ *
+ * ## Dependencies
+ * Requires the {@link ngResource } module to be installed.
+ *
+ */
+
+/**
+ * @ngdoc service
+ * @name $resource
+ * @requires $http
+ * @requires ng.$log
+ * @requires $q
+ * @requires ng.$timeout
+ *
+ * @description
+ * A factory which creates a resource object that lets you interact with
+ * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
+ *
+ * The returned resource object has action methods which provide high-level behaviors without
+ * the need to interact with the low level {@link ng.$http $http} service.
+ *
+ * Requires the {@link ngResource `ngResource`} module to be installed.
+ *
+ * By default, trailing slashes will be stripped from the calculated URLs,
+ * which can pose problems with server backends that do not expect that
+ * behavior.  This can be disabled by configuring the `$resourceProvider` like
+ * this:
+ *
+ * ```js
+     app.config(['$resourceProvider', function($resourceProvider) {
+       // Don't strip trailing slashes from calculated URLs
+       $resourceProvider.defaults.stripTrailingSlashes = false;
+     }]);
+ * ```
+ *
+ * @param {string} url A parameterized URL template with parameters prefixed by `:` as in
+ *   `/user/:username`. If you are using a URL with a port number (e.g.
+ *   `http://example.com:8080/api`), it will be respected.
+ *
+ *   If you are using a url with a suffix, just add the suffix, like this:
+ *   `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
+ *   or even `$resource('http://example.com/resource/:resource_id.:format')`
+ *   If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
+ *   collapsed down to a single `.`.  If you need this sequence to appear and not collapse then you
+ *   can escape it with `/\.`.
+ *
+ * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
+ *   `actions` methods. If a parameter value is a function, it will be called every time
+ *   a param value needs to be obtained for a request (unless the param was overridden). The function
+ *   will be passed the current data value as an argument.
+ *
+ *   Each key value in the parameter object is first bound to url template if present and then any
+ *   excess keys are appended to the url search query after the `?`.
+ *
+ *   Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
+ *   URL `/path/greet?salutation=Hello`.
+ *
+ *   If the parameter value is prefixed with `@`, then the value for that parameter will be
+ *   extracted from the corresponding property on the `data` object (provided when calling a
+ *   "non-GET" action method).
+ *   For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of
+ *   `someParam` will be `data.someProp`.
+ *   Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action
+ *   method that does not accept a request body)
+ *
+ * @param {Object.<Object>=} actions Hash with declaration of custom actions that will be available
+ *   in addition to the default set of resource actions (see below). If a custom action has the same
+ *   key as a default action (e.g. `save`), then the default action will be *overwritten*, and not
+ *   extended.
+ *
+ *   The declaration should be created in the format of {@link ng.$http#usage $http.config}:
+ *
+ *       {action1: {method:?, params:?, isArray:?, headers:?, ...},
+ *        action2: {method:?, params:?, isArray:?, headers:?, ...},
+ *        ...}
+ *
+ *   Where:
+ *
+ *   - **`action`** – {string} – The name of action. This name becomes the name of the method on
+ *     your resource object.
+ *   - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`,
+ *     `DELETE`, `JSONP`, etc).
+ *   - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of
+ *     the parameter value is a function, it will be called every time when a param value needs to
+ *     be obtained for a request (unless the param was overridden). The function will be passed the
+ *     current data value as an argument.
+ *   - **`url`** – {string} – action specific `url` override. The url templating is supported just
+ *     like for the resource-level urls.
+ *   - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
+ *     see `returns` section.
+ *   - **`transformRequest`** –
+ *     `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
+ *     transform function or an array of such functions. The transform function takes the http
+ *     request body and headers and returns its transformed (typically serialized) version.
+ *     By default, transformRequest will contain one function that checks if the request data is
+ *     an object and serializes it using `angular.toJson`. To prevent this behavior, set
+ *     `transformRequest` to an empty array: `transformRequest: []`
+ *   - **`transformResponse`** –
+ *     `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –
+ *     transform function or an array of such functions. The transform function takes the http
+ *     response body, headers and status and returns its transformed (typically deserialized)
+ *     version.
+ *     By default, transformResponse will contain one function that checks if the response looks
+ *     like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior,
+ *     set `transformResponse` to an empty array: `transformResponse: []`
+ *   - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
+ *     GET request, otherwise if a cache instance built with
+ *     {@link ng.$cacheFactory $cacheFactory} is supplied, this cache will be used for
+ *     caching.
+ *   - **`timeout`** – `{number}` – timeout in milliseconds.<br />
+ *     **Note:** In contrast to {@link ng.$http#usage $http.config}, {@link ng.$q promises} are
+ *     **not** supported in $resource, because the same value would be used for multiple requests.
+ *     If you are looking for a way to cancel requests, you should use the `cancellable` option.
+ *   - **`cancellable`** – `{boolean}` – if set to true, the request made by a "non-instance" call
+ *     will be cancelled (if not already completed) by calling `$cancelRequest()` on the call's
+ *     return value. Calling `$cancelRequest()` for a non-cancellable or an already
+ *     completed/cancelled request will have no effect.<br />
+ *   - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the
+ *     XHR object. See
+ *     [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5)
+ *     for more information.
+ *   - **`responseType`** - `{string}` - see
+ *     [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).
+ *   - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -
+ *     `response` and `responseError`. Both `response` and `responseError` interceptors get called
+ *     with `http response` object. See {@link ng.$http $http interceptors}.
+ *
+ * @param {Object} options Hash with custom settings that should extend the
+ *   default `$resourceProvider` behavior.  The supported options are:
+ *
+ *   - **`stripTrailingSlashes`** – {boolean} – If true then the trailing
+ *   slashes from any calculated URL will be stripped. (Defaults to true.)
+ *   - **`cancellable`** – {boolean} – If true, the request made by a "non-instance" call will be
+ *   cancelled (if not already completed) by calling `$cancelRequest()` on the call's return value.
+ *   This can be overwritten per action. (Defaults to false.)
+ *
+ * @returns {Object} A resource "class" object with methods for the default set of resource actions
+ *   optionally extended with custom `actions`. The default set contains these actions:
+ *   ```js
+ *   { 'get':    {method:'GET'},
+ *     'save':   {method:'POST'},
+ *     'query':  {method:'GET', isArray:true},
+ *     'remove': {method:'DELETE'},
+ *     'delete': {method:'DELETE'} };
+ *   ```
+ *
+ *   Calling these methods invoke an {@link ng.$http} with the specified http method,
+ *   destination and parameters. When the data is returned from the server then the object is an
+ *   instance of the resource class. The actions `save`, `remove` and `delete` are available on it
+ *   as  methods with the `$` prefix. This allows you to easily perform CRUD operations (create,
+ *   read, update, delete) on server-side data like this:
+ *   ```js
+ *   var User = $resource('/user/:userId', {userId:'@id'});
+ *   var user = User.get({userId:123}, function() {
+ *     user.abc = true;
+ *     user.$save();
+ *   });
+ *   ```
+ *
+ *   It is important to realize that invoking a $resource object method immediately returns an
+ *   empty reference (object or array depending on `isArray`). Once the data is returned from the
+ *   server the existing reference is populated with the actual data. This is a useful trick since
+ *   usually the resource is assigned to a model which is then rendered by the view. Having an empty
+ *   object results in no rendering, once the data arrives from the server then the object is
+ *   populated with the data and the view automatically re-renders itself showing the new data. This
+ *   means that in most cases one never has to write a callback function for the action methods.
+ *
+ *   The action methods on the class object or instance object can be invoked with the following
+ *   parameters:
+ *
+ *   - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])`
+ *   - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
+ *   - non-GET instance actions:  `instance.$action([parameters], [success], [error])`
+ *
+ *
+ *   Success callback is called with (value (Object|Array), responseHeaders (Function),
+ *   status (number), statusText (string)) arguments, where the value is the populated resource
+ *   instance or collection object. The error callback is called with (httpResponse) argument.
+ *
+ *   Class actions return empty instance (with additional properties below).
+ *   Instance actions return promise of the action.
+ *
+ *   The Resource instances and collections have these additional properties:
+ *
+ *   - `$promise`: the {@link ng.$q promise} of the original server interaction that created this
+ *     instance or collection.
+ *
+ *     On success, the promise is resolved with the same resource instance or collection object,
+ *     updated with data from server. This makes it easy to use in
+ *     {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view
+ *     rendering until the resource(s) are loaded.
+ *
+ *     On failure, the promise is rejected with the {@link ng.$http http response} object, without
+ *     the `resource` property.
+ *
+ *     If an interceptor object was provided, the promise will instead be resolved with the value
+ *     returned by the interceptor.
+ *
+ *   - `$resolved`: `true` after first server interaction is completed (either with success or
+ *      rejection), `false` before that. Knowing if the Resource has been resolved is useful in
+ *      data-binding.
+ *
+ *   The Resource instances and collections have these additional methods:
+ *
+ *   - `$cancelRequest`: If there is a cancellable, pending request related to the instance or
+ *      collection, calling this method will abort the request.
+ *
+ *   The Resource instances have these additional methods:
+ *
+ *   - `toJSON`: It returns a simple object without any of the extra properties added as part of
+ *     the Resource API. This object can be serialized through {@link angular.toJson} safely
+ *     without attaching Angular-specific fields. Notice that `JSON.stringify` (and
+ *     `angular.toJson`) automatically use this method when serializing a Resource instance
+ *     (see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior)).
+ *
+ * @example
+ *
+ * # Credit card resource
+ *
+ * ```js
+     // Define CreditCard class
+     var CreditCard = $resource('/user/:userId/card/:cardId',
+      {userId:123, cardId:'@id'}, {
+       charge: {method:'POST', params:{charge:true}}
+      });
+
+     // We can retrieve a collection from the server
+     var cards = CreditCard.query(function() {
+       // GET: /user/123/card
+       // server returns: [ {id:456, number:'1234', name:'Smith'} ];
+
+       var card = cards[0];
+       // each item is an instance of CreditCard
+       expect(card instanceof CreditCard).toEqual(true);
+       card.name = "J. Smith";
+       // non GET methods are mapped onto the instances
+       card.$save();
+       // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
+       // server returns: {id:456, number:'1234', name: 'J. Smith'};
+
+       // our custom method is mapped as well.
+       card.$charge({amount:9.99});
+       // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
+     });
+
+     // we can create an instance as well
+     var newCard = new CreditCard({number:'0123'});
+     newCard.name = "Mike Smith";
+     newCard.$save();
+     // POST: /user/123/card {number:'0123', name:'Mike Smith'}
+     // server returns: {id:789, number:'0123', name: 'Mike Smith'};
+     expect(newCard.id).toEqual(789);
+ * ```
+ *
+ * The object returned from this function execution is a resource "class" which has "static" method
+ * for each action in the definition.
+ *
+ * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and
+ * `headers`.
+ *
+ * @example
+ *
+ * # User resource
+ *
+ * When the data is returned from the server then the object is an instance of the resource type and
+ * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
+ * operations (create, read, update, delete) on server-side data.
+
+   ```js
+     var User = $resource('/user/:userId', {userId:'@id'});
+     User.get({userId:123}, function(user) {
+       user.abc = true;
+       user.$save();
+     });
+   ```
+ *
+ * It's worth noting that the success callback for `get`, `query` and other methods gets passed
+ * in the response that came from the server as well as $http header getter function, so one
+ * could rewrite the above example and get access to http headers as:
+ *
+   ```js
+     var User = $resource('/user/:userId', {userId:'@id'});
+     User.get({userId:123}, function(user, getResponseHeaders){
+       user.abc = true;
+       user.$save(function(user, putResponseHeaders) {
+         //user => saved user object
+         //putResponseHeaders => $http header getter
+       });
+     });
+   ```
+ *
+ * You can also access the raw `$http` promise via the `$promise` property on the object returned
+ *
+   ```
+     var User = $resource('/user/:userId', {userId:'@id'});
+     User.get({userId:123})
+         .$promise.then(function(user) {
+           $scope.user = user;
+         });
+   ```
+ *
+ * @example
+ *
+ * # Creating a custom 'PUT' request
+ *
+ * In this example we create a custom method on our resource to make a PUT request
+ * ```js
+ *    var app = angular.module('app', ['ngResource', 'ngRoute']);
+ *
+ *    // Some APIs expect a PUT request in the format URL/object/ID
+ *    // Here we are creating an 'update' method
+ *    app.factory('Notes', ['$resource', function($resource) {
+ *    return $resource('/notes/:id', null,
+ *        {
+ *            'update': { method:'PUT' }
+ *        });
+ *    }]);
+ *
+ *    // In our controller we get the ID from the URL using ngRoute and $routeParams
+ *    // We pass in $routeParams and our Notes factory along with $scope
+ *    app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',
+                                      function($scope, $routeParams, Notes) {
+ *    // First get a note object from the factory
+ *    var note = Notes.get({ id:$routeParams.id });
+ *    $id = note.id;
+ *
+ *    // Now call update passing in the ID first then the object you are updating
+ *    Notes.update({ id:$id }, note);
+ *
+ *    // This will PUT /notes/ID with the note object in the request payload
+ *    }]);
+ * ```
+ *
+ * @example
+ *
+ * # Cancelling requests
+ *
+ * If an action's configuration specifies that it is cancellable, you can cancel the request related
+ * to an instance or collection (as long as it is a result of a "non-instance" call):
+ *
+   ```js
+     // ...defining the `Hotel` resource...
+     var Hotel = $resource('/api/hotel/:id', {id: '@id'}, {
+       // Let's make the `query()` method cancellable
+       query: {method: 'get', isArray: true, cancellable: true}
+     });
+
+     // ...somewhere in the PlanVacationController...
+     ...
+     this.onDestinationChanged = function onDestinationChanged(destination) {
+       // We don't care about any pending request for hotels
+       // in a different destination any more
+       this.availableHotels.$cancelRequest();
+
+       // Let's query for hotels in '<destination>'
+       // (calls: /api/hotel?location=<destination>)
+       this.availableHotels = Hotel.query({location: destination});
+     };
+   ```
+ *
+ */
+angular.module('ngResource', ['ng']).
+  info({ angularVersion: '1.6.3' }).
+  provider('$resource', function ResourceProvider() {
+    var PROTOCOL_AND_IPV6_REGEX = /^https?:\/\/\[[^\]]*][^/]*/;
+
+    var provider = this;
+
+    /**
+     * @ngdoc property
+     * @name $resourceProvider#defaults
+     * @description
+     * Object containing default options used when creating `$resource` instances.
+     *
+     * The default values satisfy a wide range of usecases, but you may choose to overwrite any of
+     * them to further customize your instances. The available properties are:
+     *
+     * - **stripTrailingSlashes** – `{boolean}` – If true, then the trailing slashes from any
+     *   calculated URL will be stripped.<br />
+     *   (Defaults to true.)
+     * - **cancellable** – `{boolean}` – If true, the request made by a "non-instance" call will be
+     *   cancelled (if not already completed) by calling `$cancelRequest()` on the call's return
+     *   value. For more details, see {@link ngResource.$resource}. This can be overwritten per
+     *   resource class or action.<br />
+     *   (Defaults to false.)
+     * - **actions** - `{Object.<Object>}` - A hash with default actions declarations. Actions are
+     *   high-level methods corresponding to RESTful actions/methods on resources. An action may
+     *   specify what HTTP method to use, what URL to hit, if the return value will be a single
+     *   object or a collection (array) of objects etc. For more details, see
+     *   {@link ngResource.$resource}. The actions can also be enhanced or overwritten per resource
+     *   class.<br />
+     *   The default actions are:
+     *   ```js
+     *   {
+     *     get: {method: 'GET'},
+     *     save: {method: 'POST'},
+     *     query: {method: 'GET', isArray: true},
+     *     remove: {method: 'DELETE'},
+     *     delete: {method: 'DELETE'}
+     *   }
+     *   ```
+     *
+     * #### Example
+     *
+     * For example, you can specify a new `update` action that uses the `PUT` HTTP verb:
+     *
+     * ```js
+     *   angular.
+     *     module('myApp').
+     *     config(['$resourceProvider', function ($resourceProvider) {
+     *       $resourceProvider.defaults.actions.update = {
+     *         method: 'PUT'
+     *       };
+     *     });
+     * ```
+     *
+     * Or you can even overwrite the whole `actions` list and specify your own:
+     *
+     * ```js
+     *   angular.
+     *     module('myApp').
+     *     config(['$resourceProvider', function ($resourceProvider) {
+     *       $resourceProvider.defaults.actions = {
+     *         create: {method: 'POST'},
+     *         get:    {method: 'GET'},
+     *         getAll: {method: 'GET', isArray:true},
+     *         update: {method: 'PUT'},
+     *         delete: {method: 'DELETE'}
+     *       };
+     *     });
+     * ```
+     *
+     */
+    this.defaults = {
+      // Strip slashes by default
+      stripTrailingSlashes: true,
+
+      // Make non-instance requests cancellable (via `$cancelRequest()`)
+      cancellable: false,
+
+      // Default actions configuration
+      actions: {
+        'get': {method: 'GET'},
+        'save': {method: 'POST'},
+        'query': {method: 'GET', isArray: true},
+        'remove': {method: 'DELETE'},
+        'delete': {method: 'DELETE'}
+      }
+    };
+
+    this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) {
+
+      var noop = angular.noop,
+          forEach = angular.forEach,
+          extend = angular.extend,
+          copy = angular.copy,
+          isArray = angular.isArray,
+          isDefined = angular.isDefined,
+          isFunction = angular.isFunction,
+          isNumber = angular.isNumber,
+          encodeUriQuery = angular.$$encodeUriQuery,
+          encodeUriSegment = angular.$$encodeUriSegment;
+
+      function Route(template, defaults) {
+        this.template = template;
+        this.defaults = extend({}, provider.defaults, defaults);
+        this.urlParams = {};
+      }
+
+      Route.prototype = {
+        setUrlParams: function(config, params, actionUrl) {
+          var self = this,
+            url = actionUrl || self.template,
+            val,
+            encodedVal,
+            protocolAndIpv6 = '';
+
+          var urlParams = self.urlParams = Object.create(null);
+          forEach(url.split(/\W/), function(param) {
+            if (param === 'hasOwnProperty') {
+              throw $resourceMinErr('badname', 'hasOwnProperty is not a valid parameter name.');
+            }
+            if (!(new RegExp('^\\d+$').test(param)) && param &&
+              (new RegExp('(^|[^\\\\]):' + param + '(\\W|$)').test(url))) {
+              urlParams[param] = {
+                isQueryParamValue: (new RegExp('\\?.*=:' + param + '(?:\\W|$)')).test(url)
+              };
+            }
+          });
+          url = url.replace(/\\:/g, ':');
+          url = url.replace(PROTOCOL_AND_IPV6_REGEX, function(match) {
+            protocolAndIpv6 = match;
+            return '';
+          });
+
+          params = params || {};
+          forEach(self.urlParams, function(paramInfo, urlParam) {
+            val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
+            if (isDefined(val) && val !== null) {
+              if (paramInfo.isQueryParamValue) {
+                encodedVal = encodeUriQuery(val, true);
+              } else {
+                encodedVal = encodeUriSegment(val);
+              }
+              url = url.replace(new RegExp(':' + urlParam + '(\\W|$)', 'g'), function(match, p1) {
+                return encodedVal + p1;
+              });
+            } else {
+              url = url.replace(new RegExp('(/?):' + urlParam + '(\\W|$)', 'g'), function(match,
+                  leadingSlashes, tail) {
+                if (tail.charAt(0) === '/') {
+                  return tail;
+                } else {
+                  return leadingSlashes + tail;
+                }
+              });
+            }
+          });
+
+          // strip trailing slashes and set the url (unless this behavior is specifically disabled)
+          if (self.defaults.stripTrailingSlashes) {
+            url = url.replace(/\/+$/, '') || '/';
+          }
+
+          // Collapse `/.` if found in the last URL path segment before the query.
+          // E.g. `http://url.com/id/.format?q=x` becomes `http://url.com/id.format?q=x`.
+          url = url.replace(/\/\.(?=\w+($|\?))/, '.');
+          // Replace escaped `/\.` with `/.`.
+          // (If `\.` comes from a param value, it will be encoded as `%5C.`.)
+          config.url = protocolAndIpv6 + url.replace(/\/(\\|%5C)\./, '/.');
+
+
+          // set params - delegate param encoding to $http
+          forEach(params, function(value, key) {
+            if (!self.urlParams[key]) {
+              config.params = config.params || {};
+              config.params[key] = value;
+            }
+          });
+        }
+      };
+
+
+      function resourceFactory(url, paramDefaults, actions, options) {
+        var route = new Route(url, options);
+
+        actions = extend({}, provider.defaults.actions, actions);
+
+        function extractParams(data, actionParams) {
+          var ids = {};
+          actionParams = extend({}, paramDefaults, actionParams);
+          forEach(actionParams, function(value, key) {
+            if (isFunction(value)) { value = value(data); }
+            ids[key] = value && value.charAt && value.charAt(0) === '@' ?
+              lookupDottedPath(data, value.substr(1)) : value;
+          });
+          return ids;
+        }
+
+        function defaultResponseInterceptor(response) {
+          return response.resource;
+        }
+
+        function Resource(value) {
+          shallowClearAndCopy(value || {}, this);
+        }
+
+        Resource.prototype.toJSON = function() {
+          var data = extend({}, this);
+          delete data.$promise;
+          delete data.$resolved;
+          delete data.$cancelRequest;
+          return data;
+        };
+
+        forEach(actions, function(action, name) {
+          var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
+          var numericTimeout = action.timeout;
+          var cancellable = isDefined(action.cancellable) ?
+              action.cancellable : route.defaults.cancellable;
+
+          if (numericTimeout && !isNumber(numericTimeout)) {
+            $log.debug('ngResource:\n' +
+                       '  Only numeric values are allowed as `timeout`.\n' +
+                       '  Promises are not supported in $resource, because the same value would ' +
+                       'be used for multiple requests. If you are looking for a way to cancel ' +
+                       'requests, you should use the `cancellable` option.');
+            delete action.timeout;
+            numericTimeout = null;
+          }
+
+          Resource[name] = function(a1, a2, a3, a4) {
+            var params = {}, data, success, error;
+
+            switch (arguments.length) {
+              case 4:
+                error = a4;
+                success = a3;
+                // falls through
+              case 3:
+              case 2:
+                if (isFunction(a2)) {
+                  if (isFunction(a1)) {
+                    success = a1;
+                    error = a2;
+                    break;
+                  }
+
+                  success = a2;
+                  error = a3;
+                  // falls through
+                } else {
+                  params = a1;
+                  data = a2;
+                  success = a3;
+                  break;
+                }
+                // falls through
+              case 1:
+                if (isFunction(a1)) success = a1;
+                else if (hasBody) data = a1;
+                else params = a1;
+                break;
+              case 0: break;
+              default:
+                throw $resourceMinErr('badargs',
+                  'Expected up to 4 arguments [params, data, success, error], got {0} arguments',
+                  arguments.length);
+            }
+
+            var isInstanceCall = this instanceof Resource;
+            var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
+            var httpConfig = {};
+            var responseInterceptor = action.interceptor && action.interceptor.response ||
+              defaultResponseInterceptor;
+            var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
+              undefined;
+            var hasError = !!error;
+            var hasResponseErrorInterceptor = !!responseErrorInterceptor;
+            var timeoutDeferred;
+            var numericTimeoutPromise;
+
+            forEach(action, function(value, key) {
+              switch (key) {
+                default:
+                  httpConfig[key] = copy(value);
+                  break;
+                case 'params':
+                case 'isArray':
+                case 'interceptor':
+                case 'cancellable':
+                  break;
+              }
+            });
+
+            if (!isInstanceCall && cancellable) {
+              timeoutDeferred = $q.defer();
+              httpConfig.timeout = timeoutDeferred.promise;
+
+              if (numericTimeout) {
+                numericTimeoutPromise = $timeout(timeoutDeferred.resolve, numericTimeout);
+              }
+            }
+
+            if (hasBody) httpConfig.data = data;
+            route.setUrlParams(httpConfig,
+              extend({}, extractParams(data, action.params || {}), params),
+              action.url);
+
+            var promise = $http(httpConfig).then(function(response) {
+              var data = response.data;
+
+              if (data) {
+                // Need to convert action.isArray to boolean in case it is undefined
+                if (isArray(data) !== (!!action.isArray)) {
+                  throw $resourceMinErr('badcfg',
+                      'Error in resource configuration for action `{0}`. Expected response to ' +
+                      'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',
+                    isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);
+                }
+                if (action.isArray) {
+                  value.length = 0;
+                  forEach(data, function(item) {
+                    if (typeof item === 'object') {
+                      value.push(new Resource(item));
+                    } else {
+                      // Valid JSON values may be string literals, and these should not be converted
+                      // into objects. These items will not have access to the Resource prototype
+                      // methods, but unfortunately there
+                      value.push(item);
+                    }
+                  });
+                } else {
+                  var promise = value.$promise;     // Save the promise
+                  shallowClearAndCopy(data, value);
+                  value.$promise = promise;         // Restore the promise
+                }
+              }
+              response.resource = value;
+
+              return response;
+            });
+
+            promise = promise['finally'](function() {
+              value.$resolved = true;
+              if (!isInstanceCall && cancellable) {
+                value.$cancelRequest = noop;
+                $timeout.cancel(numericTimeoutPromise);
+                timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null;
+              }
+            });
+
+            promise = promise.then(
+              function(response) {
+                var value = responseInterceptor(response);
+                (success || noop)(value, response.headers, response.status, response.statusText);
+                return value;
+              },
+              (hasError || hasResponseErrorInterceptor) ?
+                function(response) {
+                  if (hasError && !hasResponseErrorInterceptor) {
+                    // Avoid `Possibly Unhandled Rejection` error,
+                    // but still fulfill the returned promise with a rejection
+                    promise.catch(noop);
+                  }
+                  if (hasError) error(response);
+                  return hasResponseErrorInterceptor ?
+                    responseErrorInterceptor(response) :
+                    $q.reject(response);
+                } :
+                undefined);
+
+            if (!isInstanceCall) {
+              // we are creating instance / collection
+              // - set the initial promise
+              // - return the instance / collection
+              value.$promise = promise;
+              value.$resolved = false;
+              if (cancellable) value.$cancelRequest = cancelRequest;
+
+              return value;
+            }
+
+            // instance call
+            return promise;
+
+            function cancelRequest(value) {
+              promise.catch(noop);
+              timeoutDeferred.resolve(value);
+            }
+          };
+
+
+          Resource.prototype['$' + name] = function(params, success, error) {
+            if (isFunction(params)) {
+              error = success; success = params; params = {};
+            }
+            var result = Resource[name].call(this, params, this, success, error);
+            return result.$promise || result;
+          };
+        });
+
+        Resource.bind = function(additionalParamDefaults) {
+          var extendedParamDefaults = extend({}, paramDefaults, additionalParamDefaults);
+          return resourceFactory(url, extendedParamDefaults, actions, options);
+        };
+
+        return Resource;
+      }
+
+      return resourceFactory;
+    }];
+  });
+
+
+})(window, window.angular);
+
+
+/***/ },
+/* 10 */
+/***/ function(module, exports) {
+
+/**
+ * @license AngularJS v1.6.3
+ * (c) 2010-2017 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window) {'use strict';
+
+/**
+ * @description
+ *
+ * This object provides a utility for producing rich Error messages within
+ * Angular. It can be called as follows:
+ *
+ * var exampleMinErr = minErr('example');
+ * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
+ *
+ * The above creates an instance of minErr in the example namespace. The
+ * resulting error will have a namespaced error code of example.one.  The
+ * resulting error will replace {0} with the value of foo, and {1} with the
+ * value of bar. The object is not restricted in the number of arguments it can
+ * take.
+ *
+ * If fewer arguments are specified than necessary for interpolation, the extra
+ * interpolation markers will be preserved in the final string.
+ *
+ * Since data will be parsed statically during a build step, some restrictions
+ * are applied with respect to how minErr instances are created and called.
+ * Instances should have names of the form namespaceMinErr for a minErr created
+ * using minErr('namespace') . Error codes, namespaces and template strings
+ * should all be static strings, not variables or general expressions.
+ *
+ * @param {string} module The namespace to use for the new minErr instance.
+ * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
+ *   error from returned function, for cases when a particular type of error is useful.
+ * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
+ */
+
+function minErr(module, ErrorConstructor) {
+  ErrorConstructor = ErrorConstructor || Error;
+  return function() {
+    var code = arguments[0],
+      template = arguments[1],
+      message = '[' + (module ? module + ':' : '') + code + '] ',
+      templateArgs = sliceArgs(arguments, 2).map(function(arg) {
+        return toDebugString(arg, minErrConfig.objectMaxDepth);
+      }),
+      paramPrefix, i;
+
+    message += template.replace(/\{\d+\}/g, function(match) {
+      var index = +match.slice(1, -1);
+
+      if (index < templateArgs.length) {
+        return templateArgs[index];
+      }
+
+      return match;
+    });
+
+    message += '\nhttp://errors.angularjs.org/1.6.3/' +
+      (module ? module + '/' : '') + code;
+
+    for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
+      message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]);
+    }
+
+    return new ErrorConstructor(message);
+  };
+}
+
+/* We need to tell ESLint what variables are being exported */
+/* exported
+  angular,
+  msie,
+  jqLite,
+  jQuery,
+  slice,
+  splice,
+  push,
+  toString,
+  minErrConfig,
+  errorHandlingConfig,
+  isValidObjectMaxDepth,
+  ngMinErr,
+  angularModule,
+  uid,
+  REGEX_STRING_REGEXP,
+  VALIDITY_STATE_PROPERTY,
+
+  lowercase,
+  uppercase,
+  manualLowercase,
+  manualUppercase,
+  nodeName_,
+  isArrayLike,
+  forEach,
+  forEachSorted,
+  reverseParams,
+  nextUid,
+  setHashKey,
+  extend,
+  toInt,
+  inherit,
+  merge,
+  noop,
+  identity,
+  valueFn,
+  isUndefined,
+  isDefined,
+  isObject,
+  isBlankObject,
+  isString,
+  isNumber,
+  isNumberNaN,
+  isDate,
+  isArray,
+  isFunction,
+  isRegExp,
+  isWindow,
+  isScope,
+  isFile,
+  isFormData,
+  isBlob,
+  isBoolean,
+  isPromiseLike,
+  trim,
+  escapeForRegexp,
+  isElement,
+  makeMap,
+  includes,
+  arrayRemove,
+  copy,
+  equals,
+  csp,
+  jq,
+  concat,
+  sliceArgs,
+  bind,
+  toJsonReplacer,
+  toJson,
+  fromJson,
+  convertTimezoneToLocal,
+  timezoneToOffset,
+  startingTag,
+  tryDecodeURIComponent,
+  parseKeyValue,
+  toKeyValue,
+  encodeUriSegment,
+  encodeUriQuery,
+  angularInit,
+  bootstrap,
+  getTestability,
+  snake_case,
+  bindJQuery,
+  assertArg,
+  assertArgFn,
+  assertNotHasOwnProperty,
+  getter,
+  getBlockNodes,
+  hasOwnProperty,
+  createMap,
+  stringify,
+
+  NODE_TYPE_ELEMENT,
+  NODE_TYPE_ATTRIBUTE,
+  NODE_TYPE_TEXT,
+  NODE_TYPE_COMMENT,
+  NODE_TYPE_DOCUMENT,
+  NODE_TYPE_DOCUMENT_FRAGMENT
+*/
+
+////////////////////////////////////
+
+/**
+ * @ngdoc module
+ * @name ng
+ * @module ng
+ * @installation
+ * @description
+ *
+ * # ng (core module)
+ * The ng module is loaded by default when an AngularJS application is started. The module itself
+ * contains the essential components for an AngularJS application to function. The table below
+ * lists a high level breakdown of each of the services/factories, filters, directives and testing
+ * components available within this core module.
+ *
+ * <div doc-module-components="ng"></div>
+ */
+
+var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
+
+// The name of a form control's ValidityState property.
+// This is used so that it's possible for internal tests to create mock ValidityStates.
+var VALIDITY_STATE_PROPERTY = 'validity';
+
+
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+var minErrConfig = {
+  objectMaxDepth: 5
+};
+
+ /**
+ * @ngdoc function
+ * @name angular.errorHandlingConfig
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Configure several aspects of error handling in AngularJS if used as a setter or return the
+ * current configuration if used as a getter. The following options are supported:
+ *
+ * - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages.
+ *
+ * Omitted or undefined options will leave the corresponding configuration values unchanged.
+ *
+ * @param {Object=} config - The configuration object. May only contain the options that need to be
+ *     updated. Supported keys:
+ *
+ * * `objectMaxDepth`  **{Number}** - The max depth for stringifying objects. Setting to a
+ *   non-positive or non-numeric value, removes the max depth limit.
+ *   Default: 5
+ */
+function errorHandlingConfig(config) {
+  if (isObject(config)) {
+    if (isDefined(config.objectMaxDepth)) {
+      minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN;
+    }
+  } else {
+    return minErrConfig;
+  }
+}
+
+/**
+ * @private
+ * @param {Number} maxDepth
+ * @return {boolean}
+ */
+function isValidObjectMaxDepth(maxDepth) {
+  return isNumber(maxDepth) && maxDepth > 0;
+}
+
+/**
+ * @ngdoc function
+ * @name angular.lowercase
+ * @module ng
+ * @kind function
+ *
+ * @deprecated
+ * sinceVersion="1.5.0"
+ * removeVersion="1.7.0"
+ * Use [String.prototype.toLowerCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) instead.
+ *
+ * @description Converts the specified string to lowercase.
+ * @param {string} string String to be converted to lowercase.
+ * @returns {string} Lowercased string.
+ */
+var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
+
+/**
+ * @ngdoc function
+ * @name angular.uppercase
+ * @module ng
+ * @kind function
+ *
+ * @deprecated
+ * sinceVersion="1.5.0"
+ * removeVersion="1.7.0"
+ * Use [String.prototype.toUpperCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) instead.
+ *
+ * @description Converts the specified string to uppercase.
+ * @param {string} string String to be converted to uppercase.
+ * @returns {string} Uppercased string.
+ */
+var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
+
+
+var manualLowercase = function(s) {
+  /* eslint-disable no-bitwise */
+  return isString(s)
+      ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
+      : s;
+  /* eslint-enable */
+};
+var manualUppercase = function(s) {
+  /* eslint-disable no-bitwise */
+  return isString(s)
+      ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
+      : s;
+  /* eslint-enable */
+};
+
+
+// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
+// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
+// with correct but slower alternatives. See https://github.com/angular/angular.js/issues/11387
+if ('i' !== 'I'.toLowerCase()) {
+  lowercase = manualLowercase;
+  uppercase = manualUppercase;
+}
+
+
+var
+    msie,             // holds major version number for IE, or NaN if UA is not IE.
+    jqLite,           // delay binding since jQuery could be loaded after us.
+    jQuery,           // delay binding
+    slice             = [].slice,
+    splice            = [].splice,
+    push              = [].push,
+    toString          = Object.prototype.toString,
+    getPrototypeOf    = Object.getPrototypeOf,
+    ngMinErr          = minErr('ng'),
+
+    /** @name angular */
+    angular           = window.angular || (window.angular = {}),
+    angularModule,
+    uid               = 0;
+
+// Support: IE 9-11 only
+/**
+ * documentMode is an IE-only property
+ * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
+ */
+msie = window.document.documentMode;
+
+
+/**
+ * @private
+ * @param {*} obj
+ * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
+ *                   String ...)
+ */
+function isArrayLike(obj) {
+
+  // `null`, `undefined` and `window` are not array-like
+  if (obj == null || isWindow(obj)) return false;
+
+  // arrays, strings and jQuery/jqLite objects are array like
+  // * jqLite is either the jQuery or jqLite constructor function
+  // * we have to check the existence of jqLite first as this method is called
+  //   via the forEach method when constructing the jqLite object in the first place
+  if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;
+
+  // Support: iOS 8.2 (not reproducible in simulator)
+  // "length" in obj used to prevent JIT error (gh-11508)
+  var length = 'length' in Object(obj) && obj.length;
+
+  // NodeList objects (with `item` method) and
+  // other objects with suitable length characteristics are array-like
+  return isNumber(length) &&
+    (length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item === 'function');
+
+}
+
+/**
+ * @ngdoc function
+ * @name angular.forEach
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Invokes the `iterator` function once for each item in `obj` collection, which can be either an
+ * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`
+ * is the value of an object property or an array element, `key` is the object property key or
+ * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
+ *
+ * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
+ * using the `hasOwnProperty` method.
+ *
+ * Unlike ES262's
+ * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
+ * providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
+ * return the value provided.
+ *
+   ```js
+     var values = {name: 'misko', gender: 'male'};
+     var log = [];
+     angular.forEach(values, function(value, key) {
+       this.push(key + ': ' + value);
+     }, log);
+     expect(log).toEqual(['name: misko', 'gender: male']);
+   ```
+ *
+ * @param {Object|Array} obj Object to iterate over.
+ * @param {Function} iterator Iterator function.
+ * @param {Object=} context Object to become context (`this`) for the iterator function.
+ * @returns {Object|Array} Reference to `obj`.
+ */
+
+function forEach(obj, iterator, context) {
+  var key, length;
+  if (obj) {
+    if (isFunction(obj)) {
+      for (key in obj) {
+        if (key !== 'prototype' && key !== 'length' && key !== 'name' && obj.hasOwnProperty(key)) {
+          iterator.call(context, obj[key], key, obj);
+        }
+      }
+    } else if (isArray(obj) || isArrayLike(obj)) {
+      var isPrimitive = typeof obj !== 'object';
+      for (key = 0, length = obj.length; key < length; key++) {
+        if (isPrimitive || key in obj) {
+          iterator.call(context, obj[key], key, obj);
+        }
+      }
+    } else if (obj.forEach && obj.forEach !== forEach) {
+        obj.forEach(iterator, context, obj);
+    } else if (isBlankObject(obj)) {
+      // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
+      for (key in obj) {
+        iterator.call(context, obj[key], key, obj);
+      }
+    } else if (typeof obj.hasOwnProperty === 'function') {
+      // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
+      for (key in obj) {
+        if (obj.hasOwnProperty(key)) {
+          iterator.call(context, obj[key], key, obj);
+        }
+      }
+    } else {
+      // Slow path for objects which do not have a method `hasOwnProperty`
+      for (key in obj) {
+        if (hasOwnProperty.call(obj, key)) {
+          iterator.call(context, obj[key], key, obj);
+        }
+      }
+    }
+  }
+  return obj;
+}
+
+function forEachSorted(obj, iterator, context) {
+  var keys = Object.keys(obj).sort();
+  for (var i = 0; i < keys.length; i++) {
+    iterator.call(context, obj[keys[i]], keys[i]);
+  }
+  return keys;
+}
+
+
+/**
+ * when using forEach the params are value, key, but it is often useful to have key, value.
+ * @param {function(string, *)} iteratorFn
+ * @returns {function(*, string)}
+ */
+function reverseParams(iteratorFn) {
+  return function(value, key) {iteratorFn(key, value);};
+}
+
+/**
+ * A consistent way of creating unique IDs in angular.
+ *
+ * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before
+ * we hit number precision issues in JavaScript.
+ *
+ * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M
+ *
+ * @returns {number} an unique alpha-numeric string
+ */
+function nextUid() {
+  return ++uid;
+}
+
+
+/**
+ * Set or clear the hashkey for an object.
+ * @param obj object
+ * @param h the hashkey (!truthy to delete the hashkey)
+ */
+function setHashKey(obj, h) {
+  if (h) {
+    obj.$$hashKey = h;
+  } else {
+    delete obj.$$hashKey;
+  }
+}
+
+
+function baseExtend(dst, objs, deep) {
+  var h = dst.$$hashKey;
+
+  for (var i = 0, ii = objs.length; i < ii; ++i) {
+    var obj = objs[i];
+    if (!isObject(obj) && !isFunction(obj)) continue;
+    var keys = Object.keys(obj);
+    for (var j = 0, jj = keys.length; j < jj; j++) {
+      var key = keys[j];
+      var src = obj[key];
+
+      if (deep && isObject(src)) {
+        if (isDate(src)) {
+          dst[key] = new Date(src.valueOf());
+        } else if (isRegExp(src)) {
+          dst[key] = new RegExp(src);
+        } else if (src.nodeName) {
+          dst[key] = src.cloneNode(true);
+        } else if (isElement(src)) {
+          dst[key] = src.clone();
+        } else {
+          if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
+          baseExtend(dst[key], [src], true);
+        }
+      } else {
+        dst[key] = src;
+      }
+    }
+  }
+
+  setHashKey(dst, h);
+  return dst;
+}
+
+/**
+ * @ngdoc function
+ * @name angular.extend
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
+ * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
+ * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
+ *
+ * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use
+ * {@link angular.merge} for this.
+ *
+ * @param {Object} dst Destination object.
+ * @param {...Object} src Source object(s).
+ * @returns {Object} Reference to `dst`.
+ */
+function extend(dst) {
+  return baseExtend(dst, slice.call(arguments, 1), false);
+}
+
+
+/**
+* @ngdoc function
+* @name angular.merge
+* @module ng
+* @kind function
+*
+* @description
+* Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
+* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
+* by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`.
+*
+* Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source
+* objects, performing a deep copy.
+*
+* @param {Object} dst Destination object.
+* @param {...Object} src Source object(s).
+* @returns {Object} Reference to `dst`.
+*/
+function merge(dst) {
+  return baseExtend(dst, slice.call(arguments, 1), true);
+}
+
+
+
+function toInt(str) {
+  return parseInt(str, 10);
+}
+
+var isNumberNaN = Number.isNaN || function isNumberNaN(num) {
+  // eslint-disable-next-line no-self-compare
+  return num !== num;
+};
+
+
+function inherit(parent, extra) {
+  return extend(Object.create(parent), extra);
+}
+
+/**
+ * @ngdoc function
+ * @name angular.noop
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * A function that performs no operations. This function can be useful when writing code in the
+ * functional style.
+   ```js
+     function foo(callback) {
+       var result = calculateResult();
+       (callback || angular.noop)(result);
+     }
+   ```
+ */
+function noop() {}
+noop.$inject = [];
+
+
+/**
+ * @ngdoc function
+ * @name angular.identity
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * A function that returns its first argument. This function is useful when writing code in the
+ * functional style.
+ *
+   ```js
+   function transformer(transformationFn, value) {
+     return (transformationFn || angular.identity)(value);
+   };
+
+   // E.g.
+   function getResult(fn, input) {
+     return (fn || angular.identity)(input);
+   };
+
+   getResult(function(n) { return n * 2; }, 21);   // returns 42
+   getResult(null, 21);                            // returns 21
+   getResult(undefined, 21);                       // returns 21
+   ```
+ *
+ * @param {*} value to be returned.
+ * @returns {*} the value passed in.
+ */
+function identity($) {return $;}
+identity.$inject = [];
+
+
+function valueFn(value) {return function valueRef() {return value;};}
+
+function hasCustomToString(obj) {
+  return isFunction(obj.toString) && obj.toString !== toString;
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isUndefined
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is undefined.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is undefined.
+ */
+function isUndefined(value) {return typeof value === 'undefined';}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isDefined
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is defined.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is defined.
+ */
+function isDefined(value) {return typeof value !== 'undefined';}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isObject
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
+ * considered to be objects. Note that JavaScript arrays are objects.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is an `Object` but not `null`.
+ */
+function isObject(value) {
+  // http://jsperf.com/isobject4
+  return value !== null && typeof value === 'object';
+}
+
+
+/**
+ * Determine if a value is an object with a null prototype
+ *
+ * @returns {boolean} True if `value` is an `Object` with a null prototype
+ */
+function isBlankObject(value) {
+  return value !== null && typeof value === 'object' && !getPrototypeOf(value);
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isString
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is a `String`.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `String`.
+ */
+function isString(value) {return typeof value === 'string';}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isNumber
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is a `Number`.
+ *
+ * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`.
+ *
+ * If you wish to exclude these then you can use the native
+ * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
+ * method.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `Number`.
+ */
+function isNumber(value) {return typeof value === 'number';}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isDate
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a value is a date.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `Date`.
+ */
+function isDate(value) {
+  return toString.call(value) === '[object Date]';
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isArray
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is an `Array`. Alias of Array.isArray.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is an `Array`.
+ */
+var isArray = Array.isArray;
+
+/**
+ * @ngdoc function
+ * @name angular.isFunction
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is a `Function`.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `Function`.
+ */
+function isFunction(value) {return typeof value === 'function';}
+
+
+/**
+ * Determines if a value is a regular expression object.
+ *
+ * @private
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `RegExp`.
+ */
+function isRegExp(value) {
+  return toString.call(value) === '[object RegExp]';
+}
+
+
+/**
+ * Checks if `obj` is a window object.
+ *
+ * @private
+ * @param {*} obj Object to check
+ * @returns {boolean} True if `obj` is a window obj.
+ */
+function isWindow(obj) {
+  return obj && obj.window === obj;
+}
+
+
+function isScope(obj) {
+  return obj && obj.$evalAsync && obj.$watch;
+}
+
+
+function isFile(obj) {
+  return toString.call(obj) === '[object File]';
+}
+
+
+function isFormData(obj) {
+  return toString.call(obj) === '[object FormData]';
+}
+
+
+function isBlob(obj) {
+  return toString.call(obj) === '[object Blob]';
+}
+
+
+function isBoolean(value) {
+  return typeof value === 'boolean';
+}
+
+
+function isPromiseLike(obj) {
+  return obj && isFunction(obj.then);
+}
+
+
+var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array]$/;
+function isTypedArray(value) {
+  return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));
+}
+
+function isArrayBuffer(obj) {
+  return toString.call(obj) === '[object ArrayBuffer]';
+}
+
+
+var trim = function(value) {
+  return isString(value) ? value.trim() : value;
+};
+
+// Copied from:
+// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
+// Prereq: s is a string.
+var escapeForRegexp = function(s) {
+  return s
+    .replace(/([-()[\]{}+?*.$^|,:#<!\\])/g, '\\$1')
+    // eslint-disable-next-line no-control-regex
+    .replace(/\x08/g, '\\x08');
+};
+
+
+/**
+ * @ngdoc function
+ * @name angular.isElement
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is a DOM element (or wrapped jQuery element).
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
+ */
+function isElement(node) {
+  return !!(node &&
+    (node.nodeName  // We are a direct element.
+    || (node.prop && node.attr && node.find)));  // We have an on and find method part of jQuery API.
+}
+
+/**
+ * @param str 'key1,key2,...'
+ * @returns {object} in the form of {key1:true, key2:true, ...}
+ */
+function makeMap(str) {
+  var obj = {}, items = str.split(','), i;
+  for (i = 0; i < items.length; i++) {
+    obj[items[i]] = true;
+  }
+  return obj;
+}
+
+
+function nodeName_(element) {
+  return lowercase(element.nodeName || (element[0] && element[0].nodeName));
+}
+
+function includes(array, obj) {
+  return Array.prototype.indexOf.call(array, obj) !== -1;
+}
+
+function arrayRemove(array, value) {
+  var index = array.indexOf(value);
+  if (index >= 0) {
+    array.splice(index, 1);
+  }
+  return index;
+}
+
+/**
+ * @ngdoc function
+ * @name angular.copy
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Creates a deep copy of `source`, which should be an object or an array.
+ *
+ * * If no destination is supplied, a copy of the object or array is created.
+ * * If a destination is provided, all of its elements (for arrays) or properties (for objects)
+ *   are deleted and then all elements/properties from the source are copied to it.
+ * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
+ * * If `source` is identical to `destination` an exception will be thrown.
+ *
+ * <br />
+ * <div class="alert alert-warning">
+ *   Only enumerable properties are taken into account. Non-enumerable properties (both on `source`
+ *   and on `destination`) will be ignored.
+ * </div>
+ *
+ * @param {*} source The source that will be used to make a copy.
+ *                   Can be any type, including primitives, `null`, and `undefined`.
+ * @param {(Object|Array)=} destination Destination into which the source is copied. If
+ *     provided, must be of the same type as `source`.
+ * @returns {*} The copy or updated `destination`, if `destination` was specified.
+ *
+ * @example
+  <example module="copyExample" name="angular-copy">
+    <file name="index.html">
+      <div ng-controller="ExampleController">
+        <form novalidate class="simple-form">
+          <label>Name: <input type="text" ng-model="user.name" /></label><br />
+          <label>Age:  <input type="number" ng-model="user.age" /></label><br />
+          Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
+                  <label><input type="radio" ng-model="user.gender" value="female" />female</label><br />
+          <button ng-click="reset()">RESET</button>
+          <button ng-click="update(user)">SAVE</button>
+        </form>
+        <pre>form = {{user | json}}</pre>
+        <pre>master = {{master | json}}</pre>
+      </div>
+    </file>
+    <file name="script.js">
+      // Module: copyExample
+      angular.
+        module('copyExample', []).
+        controller('ExampleController', ['$scope', function($scope) {
+          $scope.master = {};
+
+          $scope.reset = function() {
+            // Example with 1 argument
+            $scope.user = angular.copy($scope.master);
+          };
+
+          $scope.update = function(user) {
+            // Example with 2 arguments
+            angular.copy(user, $scope.master);
+          };
+
+          $scope.reset();
+        }]);
+    </file>
+  </example>
+ */
+function copy(source, destination, maxDepth) {
+  var stackSource = [];
+  var stackDest = [];
+  maxDepth = isValidObjectMaxDepth(maxDepth) ? maxDepth : NaN;
+
+  if (destination) {
+    if (isTypedArray(destination) || isArrayBuffer(destination)) {
+      throw ngMinErr('cpta', 'Can\'t copy! TypedArray destination cannot be mutated.');
+    }
+    if (source === destination) {
+      throw ngMinErr('cpi', 'Can\'t copy! Source and destination are identical.');
+    }
+
+    // Empty the destination object
+    if (isArray(destination)) {
+      destination.length = 0;
+    } else {
+      forEach(destination, function(value, key) {
+        if (key !== '$$hashKey') {
+          delete destination[key];
+        }
+      });
+    }
+
+    stackSource.push(source);
+    stackDest.push(destination);
+    return copyRecurse(source, destination, maxDepth);
+  }
+
+  return copyElement(source, maxDepth);
+
+  function copyRecurse(source, destination, maxDepth) {
+    maxDepth--;
+    if (maxDepth < 0) {
+      return '...';
+    }
+    var h = destination.$$hashKey;
+    var key;
+    if (isArray(source)) {
+      for (var i = 0, ii = source.length; i < ii; i++) {
+        destination.push(copyElement(source[i], maxDepth));
+      }
+    } else if (isBlankObject(source)) {
+      // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
+      for (key in source) {
+        destination[key] = copyElement(source[key], maxDepth);
+      }
+    } else if (source && typeof source.hasOwnProperty === 'function') {
+      // Slow path, which must rely on hasOwnProperty
+      for (key in source) {
+        if (source.hasOwnProperty(key)) {
+          destination[key] = copyElement(source[key], maxDepth);
+        }
+      }
+    } else {
+      // Slowest path --- hasOwnProperty can't be called as a method
+      for (key in source) {
+        if (hasOwnProperty.call(source, key)) {
+          destination[key] = copyElement(source[key], maxDepth);
+        }
+      }
+    }
+    setHashKey(destination, h);
+    return destination;
+  }
+
+  function copyElement(source, maxDepth) {
+    // Simple values
+    if (!isObject(source)) {
+      return source;
+    }
+
+    // Already copied values
+    var index = stackSource.indexOf(source);
+    if (index !== -1) {
+      return stackDest[index];
+    }
+
+    if (isWindow(source) || isScope(source)) {
+      throw ngMinErr('cpws',
+        'Can\'t copy! Making copies of Window or Scope instances is not supported.');
+    }
+
+    var needsRecurse = false;
+    var destination = copyType(source);
+
+    if (destination === undefined) {
+      destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
+      needsRecurse = true;
+    }
+
+    stackSource.push(source);
+    stackDest.push(destination);
+
+    return needsRecurse
+      ? copyRecurse(source, destination, maxDepth)
+      : destination;
+  }
+
+  function copyType(source) {
+    switch (toString.call(source)) {
+      case '[object Int8Array]':
+      case '[object Int16Array]':
+      case '[object Int32Array]':
+      case '[object Float32Array]':
+      case '[object Float64Array]':
+      case '[object Uint8Array]':
+      case '[object Uint8ClampedArray]':
+      case '[object Uint16Array]':
+      case '[object Uint32Array]':
+        return new source.constructor(copyElement(source.buffer), source.byteOffset, source.length);
+
+      case '[object ArrayBuffer]':
+        // Support: IE10
+        if (!source.slice) {
+          // If we're in this case we know the environment supports ArrayBuffer
+          /* eslint-disable no-undef */
+          var copied = new ArrayBuffer(source.byteLength);
+          new Uint8Array(copied).set(new Uint8Array(source));
+          /* eslint-enable */
+          return copied;
+        }
+        return source.slice(0);
+
+      case '[object Boolean]':
+      case '[object Number]':
+      case '[object String]':
+      case '[object Date]':
+        return new source.constructor(source.valueOf());
+
+      case '[object RegExp]':
+        var re = new RegExp(source.source, source.toString().match(/[^/]*$/)[0]);
+        re.lastIndex = source.lastIndex;
+        return re;
+
+      case '[object Blob]':
+        return new source.constructor([source], {type: source.type});
+    }
+
+    if (isFunction(source.cloneNode)) {
+      return source.cloneNode(true);
+    }
+  }
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.equals
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if two objects or two values are equivalent. Supports value types, regular
+ * expressions, arrays and objects.
+ *
+ * Two objects or values are considered equivalent if at least one of the following is true:
+ *
+ * * Both objects or values pass `===` comparison.
+ * * Both objects or values are of the same type and all of their properties are equal by
+ *   comparing them with `angular.equals`.
+ * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
+ * * Both values represent the same regular expression (In JavaScript,
+ *   /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
+ *   representation matches).
+ *
+ * During a property comparison, properties of `function` type and properties with names
+ * that begin with `$` are ignored.
+ *
+ * Scope and DOMWindow objects are being compared only by identify (`===`).
+ *
+ * @param {*} o1 Object or value to compare.
+ * @param {*} o2 Object or value to compare.
+ * @returns {boolean} True if arguments are equal.
+ *
+ * @example
+   <example module="equalsExample" name="equalsExample">
+     <file name="index.html">
+      <div ng-controller="ExampleController">
+        <form novalidate>
+          <h3>User 1</h3>
+          Name: <input type="text" ng-model="user1.name">
+          Age: <input type="number" ng-model="user1.age">
+
+          <h3>User 2</h3>
+          Name: <input type="text" ng-model="user2.name">
+          Age: <input type="number" ng-model="user2.age">
+
+          <div>
+            <br/>
+            <input type="button" value="Compare" ng-click="compare()">
+          </div>
+          User 1: <pre>{{user1 | json}}</pre>
+          User 2: <pre>{{user2 | json}}</pre>
+          Equal: <pre>{{result}}</pre>
+        </form>
+      </div>
+    </file>
+    <file name="script.js">
+        angular.module('equalsExample', []).controller('ExampleController', ['$scope', function($scope) {
+          $scope.user1 = {};
+          $scope.user2 = {};
+          $scope.compare = function() {
+            $scope.result = angular.equals($scope.user1, $scope.user2);
+          };
+        }]);
+    </file>
+  </example>
+ */
+function equals(o1, o2) {
+  if (o1 === o2) return true;
+  if (o1 === null || o2 === null) return false;
+  // eslint-disable-next-line no-self-compare
+  if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
+  var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
+  if (t1 === t2 && t1 === 'object') {
+    if (isArray(o1)) {
+      if (!isArray(o2)) return false;
+      if ((length = o1.length) === o2.length) {
+        for (key = 0; key < length; key++) {
+          if (!equals(o1[key], o2[key])) return false;
+        }
+        return true;
+      }
+    } else if (isDate(o1)) {
+      if (!isDate(o2)) return false;
+      return equals(o1.getTime(), o2.getTime());
+    } else if (isRegExp(o1)) {
+      if (!isRegExp(o2)) return false;
+      return o1.toString() === o2.toString();
+    } else {
+      if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
+        isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
+      keySet = createMap();
+      for (key in o1) {
+        if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
+        if (!equals(o1[key], o2[key])) return false;
+        keySet[key] = true;
+      }
+      for (key in o2) {
+        if (!(key in keySet) &&
+            key.charAt(0) !== '$' &&
+            isDefined(o2[key]) &&
+            !isFunction(o2[key])) return false;
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+var csp = function() {
+  if (!isDefined(csp.rules)) {
+
+
+    var ngCspElement = (window.document.querySelector('[ng-csp]') ||
+                    window.document.querySelector('[data-ng-csp]'));
+
+    if (ngCspElement) {
+      var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||
+                    ngCspElement.getAttribute('data-ng-csp');
+      csp.rules = {
+        noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),
+        noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)
+      };
+    } else {
+      csp.rules = {
+        noUnsafeEval: noUnsafeEval(),
+        noInlineStyle: false
+      };
+    }
+  }
+
+  return csp.rules;
+
+  function noUnsafeEval() {
+    try {
+      // eslint-disable-next-line no-new, no-new-func
+      new Function('');
+      return false;
+    } catch (e) {
+      return true;
+    }
+  }
+};
+
+/**
+ * @ngdoc directive
+ * @module ng
+ * @name ngJq
+ *
+ * @element ANY
+ * @param {string=} ngJq the name of the library available under `window`
+ * to be used for angular.element
+ * @description
+ * Use this directive to force the angular.element library.  This should be
+ * used to force either jqLite by leaving ng-jq blank or setting the name of
+ * the jquery variable under window (eg. jQuery).
+ *
+ * Since angular looks for this directive when it is loaded (doesn't wait for the
+ * DOMContentLoaded event), it must be placed on an element that comes before the script
+ * which loads angular. Also, only the first instance of `ng-jq` will be used and all
+ * others ignored.
+ *
+ * @example
+ * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
+ ```html
+ <!doctype html>
+ <html ng-app ng-jq>
+ ...
+ ...
+ </html>
+ ```
+ * @example
+ * This example shows how to use a jQuery based library of a different name.
+ * The library name must be available at the top most 'window'.
+ ```html
+ <!doctype html>
+ <html ng-app ng-jq="jQueryLib">
+ ...
+ ...
+ </html>
+ ```
+ */
+var jq = function() {
+  if (isDefined(jq.name_)) return jq.name_;
+  var el;
+  var i, ii = ngAttrPrefixes.length, prefix, name;
+  for (i = 0; i < ii; ++i) {
+    prefix = ngAttrPrefixes[i];
+    el = window.document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]');
+    if (el) {
+      name = el.getAttribute(prefix + 'jq');
+      break;
+    }
+  }
+
+  return (jq.name_ = name);
+};
+
+function concat(array1, array2, index) {
+  return array1.concat(slice.call(array2, index));
+}
+
+function sliceArgs(args, startIndex) {
+  return slice.call(args, startIndex || 0);
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.bind
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
+ * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
+ * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
+ * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).
+ *
+ * @param {Object} self Context which `fn` should be evaluated in.
+ * @param {function()} fn Function to be bound.
+ * @param {...*} args Optional arguments to be prebound to the `fn` function call.
+ * @returns {function()} Function that wraps the `fn` with all the specified bindings.
+ */
+function bind(self, fn) {
+  var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
+  if (isFunction(fn) && !(fn instanceof RegExp)) {
+    return curryArgs.length
+      ? function() {
+          return arguments.length
+            ? fn.apply(self, concat(curryArgs, arguments, 0))
+            : fn.apply(self, curryArgs);
+        }
+      : function() {
+          return arguments.length
+            ? fn.apply(self, arguments)
+            : fn.call(self);
+        };
+  } else {
+    // In IE, native methods are not functions so they cannot be bound (note: they don't need to be).
+    return fn;
+  }
+}
+
+
+function toJsonReplacer(key, value) {
+  var val = value;
+
+  if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
+    val = undefined;
+  } else if (isWindow(value)) {
+    val = '$WINDOW';
+  } else if (value &&  window.document === value) {
+    val = '$DOCUMENT';
+  } else if (isScope(value)) {
+    val = '$SCOPE';
+  }
+
+  return val;
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.toJson
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be
+ * stripped since angular uses this notation internally.
+ *
+ * @param {Object|Array|Date|string|number|boolean} obj Input to be serialized into JSON.
+ * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
+ *    If set to an integer, the JSON output will contain that many spaces per indentation.
+ * @returns {string|undefined} JSON-ified string representing `obj`.
+ * @knownIssue
+ *
+ * The Safari browser throws a `RangeError` instead of returning `null` when it tries to stringify a `Date`
+ * object with an invalid date value. The only reliable way to prevent this is to monkeypatch the
+ * `Date.prototype.toJSON` method as follows:
+ *
+ * ```
+ * var _DatetoJSON = Date.prototype.toJSON;
+ * Date.prototype.toJSON = function() {
+ *   try {
+ *     return _DatetoJSON.call(this);
+ *   } catch(e) {
+ *     if (e instanceof RangeError) {
+ *       return null;
+ *     }
+ *     throw e;
+ *   }
+ * };
+ * ```
+ *
+ * See https://github.com/angular/angular.js/pull/14221 for more information.
+ */
+function toJson(obj, pretty) {
+  if (isUndefined(obj)) return undefined;
+  if (!isNumber(pretty)) {
+    pretty = pretty ? 2 : null;
+  }
+  return JSON.stringify(obj, toJsonReplacer, pretty);
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.fromJson
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Deserializes a JSON string.
+ *
+ * @param {string} json JSON string to deserialize.
+ * @returns {Object|Array|string|number} Deserialized JSON string.
+ */
+function fromJson(json) {
+  return isString(json)
+      ? JSON.parse(json)
+      : json;
+}
+
+
+var ALL_COLONS = /:/g;
+function timezoneToOffset(timezone, fallback) {
+  // Support: IE 9-11 only, Edge 13-14+
+  // IE/Edge do not "understand" colon (`:`) in timezone
+  timezone = timezone.replace(ALL_COLONS, '');
+  var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
+  return isNumberNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
+}
+
+
+function addDateMinutes(date, minutes) {
+  date = new Date(date.getTime());
+  date.setMinutes(date.getMinutes() + minutes);
+  return date;
+}
+
+
+function convertTimezoneToLocal(date, timezone, reverse) {
+  reverse = reverse ? -1 : 1;
+  var dateTimezoneOffset = date.getTimezoneOffset();
+  var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
+  return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));
+}
+
+
+/**
+ * @returns {string} Returns the string representation of the element.
+ */
+function startingTag(element) {
+  element = jqLite(element).clone();
+  try {
+    // turns out IE does not let you set .html() on elements which
+    // are not allowed to have children. So we just ignore it.
+    element.empty();
+  } catch (e) { /* empty */ }
+  var elemHtml = jqLite('<div>').append(element).html();
+  try {
+    return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
+        elemHtml.
+          match(/^(<[^>]+>)/)[1].
+          replace(/^<([\w-]+)/, function(match, nodeName) {return '<' + lowercase(nodeName);});
+  } catch (e) {
+    return lowercase(elemHtml);
+  }
+
+}
+
+
+/////////////////////////////////////////////////
+
+/**
+ * Tries to decode the URI component without throwing an exception.
+ *
+ * @private
+ * @param str value potential URI component to check.
+ * @returns {boolean} True if `value` can be decoded
+ * with the decodeURIComponent function.
+ */
+function tryDecodeURIComponent(value) {
+  try {
+    return decodeURIComponent(value);
+  } catch (e) {
+    // Ignore any invalid uri component.
+  }
+}
+
+
+/**
+ * Parses an escaped url query string into key-value pairs.
+ * @returns {Object.<string,boolean|Array>}
+ */
+function parseKeyValue(/**string*/keyValue) {
+  var obj = {};
+  forEach((keyValue || '').split('&'), function(keyValue) {
+    var splitPoint, key, val;
+    if (keyValue) {
+      key = keyValue = keyValue.replace(/\+/g,'%20');
+      splitPoint = keyValue.indexOf('=');
+      if (splitPoint !== -1) {
+        key = keyValue.substring(0, splitPoint);
+        val = keyValue.substring(splitPoint + 1);
+      }
+      key = tryDecodeURIComponent(key);
+      if (isDefined(key)) {
+        val = isDefined(val) ? tryDecodeURIComponent(val) : true;
+        if (!hasOwnProperty.call(obj, key)) {
+          obj[key] = val;
+        } else if (isArray(obj[key])) {
+          obj[key].push(val);
+        } else {
+          obj[key] = [obj[key],val];
+        }
+      }
+    }
+  });
+  return obj;
+}
+
+function toKeyValue(obj) {
+  var parts = [];
+  forEach(obj, function(value, key) {
+    if (isArray(value)) {
+      forEach(value, function(arrayValue) {
+        parts.push(encodeUriQuery(key, true) +
+                   (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
+      });
+    } else {
+    parts.push(encodeUriQuery(key, true) +
+               (value === true ? '' : '=' + encodeUriQuery(value, true)));
+    }
+  });
+  return parts.length ? parts.join('&') : '';
+}
+
+
+/**
+ * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
+ * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
+ * segments:
+ *    segment       = *pchar
+ *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
+ *    pct-encoded   = "%" HEXDIG HEXDIG
+ *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
+ *                     / "*" / "+" / "," / ";" / "="
+ */
+function encodeUriSegment(val) {
+  return encodeUriQuery(val, true).
+             replace(/%26/gi, '&').
+             replace(/%3D/gi, '=').
+             replace(/%2B/gi, '+');
+}
+
+
+/**
+ * This method is intended for encoding *key* or *value* parts of query component. We need a custom
+ * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
+ * encoded per http://tools.ietf.org/html/rfc3986:
+ *    query         = *( pchar / "/" / "?" )
+ *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
+ *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ *    pct-encoded   = "%" HEXDIG HEXDIG
+ *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
+ *                     / "*" / "+" / "," / ";" / "="
+ */
+function encodeUriQuery(val, pctEncodeSpaces) {
+  return encodeURIComponent(val).
+             replace(/%40/gi, '@').
+             replace(/%3A/gi, ':').
+             replace(/%24/g, '$').
+             replace(/%2C/gi, ',').
+             replace(/%3B/gi, ';').
+             replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
+}
+
+var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
+
+function getNgAttribute(element, ngAttr) {
+  var attr, i, ii = ngAttrPrefixes.length;
+  for (i = 0; i < ii; ++i) {
+    attr = ngAttrPrefixes[i] + ngAttr;
+    if (isString(attr = element.getAttribute(attr))) {
+      return attr;
+    }
+  }
+  return null;
+}
+
+function allowAutoBootstrap(document) {
+  var script = document.currentScript;
+
+  if (!script) {
+    // IE does not have `document.currentScript`
+    return true;
+  }
+
+  // If the `currentScript` property has been clobbered just return false, since this indicates a probable attack
+  if (!(script instanceof window.HTMLScriptElement || script instanceof window.SVGScriptElement)) {
+    return false;
+  }
+
+  var attributes = script.attributes;
+  var srcs = [attributes.getNamedItem('src'), attributes.getNamedItem('href'), attributes.getNamedItem('xlink:href')];
+
+  return srcs.every(function(src) {
+    if (!src) {
+      return true;
+    }
+    if (!src.value) {
+      return false;
+    }
+
+    var link = document.createElement('a');
+    link.href = src.value;
+
+    if (document.location.origin === link.origin) {
+      // Same-origin resources are always allowed, even for non-whitelisted schemes.
+      return true;
+    }
+    // Disabled bootstrapping unless angular.js was loaded from a known scheme used on the web.
+    // This is to prevent angular.js bundled with browser extensions from being used to bypass the
+    // content security policy in web pages and other browser extensions.
+    switch (link.protocol) {
+      case 'http:':
+      case 'https:':
+      case 'ftp:':
+      case 'blob:':
+      case 'file:':
+      case 'data:':
+        return true;
+      default:
+        return false;
+    }
+  });
+}
+
+// Cached as it has to run during loading so that document.currentScript is available.
+var isAutoBootstrapAllowed = allowAutoBootstrap(window.document);
+
+/**
+ * @ngdoc directive
+ * @name ngApp
+ * @module ng
+ *
+ * @element ANY
+ * @param {angular.Module} ngApp an optional application
+ *   {@link angular.module module} name to load.
+ * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be
+ *   created in "strict-di" mode. This means that the application will fail to invoke functions which
+ *   do not use explicit function annotation (and are thus unsuitable for minification), as described
+ *   in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in
+ *   tracking down the root of these bugs.
+ *
+ * @description
+ *
+ * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
+ * designates the **root element** of the application and is typically placed near the root element
+ * of the page - e.g. on the `<body>` or `<html>` tags.
+ *
+ * There are a few things to keep in mind when using `ngApp`:
+ * - only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
+ *   found in the document will be used to define the root element to auto-bootstrap as an
+ *   application. To run multiple applications in an HTML document you must manually bootstrap them using
+ *   {@link angular.bootstrap} instead.
+ * - AngularJS applications cannot be nested within each other.
+ * - Do not use a directive that uses {@link ng.$compile#transclusion transclusion} on the same element as `ngApp`.
+ *   This includes directives such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and
+ *   {@link ngRoute.ngView `ngView`}.
+ *   Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
+ *   causing animations to stop working and making the injector inaccessible from outside the app.
+ *
+ * You can specify an **AngularJS module** to be used as the root module for the application.  This
+ * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It
+ * should contain the application code needed or have dependencies on other modules that will
+ * contain the code. See {@link angular.module} for more information.
+ *
+ * In the example below if the `ngApp` directive were not placed on the `html` element then the
+ * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
+ * would not be resolved to `3`.
+ *
+ * `ngApp` is the easiest, and most common way to bootstrap an application.
+ *
+ <example module="ngAppDemo" name="ng-app">
+   <file name="index.html">
+   <div ng-controller="ngAppDemoController">
+     I can add: {{a}} + {{b}} =  {{ a+b }}
+   </div>
+   </file>
+   <file name="script.js">
+   angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
+     $scope.a = 1;
+     $scope.b = 2;
+   });
+   </file>
+ </example>
+ *
+ * Using `ngStrictDi`, you would see something like this:
+ *
+ <example ng-app-included="true" name="strict-di">
+   <file name="index.html">
+   <div ng-app="ngAppStrictDemo" ng-strict-di>
+       <div ng-controller="GoodController1">
+           I can add: {{a}} + {{b}} =  {{ a+b }}
+
+           <p>This renders because the controller does not fail to
+              instantiate, by using explicit annotation style (see
+              script.js for details)
+           </p>
+       </div>
+
+       <div ng-controller="GoodController2">
+           Name: <input ng-model="name"><br />
+           Hello, {{name}}!
+
+           <p>This renders because the controller does not fail to
+              instantiate, by using explicit annotation style
+              (see script.js for details)
+           </p>
+       </div>
+
+       <div ng-controller="BadController">
+           I can add: {{a}} + {{b}} =  {{ a+b }}
+
+           <p>The controller could not be instantiated, due to relying
+              on automatic function annotations (which are disabled in
+              strict mode). As such, the content of this section is not
+              interpolated, and there should be an error in your web console.
+           </p>
+       </div>
+   </div>
+   </file>
+   <file name="script.js">
+   angular.module('ngAppStrictDemo', [])
+     // BadController will fail to instantiate, due to relying on automatic function annotation,
+     // rather than an explicit annotation
+     .controller('BadController', function($scope) {
+       $scope.a = 1;
+       $scope.b = 2;
+     })
+     // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,
+     // due to using explicit annotations using the array style and $inject property, respectively.
+     .controller('GoodController1', ['$scope', function($scope) {
+       $scope.a = 1;
+       $scope.b = 2;
+     }])
+     .controller('GoodController2', GoodController2);
+     function GoodController2($scope) {
+       $scope.name = 'World';
+     }
+     GoodController2.$inject = ['$scope'];
+   </file>
+   <file name="style.css">
+   div[ng-controller] {
+       margin-bottom: 1em;
+       -webkit-border-radius: 4px;
+       border-radius: 4px;
+       border: 1px solid;
+       padding: .5em;
+   }
+   div[ng-controller^=Good] {
+       border-color: #d6e9c6;
+       background-color: #dff0d8;
+       color: #3c763d;
+   }
+   div[ng-controller^=Bad] {
+       border-color: #ebccd1;
+       background-color: #f2dede;
+       color: #a94442;
+       margin-bottom: 0;
+   }
+   </file>
+ </example>
+ */
+function angularInit(element, bootstrap) {
+  var appElement,
+      module,
+      config = {};
+
+  // The element `element` has priority over any other element.
+  forEach(ngAttrPrefixes, function(prefix) {
+    var name = prefix + 'app';
+
+    if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
+      appElement = element;
+      module = element.getAttribute(name);
+    }
+  });
+  forEach(ngAttrPrefixes, function(prefix) {
+    var name = prefix + 'app';
+    var candidate;
+
+    if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
+      appElement = candidate;
+      module = candidate.getAttribute(name);
+    }
+  });
+  if (appElement) {
+    if (!isAutoBootstrapAllowed) {
+      window.console.error('Angular: disabling automatic bootstrap. <script> protocol indicates ' +
+          'an extension, document.location.href does not match.');
+      return;
+    }
+    config.strictDi = getNgAttribute(appElement, 'strict-di') !== null;
+    bootstrap(appElement, module ? [module] : [], config);
+  }
+}
+
+/**
+ * @ngdoc function
+ * @name angular.bootstrap
+ * @module ng
+ * @description
+ * Use this function to manually start up angular application.
+ *
+ * For more information, see the {@link guide/bootstrap Bootstrap guide}.
+ *
+ * Angular will detect if it has been loaded into the browser more than once and only allow the
+ * first loaded script to be bootstrapped and will report a warning to the browser console for
+ * each of the subsequent scripts. This prevents strange results in applications, where otherwise
+ * multiple instances of Angular try to work on the DOM.
+ *
+ * <div class="alert alert-warning">
+ * **Note:** Protractor based end-to-end tests cannot use this function to bootstrap manually.
+ * They must use {@link ng.directive:ngApp ngApp}.
+ * </div>
+ *
+ * <div class="alert alert-warning">
+ * **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion},
+ * such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.
+ * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
+ * causing animations to stop working and making the injector inaccessible from outside the app.
+ * </div>
+ *
+ * ```html
+ * <!doctype html>
+ * <html>
+ * <body>
+ * <div ng-controller="WelcomeController">
+ *   {{greeting}}
+ * </div>
+ *
+ * <script src="angular.js"></script>
+ * <script>
+ *   var app = angular.module('demo', [])
+ *   .controller('WelcomeController', function($scope) {
+ *       $scope.greeting = 'Welcome!';
+ *   });
+ *   angular.bootstrap(document, ['demo']);
+ * </script>
+ * </body>
+ * </html>
+ * ```
+ *
+ * @param {DOMElement} element DOM element which is the root of angular application.
+ * @param {Array<String|Function|Array>=} modules an array of modules to load into the application.
+ *     Each item in the array should be the name of a predefined module or a (DI annotated)
+ *     function that will be invoked by the injector as a `config` block.
+ *     See: {@link angular.module modules}
+ * @param {Object=} config an object for defining configuration options for the application. The
+ *     following keys are supported:
+ *
+ * * `strictDi` - disable automatic function annotation for the application. This is meant to
+ *   assist in finding bugs which break minified code. Defaults to `false`.
+ *
+ * @returns {auto.$injector} Returns the newly created injector for this app.
+ */
+function bootstrap(element, modules, config) {
+  if (!isObject(config)) config = {};
+  var defaultConfig = {
+    strictDi: false
+  };
+  config = extend(defaultConfig, config);
+  var doBootstrap = function() {
+    element = jqLite(element);
+
+    if (element.injector()) {
+      var tag = (element[0] === window.document) ? 'document' : startingTag(element);
+      // Encode angle brackets to prevent input from being sanitized to empty string #8683.
+      throw ngMinErr(
+          'btstrpd',
+          'App already bootstrapped with this element \'{0}\'',
+          tag.replace(/</,'&lt;').replace(/>/,'&gt;'));
+    }
+
+    modules = modules || [];
+    modules.unshift(['$provide', function($provide) {
+      $provide.value('$rootElement', element);
+    }]);
+
+    if (config.debugInfoEnabled) {
+      // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.
+      modules.push(['$compileProvider', function($compileProvider) {
+        $compileProvider.debugInfoEnabled(true);
+      }]);
+    }
+
+    modules.unshift('ng');
+    var injector = createInjector(modules, config.strictDi);
+    injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
+       function bootstrapApply(scope, element, compile, injector) {
+        scope.$apply(function() {
+          element.data('$injector', injector);
+          compile(element)(scope);
+        });
+      }]
+    );
+    return injector;
+  };
+
+  var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
+  var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
+
+  if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
+    config.debugInfoEnabled = true;
+    window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
+  }
+
+  if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
+    return doBootstrap();
+  }
+
+  window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
+  angular.resumeBootstrap = function(extraModules) {
+    forEach(extraModules, function(module) {
+      modules.push(module);
+    });
+    return doBootstrap();
+  };
+
+  if (isFunction(angular.resumeDeferredBootstrap)) {
+    angular.resumeDeferredBootstrap();
+  }
+}
+
+/**
+ * @ngdoc function
+ * @name angular.reloadWithDebugInfo
+ * @module ng
+ * @description
+ * Use this function to reload the current application with debug information turned on.
+ * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`.
+ *
+ * See {@link ng.$compileProvider#debugInfoEnabled} for more.
+ */
+function reloadWithDebugInfo() {
+  window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;
+  window.location.reload();
+}
+
+/**
+ * @name angular.getTestability
+ * @module ng
+ * @description
+ * Get the testability service for the instance of Angular on the given
+ * element.
+ * @param {DOMElement} element DOM element which is the root of angular application.
+ */
+function getTestability(rootElement) {
+  var injector = angular.element(rootElement).injector();
+  if (!injector) {
+    throw ngMinErr('test',
+      'no injector found for element argument to getTestability');
+  }
+  return injector.get('$$testability');
+}
+
+var SNAKE_CASE_REGEXP = /[A-Z]/g;
+function snake_case(name, separator) {
+  separator = separator || '_';
+  return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
+    return (pos ? separator : '') + letter.toLowerCase();
+  });
+}
+
+var bindJQueryFired = false;
+function bindJQuery() {
+  var originalCleanData;
+
+  if (bindJQueryFired) {
+    return;
+  }
+
+  // bind to jQuery if present;
+  var jqName = jq();
+  jQuery = isUndefined(jqName) ? window.jQuery :   // use jQuery (if present)
+           !jqName             ? undefined     :   // use jqLite
+                                 window[jqName];   // use jQuery specified by `ngJq`
+
+  // Use jQuery if it exists with proper functionality, otherwise default to us.
+  // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
+  // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
+  // versions. It will not work for sure with jQuery <1.7, though.
+  if (jQuery && jQuery.fn.on) {
+    jqLite = jQuery;
+    extend(jQuery.fn, {
+      scope: JQLitePrototype.scope,
+      isolateScope: JQLitePrototype.isolateScope,
+      controller: /** @type {?} */ (JQLitePrototype).controller,
+      injector: JQLitePrototype.injector,
+      inheritedData: JQLitePrototype.inheritedData
+    });
+
+    // All nodes removed from the DOM via various jQuery APIs like .remove()
+    // are passed through jQuery.cleanData. Monkey-patch this method to fire
+    // the $destroy event on all removed nodes.
+    originalCleanData = jQuery.cleanData;
+    jQuery.cleanData = function(elems) {
+      var events;
+      for (var i = 0, elem; (elem = elems[i]) != null; i++) {
+        events = jQuery._data(elem, 'events');
+        if (events && events.$destroy) {
+          jQuery(elem).triggerHandler('$destroy');
+        }
+      }
+      originalCleanData(elems);
+    };
+  } else {
+    jqLite = JQLite;
+  }
+
+  angular.element = jqLite;
+
+  // Prevent double-proxying.
+  bindJQueryFired = true;
+}
+
+/**
+ * throw error if the argument is falsy.
+ */
+function assertArg(arg, name, reason) {
+  if (!arg) {
+    throw ngMinErr('areq', 'Argument \'{0}\' is {1}', (name || '?'), (reason || 'required'));
+  }
+  return arg;
+}
+
+function assertArgFn(arg, name, acceptArrayAnnotation) {
+  if (acceptArrayAnnotation && isArray(arg)) {
+      arg = arg[arg.length - 1];
+  }
+
+  assertArg(isFunction(arg), name, 'not a function, got ' +
+      (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));
+  return arg;
+}
+
+/**
+ * throw error if the name given is hasOwnProperty
+ * @param  {String} name    the name to test
+ * @param  {String} context the context in which the name is used, such as module or directive
+ */
+function assertNotHasOwnProperty(name, context) {
+  if (name === 'hasOwnProperty') {
+    throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
+  }
+}
+
+/**
+ * Return the value accessible from the object by path. Any undefined traversals are ignored
+ * @param {Object} obj starting object
+ * @param {String} path path to traverse
+ * @param {boolean} [bindFnToScope=true]
+ * @returns {Object} value as accessible by path
+ */
+//TODO(misko): this function needs to be removed
+function getter(obj, path, bindFnToScope) {
+  if (!path) return obj;
+  var keys = path.split('.');
+  var key;
+  var lastInstance = obj;
+  var len = keys.length;
+
+  for (var i = 0; i < len; i++) {
+    key = keys[i];
+    if (obj) {
+      obj = (lastInstance = obj)[key];
+    }
+  }
+  if (!bindFnToScope && isFunction(obj)) {
+    return bind(lastInstance, obj);
+  }
+  return obj;
+}
+
+/**
+ * Return the DOM siblings between the first and last node in the given array.
+ * @param {Array} array like object
+ * @returns {Array} the inputted object or a jqLite collection containing the nodes
+ */
+function getBlockNodes(nodes) {
+  // TODO(perf): update `nodes` instead of creating a new object?
+  var node = nodes[0];
+  var endNode = nodes[nodes.length - 1];
+  var blockNodes;
+
+  for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {
+    if (blockNodes || nodes[i] !== node) {
+      if (!blockNodes) {
+        blockNodes = jqLite(slice.call(nodes, 0, i));
+      }
+      blockNodes.push(node);
+    }
+  }
+
+  return blockNodes || nodes;
+}
+
+
+/**
+ * Creates a new object without a prototype. This object is useful for lookup without having to
+ * guard against prototypically inherited properties via hasOwnProperty.
+ *
+ * Related micro-benchmarks:
+ * - http://jsperf.com/object-create2
+ * - http://jsperf.com/proto-map-lookup/2
+ * - http://jsperf.com/for-in-vs-object-keys2
+ *
+ * @returns {Object}
+ */
+function createMap() {
+  return Object.create(null);
+}
+
+function stringify(value) {
+  if (value == null) { // null || undefined
+    return '';
+  }
+  switch (typeof value) {
+    case 'string':
+      break;
+    case 'number':
+      value = '' + value;
+      break;
+    default:
+      if (hasCustomToString(value) && !isArray(value) && !isDate(value)) {
+        value = value.toString();
+      } else {
+        value = toJson(value);
+      }
+  }
+
+  return value;
+}
+
+var NODE_TYPE_ELEMENT = 1;
+var NODE_TYPE_ATTRIBUTE = 2;
+var NODE_TYPE_TEXT = 3;
+var NODE_TYPE_COMMENT = 8;
+var NODE_TYPE_DOCUMENT = 9;
+var NODE_TYPE_DOCUMENT_FRAGMENT = 11;
+
+/**
+ * @ngdoc type
+ * @name angular.Module
+ * @module ng
+ * @description
+ *
+ * Interface for configuring angular {@link angular.module modules}.
+ */
+
+function setupModuleLoader(window) {
+
+  var $injectorMinErr = minErr('$injector');
+  var ngMinErr = minErr('ng');
+
+  function ensure(obj, name, factory) {
+    return obj[name] || (obj[name] = factory());
+  }
+
+  var angular = ensure(window, 'angular', Object);
+
+  // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
+  angular.$$minErr = angular.$$minErr || minErr;
+
+  return ensure(angular, 'module', function() {
+    /** @type {Object.<string, angular.Module>} */
+    var modules = {};
+
+    /**
+     * @ngdoc function
+     * @name angular.module
+     * @module ng
+     * @description
+     *
+     * The `angular.module` is a global place for creating, registering and retrieving Angular
+     * modules.
+     * All modules (angular core or 3rd party) that should be available to an application must be
+     * registered using this mechanism.
+     *
+     * Passing one argument retrieves an existing {@link angular.Module},
+     * whereas passing more than one argument creates a new {@link angular.Module}
+     *
+     *
+     * # Module
+     *
+     * A module is a collection of services, directives, controllers, filters, and configuration information.
+     * `angular.module` is used to configure the {@link auto.$injector $injector}.
+     *
+     * ```js
+     * // Create a new module
+     * var myModule = angular.module('myModule', []);
+     *
+     * // register a new service
+     * myModule.value('appName', 'MyCoolApp');
+     *
+     * // configure existing services inside initialization blocks.
+     * myModule.config(['$locationProvider', function($locationProvider) {
+     *   // Configure existing providers
+     *   $locationProvider.hashPrefix('!');
+     * }]);
+     * ```
+     *
+     * Then you can create an injector and load your modules like this:
+     *
+     * ```js
+     * var injector = angular.injector(['ng', 'myModule'])
+     * ```
+     *
+     * However it's more likely that you'll just use
+     * {@link ng.directive:ngApp ngApp} or
+     * {@link angular.bootstrap} to simplify this process for you.
+     *
+     * @param {!string} name The name of the module to create or retrieve.
+     * @param {!Array.<string>=} requires If specified then new module is being created. If
+     *        unspecified then the module is being retrieved for further configuration.
+     * @param {Function=} configFn Optional configuration function for the module. Same as
+     *        {@link angular.Module#config Module#config()}.
+     * @returns {angular.Module} new module with the {@link angular.Module} api.
+     */
+    return function module(name, requires, configFn) {
+
+      var info = {};
+
+      var assertNotHasOwnProperty = function(name, context) {
+        if (name === 'hasOwnProperty') {
+          throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
+        }
+      };
+
+      assertNotHasOwnProperty(name, 'module');
+      if (requires && modules.hasOwnProperty(name)) {
+        modules[name] = null;
+      }
+      return ensure(modules, name, function() {
+        if (!requires) {
+          throw $injectorMinErr('nomod', 'Module \'{0}\' is not available! You either misspelled ' +
+             'the module name or forgot to load it. If registering a module ensure that you ' +
+             'specify the dependencies as the second argument.', name);
+        }
+
+        /** @type {!Array.<Array.<*>>} */
+        var invokeQueue = [];
+
+        /** @type {!Array.<Function>} */
+        var configBlocks = [];
+
+        /** @type {!Array.<Function>} */
+        var runBlocks = [];
+
+        var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
+
+        /** @type {angular.Module} */
+        var moduleInstance = {
+          // Private state
+          _invokeQueue: invokeQueue,
+          _configBlocks: configBlocks,
+          _runBlocks: runBlocks,
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#info
+           * @module ng
+           *
+           * @param {Object=} info Information about the module
+           * @returns {Object|Module} The current info object for this module if called as a getter,
+           *                          or `this` if called as a setter.
+           *
+           * @description
+           * Read and write custom information about this module.
+           * For example you could put the version of the module in here.
+           *
+           * ```js
+           * angular.module('myModule', []).info({ version: '1.0.0' });
+           * ```
+           *
+           * The version could then be read back out by accessing the module elsewhere:
+           *
+           * ```
+           * var version = angular.module('myModule').info().version;
+           * ```
+           *
+           * You can also retrieve this information during runtime via the
+           * {@link $injector#modules `$injector.modules`} property:
+           *
+           * ```js
+           * var version = $injector.modules['myModule'].info().version;
+           * ```
+           */
+          info: function(value) {
+            if (isDefined(value)) {
+              if (!isObject(value)) throw ngMinErr('aobj', 'Argument \'{0}\' must be an object', 'value');
+              info = value;
+              return this;
+            }
+            return info;
+          },
+
+          /**
+           * @ngdoc property
+           * @name angular.Module#requires
+           * @module ng
+           *
+           * @description
+           * Holds the list of modules which the injector will load before the current module is
+           * loaded.
+           */
+          requires: requires,
+
+          /**
+           * @ngdoc property
+           * @name angular.Module#name
+           * @module ng
+           *
+           * @description
+           * Name of the module.
+           */
+          name: name,
+
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#provider
+           * @module ng
+           * @param {string} name service name
+           * @param {Function} providerType Construction function for creating new instance of the
+           *                                service.
+           * @description
+           * See {@link auto.$provide#provider $provide.provider()}.
+           */
+          provider: invokeLaterAndSetModuleName('$provide', 'provider'),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#factory
+           * @module ng
+           * @param {string} name service name
+           * @param {Function} providerFunction Function for creating new instance of the service.
+           * @description
+           * See {@link auto.$provide#factory $provide.factory()}.
+           */
+          factory: invokeLaterAndSetModuleName('$provide', 'factory'),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#service
+           * @module ng
+           * @param {string} name service name
+           * @param {Function} constructor A constructor function that will be instantiated.
+           * @description
+           * See {@link auto.$provide#service $provide.service()}.
+           */
+          service: invokeLaterAndSetModuleName('$provide', 'service'),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#value
+           * @module ng
+           * @param {string} name service name
+           * @param {*} object Service instance object.
+           * @description
+           * See {@link auto.$provide#value $provide.value()}.
+           */
+          value: invokeLater('$provide', 'value'),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#constant
+           * @module ng
+           * @param {string} name constant name
+           * @param {*} object Constant value.
+           * @description
+           * Because the constants are fixed, they get applied before other provide methods.
+           * See {@link auto.$provide#constant $provide.constant()}.
+           */
+          constant: invokeLater('$provide', 'constant', 'unshift'),
+
+           /**
+           * @ngdoc method
+           * @name angular.Module#decorator
+           * @module ng
+           * @param {string} name The name of the service to decorate.
+           * @param {Function} decorFn This function will be invoked when the service needs to be
+           *                           instantiated and should return the decorated service instance.
+           * @description
+           * See {@link auto.$provide#decorator $provide.decorator()}.
+           */
+          decorator: invokeLaterAndSetModuleName('$provide', 'decorator', configBlocks),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#animation
+           * @module ng
+           * @param {string} name animation name
+           * @param {Function} animationFactory Factory function for creating new instance of an
+           *                                    animation.
+           * @description
+           *
+           * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
+           *
+           *
+           * Defines an animation hook that can be later used with
+           * {@link $animate $animate} service and directives that use this service.
+           *
+           * ```js
+           * module.animation('.animation-name', function($inject1, $inject2) {
+           *   return {
+           *     eventName : function(element, done) {
+           *       //code to run the animation
+           *       //once complete, then run done()
+           *       return function cancellationFunction(element) {
+           *         //code to cancel the animation
+           *       }
+           *     }
+           *   }
+           * })
+           * ```
+           *
+           * See {@link ng.$animateProvider#register $animateProvider.register()} and
+           * {@link ngAnimate ngAnimate module} for more information.
+           */
+          animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#filter
+           * @module ng
+           * @param {string} name Filter name - this must be a valid angular expression identifier
+           * @param {Function} filterFactory Factory function for creating new instance of filter.
+           * @description
+           * See {@link ng.$filterProvider#register $filterProvider.register()}.
+           *
+           * <div class="alert alert-warning">
+           * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
+           * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
+           * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
+           * (`myapp_subsection_filterx`).
+           * </div>
+           */
+          filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#controller
+           * @module ng
+           * @param {string|Object} name Controller name, or an object map of controllers where the
+           *    keys are the names and the values are the constructors.
+           * @param {Function} constructor Controller constructor function.
+           * @description
+           * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
+           */
+          controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#directive
+           * @module ng
+           * @param {string|Object} name Directive name, or an object map of directives where the
+           *    keys are the names and the values are the factories.
+           * @param {Function} directiveFactory Factory function for creating new instance of
+           * directives.
+           * @description
+           * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
+           */
+          directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#component
+           * @module ng
+           * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp)
+           * @param {Object} options Component definition object (a simplified
+           *    {@link ng.$compile#directive-definition-object directive definition object})
+           *
+           * @description
+           * See {@link ng.$compileProvider#component $compileProvider.component()}.
+           */
+          component: invokeLaterAndSetModuleName('$compileProvider', 'component'),
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#config
+           * @module ng
+           * @param {Function} configFn Execute this function on module load. Useful for service
+           *    configuration.
+           * @description
+           * Use this method to register work which needs to be performed on module loading.
+           * For more about how to configure services, see
+           * {@link providers#provider-recipe Provider Recipe}.
+           */
+          config: config,
+
+          /**
+           * @ngdoc method
+           * @name angular.Module#run
+           * @module ng
+           * @param {Function} initializationFn Execute this function after injector creation.
+           *    Useful for application initialization.
+           * @description
+           * Use this method to register work which should be performed when the injector is done
+           * loading all modules.
+           */
+          run: function(block) {
+            runBlocks.push(block);
+            return this;
+          }
+        };
+
+        if (configFn) {
+          config(configFn);
+        }
+
+        return moduleInstance;
+
+        /**
+         * @param {string} provider
+         * @param {string} method
+         * @param {String=} insertMethod
+         * @returns {angular.Module}
+         */
+        function invokeLater(provider, method, insertMethod, queue) {
+          if (!queue) queue = invokeQueue;
+          return function() {
+            queue[insertMethod || 'push']([provider, method, arguments]);
+            return moduleInstance;
+          };
+        }
+
+        /**
+         * @param {string} provider
+         * @param {string} method
+         * @returns {angular.Module}
+         */
+        function invokeLaterAndSetModuleName(provider, method, queue) {
+          if (!queue) queue = invokeQueue;
+          return function(recipeName, factoryFunction) {
+            if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
+            queue.push([provider, method, arguments]);
+            return moduleInstance;
+          };
+        }
+      });
+    };
+  });
+
+}
+
+/* global shallowCopy: true */
+
+/**
+ * Creates a shallow copy of an object, an array or a primitive.
+ *
+ * Assumes that there are no proto properties for objects.
+ */
+function shallowCopy(src, dst) {
+  if (isArray(src)) {
+    dst = dst || [];
+
+    for (var i = 0, ii = src.length; i < ii; i++) {
+      dst[i] = src[i];
+    }
+  } else if (isObject(src)) {
+    dst = dst || {};
+
+    for (var key in src) {
+      if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
+        dst[key] = src[key];
+      }
+    }
+  }
+
+  return dst || src;
+}
+
+/* global toDebugString: true */
+
+function serializeObject(obj, maxDepth) {
+  var seen = [];
+
+  // There is no direct way to stringify object until reaching a specific depth
+  // and a very deep object can cause a performance issue, so we copy the object
+  // based on this specific depth and then stringify it.
+  if (isValidObjectMaxDepth(maxDepth)) {
+    obj = copy(obj, null, maxDepth);
+  }
+  return JSON.stringify(obj, function(key, val) {
+    val = toJsonReplacer(key, val);
+    if (isObject(val)) {
+
+      if (seen.indexOf(val) >= 0) return '...';
+
+      seen.push(val);
+    }
+    return val;
+  });
+}
+
+function toDebugString(obj, maxDepth) {
+  if (typeof obj === 'function') {
+    return obj.toString().replace(/ \{[\s\S]*$/, '');
+  } else if (isUndefined(obj)) {
+    return 'undefined';
+  } else if (typeof obj !== 'string') {
+    return serializeObject(obj, maxDepth);
+  }
+  return obj;
+}
+
+/* global angularModule: true,
+  version: true,
+
+  $CompileProvider,
+
+  htmlAnchorDirective,
+  inputDirective,
+  inputDirective,
+  formDirective,
+  scriptDirective,
+  selectDirective,
+  optionDirective,
+  ngBindDirective,
+  ngBindHtmlDirective,
+  ngBindTemplateDirective,
+  ngClassDirective,
+  ngClassEvenDirective,
+  ngClassOddDirective,
+  ngCloakDirective,
+  ngControllerDirective,
+  ngFormDirective,
+  ngHideDirective,
+  ngIfDirective,
+  ngIncludeDirective,
+  ngIncludeFillContentDirective,
+  ngInitDirective,
+  ngNonBindableDirective,
+  ngPluralizeDirective,
+  ngRepeatDirective,
+  ngShowDirective,
+  ngStyleDirective,
+  ngSwitchDirective,
+  ngSwitchWhenDirective,
+  ngSwitchDefaultDirective,
+  ngOptionsDirective,
+  ngTranscludeDirective,
+  ngModelDirective,
+  ngListDirective,
+  ngChangeDirective,
+  patternDirective,
+  patternDirective,
+  requiredDirective,
+  requiredDirective,
+  minlengthDirective,
+  minlengthDirective,
+  maxlengthDirective,
+  maxlengthDirective,
+  ngValueDirective,
+  ngModelOptionsDirective,
+  ngAttributeAliasDirectives,
+  ngEventDirectives,
+
+  $AnchorScrollProvider,
+  $AnimateProvider,
+  $CoreAnimateCssProvider,
+  $$CoreAnimateJsProvider,
+  $$CoreAnimateQueueProvider,
+  $$AnimateRunnerFactoryProvider,
+  $$AnimateAsyncRunFactoryProvider,
+  $BrowserProvider,
+  $CacheFactoryProvider,
+  $ControllerProvider,
+  $DateProvider,
+  $DocumentProvider,
+  $$IsDocumentHiddenProvider,
+  $ExceptionHandlerProvider,
+  $FilterProvider,
+  $$ForceReflowProvider,
+  $InterpolateProvider,
+  $IntervalProvider,
+  $HttpProvider,
+  $HttpParamSerializerProvider,
+  $HttpParamSerializerJQLikeProvider,
+  $HttpBackendProvider,
+  $xhrFactoryProvider,
+  $jsonpCallbacksProvider,
+  $LocationProvider,
+  $LogProvider,
+  $$MapProvider,
+  $ParseProvider,
+  $RootScopeProvider,
+  $QProvider,
+  $$QProvider,
+  $$SanitizeUriProvider,
+  $SceProvider,
+  $SceDelegateProvider,
+  $SnifferProvider,
+  $TemplateCacheProvider,
+  $TemplateRequestProvider,
+  $$TestabilityProvider,
+  $TimeoutProvider,
+  $$RAFProvider,
+  $WindowProvider,
+  $$jqLiteProvider,
+  $$CookieReaderProvider
+*/
+
+
+/**
+ * @ngdoc object
+ * @name angular.version
+ * @module ng
+ * @description
+ * An object that contains information about the current AngularJS version.
+ *
+ * This object has the following properties:
+ *
+ * - `full` – `{string}` – Full version string, such as "0.9.18".
+ * - `major` – `{number}` – Major version number, such as "0".
+ * - `minor` – `{number}` – Minor version number, such as "9".
+ * - `dot` – `{number}` – Dot version number, such as "18".
+ * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
+ */
+var version = {
+  // These placeholder strings will be replaced by grunt's `build` task.
+  // They need to be double- or single-quoted.
+  full: '1.6.3',
+  major: 1,
+  minor: 6,
+  dot: 3,
+  codeName: 'scriptalicious-bootstrapping'
+};
+
+
+function publishExternalAPI(angular) {
+  extend(angular, {
+    'errorHandlingConfig': errorHandlingConfig,
+    'bootstrap': bootstrap,
+    'copy': copy,
+    'extend': extend,
+    'merge': merge,
+    'equals': equals,
+    'element': jqLite,
+    'forEach': forEach,
+    'injector': createInjector,
+    'noop': noop,
+    'bind': bind,
+    'toJson': toJson,
+    'fromJson': fromJson,
+    'identity': identity,
+    'isUndefined': isUndefined,
+    'isDefined': isDefined,
+    'isString': isString,
+    'isFunction': isFunction,
+    'isObject': isObject,
+    'isNumber': isNumber,
+    'isElement': isElement,
+    'isArray': isArray,
+    'version': version,
+    'isDate': isDate,
+    'lowercase': lowercase,
+    'uppercase': uppercase,
+    'callbacks': {$$counter: 0},
+    'getTestability': getTestability,
+    'reloadWithDebugInfo': reloadWithDebugInfo,
+    '$$minErr': minErr,
+    '$$csp': csp,
+    '$$encodeUriSegment': encodeUriSegment,
+    '$$encodeUriQuery': encodeUriQuery,
+    '$$stringify': stringify
+  });
+
+  angularModule = setupModuleLoader(window);
+
+  angularModule('ng', ['ngLocale'], ['$provide',
+    function ngModule($provide) {
+      // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
+      $provide.provider({
+        $$sanitizeUri: $$SanitizeUriProvider
+      });
+      $provide.provider('$compile', $CompileProvider).
+        directive({
+            a: htmlAnchorDirective,
+            input: inputDirective,
+            textarea: inputDirective,
+            form: formDirective,
+            script: scriptDirective,
+            select: selectDirective,
+            option: optionDirective,
+            ngBind: ngBindDirective,
+            ngBindHtml: ngBindHtmlDirective,
+            ngBindTemplate: ngBindTemplateDirective,
+            ngClass: ngClassDirective,
+            ngClassEven: ngClassEvenDirective,
+            ngClassOdd: ngClassOddDirective,
+            ngCloak: ngCloakDirective,
+            ngController: ngControllerDirective,
+            ngForm: ngFormDirective,
+            ngHide: ngHideDirective,
+            ngIf: ngIfDirective,
+            ngInclude: ngIncludeDirective,
+            ngInit: ngInitDirective,
+            ngNonBindable: ngNonBindableDirective,
+            ngPluralize: ngPluralizeDirective,
+            ngRepeat: ngRepeatDirective,
+            ngShow: ngShowDirective,
+            ngStyle: ngStyleDirective,
+            ngSwitch: ngSwitchDirective,
+            ngSwitchWhen: ngSwitchWhenDirective,
+            ngSwitchDefault: ngSwitchDefaultDirective,
+            ngOptions: ngOptionsDirective,
+            ngTransclude: ngTranscludeDirective,
+            ngModel: ngModelDirective,
+            ngList: ngListDirective,
+            ngChange: ngChangeDirective,
+            pattern: patternDirective,
+            ngPattern: patternDirective,
+            required: requiredDirective,
+            ngRequired: requiredDirective,
+            minlength: minlengthDirective,
+            ngMinlength: minlengthDirective,
+            maxlength: maxlengthDirective,
+            ngMaxlength: maxlengthDirective,
+            ngValue: ngValueDirective,
+            ngModelOptions: ngModelOptionsDirective
+        }).
+        directive({
+          ngInclude: ngIncludeFillContentDirective
+        }).
+        directive(ngAttributeAliasDirectives).
+        directive(ngEventDirectives);
+      $provide.provider({
+        $anchorScroll: $AnchorScrollProvider,
+        $animate: $AnimateProvider,
+        $animateCss: $CoreAnimateCssProvider,
+        $$animateJs: $$CoreAnimateJsProvider,
+        $$animateQueue: $$CoreAnimateQueueProvider,
+        $$AnimateRunner: $$AnimateRunnerFactoryProvider,
+        $$animateAsyncRun: $$AnimateAsyncRunFactoryProvider,
+        $browser: $BrowserProvider,
+        $cacheFactory: $CacheFactoryProvider,
+        $controller: $ControllerProvider,
+        $document: $DocumentProvider,
+        $$isDocumentHidden: $$IsDocumentHiddenProvider,
+        $exceptionHandler: $ExceptionHandlerProvider,
+        $filter: $FilterProvider,
+        $$forceReflow: $$ForceReflowProvider,
+        $interpolate: $InterpolateProvider,
+        $interval: $IntervalProvider,
+        $http: $HttpProvider,
+        $httpParamSerializer: $HttpParamSerializerProvider,
+        $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,
+        $httpBackend: $HttpBackendProvider,
+        $xhrFactory: $xhrFactoryProvider,
+        $jsonpCallbacks: $jsonpCallbacksProvider,
+        $location: $LocationProvider,
+        $log: $LogProvider,
+        $parse: $ParseProvider,
+        $rootScope: $RootScopeProvider,
+        $q: $QProvider,
+        $$q: $$QProvider,
+        $sce: $SceProvider,
+        $sceDelegate: $SceDelegateProvider,
+        $sniffer: $SnifferProvider,
+        $templateCache: $TemplateCacheProvider,
+        $templateRequest: $TemplateRequestProvider,
+        $$testability: $$TestabilityProvider,
+        $timeout: $TimeoutProvider,
+        $window: $WindowProvider,
+        $$rAF: $$RAFProvider,
+        $$jqLite: $$jqLiteProvider,
+        $$Map: $$MapProvider,
+        $$cookieReader: $$CookieReaderProvider
+      });
+    }
+  ])
+  .info({ angularVersion: '1.6.3' });
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *     Any commits to this file should be reviewed with security in mind.  *
+ *   Changes to this file can potentially create security vulnerabilities. *
+ *          An approval from 2 Core members with history of modifying      *
+ *                         this file is required.                          *
+ *                                                                         *
+ *  Does the change somehow allow for arbitrary javascript to be executed? *
+ *    Or allows for someone to change the prototype of built-in objects?   *
+ *     Or gives undesired access to variables likes document or window?    *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* global
+  JQLitePrototype: true,
+  BOOLEAN_ATTR: true,
+  ALIASED_ATTR: true
+*/
+
+//////////////////////////////////
+//JQLite
+//////////////////////////////////
+
+/**
+ * @ngdoc function
+ * @name angular.element
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.
+ *
+ * If jQuery is available, `angular.element` is an alias for the
+ * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element`
+ * delegates to Angular's built-in subset of jQuery, called "jQuery lite" or **jqLite**.
+ *
+ * jqLite is a tiny, API-compatible subset of jQuery that allows
+ * Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most
+ * commonly needed functionality with the goal of having a very small footprint.
+ *
+ * To use `jQuery`, simply ensure it is loaded before the `angular.js` file. You can also use the
+ * {@link ngJq `ngJq`} directive to specify that jqlite should be used over jQuery, or to use a
+ * specific version of jQuery if multiple versions exist on the page.
+ *
+ * <div class="alert alert-info">**Note:** All element references in Angular are always wrapped with jQuery or
+ * jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.</div>
+ *
+ * <div class="alert alert-warning">**Note:** Keep in mind that this function will not find elements
+ * by tag name / CSS selector. For lookups by tag name, try instead `angular.element(document).find(...)`
+ * or `$document.find()`, or use the standard DOM APIs, e.g. `document.querySelectorAll()`.</div>
+ *
+ * ## Angular's jqLite
+ * jqLite provides only the following jQuery methods:
+ *
+ * - [`addClass()`](http://api.jquery.com/addClass/) - Does not support a function as first argument
+ * - [`after()`](http://api.jquery.com/after/)
+ * - [`append()`](http://api.jquery.com/append/)
+ * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
+ * - [`bind()`](http://api.jquery.com/bind/) (_deprecated_, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData
+ * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
+ * - [`clone()`](http://api.jquery.com/clone/)
+ * - [`contents()`](http://api.jquery.com/contents/)
+ * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`.
+ *   As a setter, does not convert numbers to strings or append 'px', and also does not have automatic property prefixing.
+ * - [`data()`](http://api.jquery.com/data/)
+ * - [`detach()`](http://api.jquery.com/detach/)
+ * - [`empty()`](http://api.jquery.com/empty/)
+ * - [`eq()`](http://api.jquery.com/eq/)
+ * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name
+ * - [`hasClass()`](http://api.jquery.com/hasClass/)
+ * - [`html()`](http://api.jquery.com/html/)
+ * - [`next()`](http://api.jquery.com/next/) - Does not support selectors
+ * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
+ * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter
+ * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
+ * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
+ * - [`prepend()`](http://api.jquery.com/prepend/)
+ * - [`prop()`](http://api.jquery.com/prop/)
+ * - [`ready()`](http://api.jquery.com/ready/) (_deprecated_, use `angular.element(callback)` instead of `angular.element(document).ready(callback)`)
+ * - [`remove()`](http://api.jquery.com/remove/)
+ * - [`removeAttr()`](http://api.jquery.com/removeAttr/) - Does not support multiple attributes
+ * - [`removeClass()`](http://api.jquery.com/removeClass/) - Does not support a function as first argument
+ * - [`removeData()`](http://api.jquery.com/removeData/)
+ * - [`replaceWith()`](http://api.jquery.com/replaceWith/)
+ * - [`text()`](http://api.jquery.com/text/)
+ * - [`toggleClass()`](http://api.jquery.com/toggleClass/) - Does not support a function as first argument
+ * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers
+ * - [`unbind()`](http://api.jquery.com/unbind/) (_deprecated_, use [`off()`](http://api.jquery.com/off/)) - Does not support namespaces or event object as parameter
+ * - [`val()`](http://api.jquery.com/val/)
+ * - [`wrap()`](http://api.jquery.com/wrap/)
+ *
+ * ## jQuery/jqLite Extras
+ * Angular also provides the following additional methods and events to both jQuery and jqLite:
+ *
+ * ### Events
+ * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
+ *    on all DOM nodes being removed.  This can be used to clean up any 3rd party bindings to the DOM
+ *    element before it is removed.
+ *
+ * ### Methods
+ * - `controller(name)` - retrieves the controller of the current element or its parent. By default
+ *   retrieves controller associated with the `ngController` directive. If `name` is provided as
+ *   camelCase directive name, then the controller for this directive will be retrieved (e.g.
+ *   `'ngModel'`).
+ * - `injector()` - retrieves the injector of the current element or its parent.
+ * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current
+ *   element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to
+ *   be enabled.
+ * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the
+ *   current element. This getter should be used only on elements that contain a directive which starts a new isolate
+ *   scope. Calling `scope()` on this element always returns the original non-isolate scope.
+ *   Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.
+ * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
+ *   parent element is reached.
+ *
+ * @knownIssue You cannot spy on `angular.element` if you are using Jasmine version 1.x. See
+ * https://github.com/angular/angular.js/issues/14251 for more information.
+ *
+ * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
+ * @returns {Object} jQuery object.
+ */
+
+JQLite.expando = 'ng339';
+
+var jqCache = JQLite.cache = {},
+    jqId = 1;
+
+/*
+ * !!! This is an undocumented "private" function !!!
+ */
+JQLite._data = function(node) {
+  //jQuery always returns an object on cache miss
+  return this.cache[node[this.expando]] || {};
+};
+
+function jqNextId() { return ++jqId; }
+
+
+var DASH_LOWERCASE_REGEXP = /-([a-z])/g;
+var MS_HACK_REGEXP = /^-ms-/;
+var MOUSE_EVENT_MAP = { mouseleave: 'mouseout', mouseenter: 'mouseover' };
+var jqLiteMinErr = minErr('jqLite');
+
+/**
+ * Converts kebab-case to camelCase.
+ * There is also a special case for the ms prefix starting with a lowercase letter.
+ * @param name Name to normalize
+ */
+function cssKebabToCamel(name) {
+    return kebabToCamel(name.replace(MS_HACK_REGEXP, 'ms-'));
+}
+
+function fnCamelCaseReplace(all, letter) {
+  return letter.toUpperCase();
+}
+
+/**
+ * Converts kebab-case to camelCase.
+ * @param name Name to normalize
+ */
+function kebabToCamel(name) {
+  return name
+    .replace(DASH_LOWERCASE_REGEXP, fnCamelCaseReplace);
+}
+
+var SINGLE_TAG_REGEXP = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/;
+var HTML_REGEXP = /<|&#?\w+;/;
+var TAG_NAME_REGEXP = /<([\w:-]+)/;
+var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi;
+
+var wrapMap = {
+  'option': [1, '<select multiple="multiple">', '</select>'],
+
+  'thead': [1, '<table>', '</table>'],
+  'col': [2, '<table><colgroup>', '</colgroup></table>'],
+  'tr': [2, '<table><tbody>', '</tbody></table>'],
+  'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],
+  '_default': [0, '', '']
+};
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function jqLiteIsTextNode(html) {
+  return !HTML_REGEXP.test(html);
+}
+
+function jqLiteAcceptsData(node) {
+  // The window object can accept data but has no nodeType
+  // Otherwise we are only interested in elements (1) and documents (9)
+  var nodeType = node.nodeType;
+  return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
+}
+
+function jqLiteHasData(node) {
+  for (var key in jqCache[node.ng339]) {
+    return true;
+  }
+  return false;
+}
+
+function jqLiteCleanData(nodes) {
+  for (var i = 0, ii = nodes.length; i < ii; i++) {
+    jqLiteRemoveData(nodes[i]);
+  }
+}
+
+function jqLiteBuildFragment(html, context) {
+  var tmp, tag, wrap,
+      fragment = context.createDocumentFragment(),
+      nodes = [], i;
+
+  if (jqLiteIsTextNode(html)) {
+    // Convert non-html into a text node
+    nodes.push(context.createTextNode(html));
+  } else {
+    // Convert html into DOM nodes
+    tmp = fragment.appendChild(context.createElement('div'));
+    tag = (TAG_NAME_REGEXP.exec(html) || ['', ''])[1].toLowerCase();
+    wrap = wrapMap[tag] || wrapMap._default;
+    tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, '<$1></$2>') + wrap[2];
+
+    // Descend through wrappers to the right content
+    i = wrap[0];
+    while (i--) {
+      tmp = tmp.lastChild;
+    }
+
+    nodes = concat(nodes, tmp.childNodes);
+
+    tmp = fragment.firstChild;
+    tmp.textContent = '';
+  }
+
+  // Remove wrapper from fragment
+  fragment.textContent = '';
+  fragment.innerHTML = ''; // Clear inner HTML
+  forEach(nodes, function(node) {
+    fragment.appendChild(node);
+  });
+
+  return fragment;
+}
+
+function jqLiteParseHTML(html, context) {
+  context = context || window.document;
+  var parsed;
+
+  if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
+    return [context.createElement(parsed[1])];
+  }
+
+  if ((parsed = jqLiteBuildFragment(html, context))) {
+    return parsed.childNodes;
+  }
+
+  return [];
+}
+
+function jqLiteWrapNode(node, wrapper) {
+  var parent = node.parentNode;
+
+  if (parent) {
+    parent.replaceChild(wrapper, node);
+  }
+
+  wrapper.appendChild(node);
+}
+
+
+// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
+var jqLiteContains = window.Node.prototype.contains || /** @this */ function(arg) {
+  // eslint-disable-next-line no-bitwise
+  return !!(this.compareDocumentPosition(arg) & 16);
+};
+
+/////////////////////////////////////////////
+function JQLite(element) {
+  if (element instanceof JQLite) {
+    return element;
+  }
+
+  var argIsString;
+
+  if (isString(element)) {
+    element = trim(element);
+    argIsString = true;
+  }
+  if (!(this instanceof JQLite)) {
+    if (argIsString && element.charAt(0) !== '<') {
+      throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
+    }
+    return new JQLite(element);
+  }
+
+  if (argIsString) {
+    jqLiteAddNodes(this, jqLiteParseHTML(element));
+  } else if (isFunction(element)) {
+    jqLiteReady(element);
+  } else {
+    jqLiteAddNodes(this, element);
+  }
+}
+
+function jqLiteClone(element) {
+  return element.cloneNode(true);
+}
+
+function jqLiteDealoc(element, onlyDescendants) {
+  if (!onlyDescendants) jqLiteRemoveData(element);
+
+  if (element.querySelectorAll) {
+    var descendants = element.querySelectorAll('*');
+    for (var i = 0, l = descendants.length; i < l; i++) {
+      jqLiteRemoveData(descendants[i]);
+    }
+  }
+}
+
+function jqLiteOff(element, type, fn, unsupported) {
+  if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');
+
+  var expandoStore = jqLiteExpandoStore(element);
+  var events = expandoStore && expandoStore.events;
+  var handle = expandoStore && expandoStore.handle;
+
+  if (!handle) return; //no listeners registered
+
+  if (!type) {
+    for (type in events) {
+      if (type !== '$destroy') {
+        element.removeEventListener(type, handle);
+      }
+      delete events[type];
+    }
+  } else {
+
+    var removeHandler = function(type) {
+      var listenerFns = events[type];
+      if (isDefined(fn)) {
+        arrayRemove(listenerFns || [], fn);
+      }
+      if (!(isDefined(fn) && listenerFns && listenerFns.length > 0)) {
+        element.removeEventListener(type, handle);
+        delete events[type];
+      }
+    };
+
+    forEach(type.split(' '), function(type) {
+      removeHandler(type);
+      if (MOUSE_EVENT_MAP[type]) {
+        removeHandler(MOUSE_EVENT_MAP[type]);
+      }
+    });
+  }
+}
+
+function jqLiteRemoveData(element, name) {
+  var expandoId = element.ng339;
+  var expandoStore = expandoId && jqCache[expandoId];
+
+  if (expandoStore) {
+    if (name) {
+      delete expandoStore.data[name];
+      return;
+    }
+
+    if (expandoStore.handle) {
+      if (expandoStore.events.$destroy) {
+        expandoStore.handle({}, '$destroy');
+      }
+      jqLiteOff(element);
+    }
+    delete jqCache[expandoId];
+    element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it
+  }
+}
+
+
+function jqLiteExpandoStore(element, createIfNecessary) {
+  var expandoId = element.ng339,
+      expandoStore = expandoId && jqCache[expandoId];
+
+  if (createIfNecessary && !expandoStore) {
+    element.ng339 = expandoId = jqNextId();
+    expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined};
+  }
+
+  return expandoStore;
+}
+
+
+function jqLiteData(element, key, value) {
+  if (jqLiteAcceptsData(element)) {
+    var prop;
+
+    var isSimpleSetter = isDefined(value);
+    var isSimpleGetter = !isSimpleSetter && key && !isObject(key);
+    var massGetter = !key;
+    var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);
+    var data = expandoStore && expandoStore.data;
+
+    if (isSimpleSetter) { // data('key', value)
+      data[kebabToCamel(key)] = value;
+    } else {
+      if (massGetter) {  // data()
+        return data;
+      } else {
+        if (isSimpleGetter) { // data('key')
+          // don't force creation of expandoStore if it doesn't exist yet
+          return data && data[kebabToCamel(key)];
+        } else { // mass-setter: data({key1: val1, key2: val2})
+          for (prop in key) {
+            data[kebabToCamel(prop)] = key[prop];
+          }
+        }
+      }
+    }
+  }
+}
+
+function jqLiteHasClass(element, selector) {
+  if (!element.getAttribute) return false;
+  return ((' ' + (element.getAttribute('class') || '') + ' ').replace(/[\n\t]/g, ' ').
+      indexOf(' ' + selector + ' ') > -1);
+}
+
+function jqLiteRemoveClass(element, cssClasses) {
+  if (cssClasses && element.setAttribute) {
+    forEach(cssClasses.split(' '), function(cssClass) {
+      element.setAttribute('class', trim(
+          (' ' + (element.getAttribute('class') || '') + ' ')
+          .replace(/[\n\t]/g, ' ')
+          .replace(' ' + trim(cssClass) + ' ', ' '))
+      );
+    });
+  }
+}
+
+function jqLiteAddClass(element, cssClasses) {
+  if (cssClasses && element.setAttribute) {
+    var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
+                            .replace(/[\n\t]/g, ' ');
+
+    forEach(cssClasses.split(' '), function(cssClass) {
+      cssClass = trim(cssClass);
+      if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
+        existingClasses += cssClass + ' ';
+      }
+    });
+
+    element.setAttribute('class', trim(existingClasses));
+  }
+}
+
+
+function jqLiteAddNodes(root, elements) {
+  // THIS CODE IS VERY HOT. Don't make changes without benchmarking.
+
+  if (elements) {
+
+    // if a Node (the most common case)
+    if (elements.nodeType) {
+      root[root.length++] = elements;
+    } else {
+      var length = elements.length;
+
+      // if an Array or NodeList and not a Window
+      if (typeof length === 'number' && elements.window !== elements) {
+        if (length) {
+          for (var i = 0; i < length; i++) {
+            root[root.length++] = elements[i];
+          }
+        }
+      } else {
+        root[root.length++] = elements;
+      }
+    }
+  }
+}
+
+
+function jqLiteController(element, name) {
+  return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');
+}
+
+function jqLiteInheritedData(element, name, value) {
+  // if element is the document object work with the html element instead
+  // this makes $(document).scope() possible
+  if (element.nodeType === NODE_TYPE_DOCUMENT) {
+    element = element.documentElement;
+  }
+  var names = isArray(name) ? name : [name];
+
+  while (element) {
+    for (var i = 0, ii = names.length; i < ii; i++) {
+      if (isDefined(value = jqLite.data(element, names[i]))) return value;
+    }
+
+    // If dealing with a document fragment node with a host element, and no parent, use the host
+    // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM
+    // to lookup parent controllers.
+    element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host);
+  }
+}
+
+function jqLiteEmpty(element) {
+  jqLiteDealoc(element, true);
+  while (element.firstChild) {
+    element.removeChild(element.firstChild);
+  }
+}
+
+function jqLiteRemove(element, keepData) {
+  if (!keepData) jqLiteDealoc(element);
+  var parent = element.parentNode;
+  if (parent) parent.removeChild(element);
+}
+
+
+function jqLiteDocumentLoaded(action, win) {
+  win = win || window;
+  if (win.document.readyState === 'complete') {
+    // Force the action to be run async for consistent behavior
+    // from the action's point of view
+    // i.e. it will definitely not be in a $apply
+    win.setTimeout(action);
+  } else {
+    // No need to unbind this handler as load is only ever called once
+    jqLite(win).on('load', action);
+  }
+}
+
+function jqLiteReady(fn) {
+  function trigger() {
+    window.document.removeEventListener('DOMContentLoaded', trigger);
+    window.removeEventListener('load', trigger);
+    fn();
+  }
+
+  // check if document is already loaded
+  if (window.document.readyState === 'complete') {
+    window.setTimeout(fn);
+  } else {
+    // We can not use jqLite since we are not done loading and jQuery could be loaded later.
+
+    // Works for modern browsers and IE9
+    window.document.addEventListener('DOMContentLoaded', trigger);
+
+    // Fallback to window.onload for others
+    window.addEventListener('load', trigger);
+  }
+}
+
+//////////////////////////////////////////
+// Functions which are declared directly.
+//////////////////////////////////////////
+var JQLitePrototype = JQLite.prototype = {
+  ready: jqLiteReady,
+  toString: function() {
+    var value = [];
+    forEach(this, function(e) { value.push('' + e);});
+    return '[' + value.join(', ') + ']';
+  },
+
+  eq: function(index) {
+      return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]);
+  },
+
+  length: 0,
+  push: push,
+  sort: [].sort,
+  splice: [].splice
+};
+
+//////////////////////////////////////////
+// Functions iterating getter/setters.
+// these functions return self on setter and
+// value on get.
+//////////////////////////////////////////
+var BOOLEAN_ATTR = {};
+forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
+  BOOLEAN_ATTR[lowercase(value)] = value;
+});
+var BOOLEAN_ELEMENTS = {};
+forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
+  BOOLEAN_ELEMENTS[value] = true;
+});
+var ALIASED_ATTR = {
+  'ngMinlength': 'minlength',
+  'ngMaxlength': 'maxlength',
+  'ngMin': 'min',
+  'ngMax': 'max',
+  'ngPattern': 'pattern',
+  'ngStep': 'step'
+};
+
+function getBooleanAttrName(element, name) {
+  // check dom last since we will most likely fail on name
+  var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];
+
+  // booleanAttr is here twice to minimize DOM access
+  return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
+}
+
+function getAliasedAttrName(name) {
+  return ALIASED_ATTR[name];
+}
+
+forEach({
+  data: jqLiteData,
+  removeData: jqLiteRemoveData,
+  hasData: jqLiteHasData,
+  cleanData: jqLiteCleanData
+}, function(fn, name) {
+  JQLite[name] = fn;
+});
+
+forEach({
+  data: jqLiteData,
+  inheritedData: jqLiteInheritedData,
+
+  scope: function(element) {
+    // Can't use jqLiteData here directly so we stay compatible with jQuery!
+    return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);
+  },
+
+  isolateScope: function(element) {
+    // Can't use jqLiteData here directly so we stay compatible with jQuery!
+    return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');
+  },
+
+  controller: jqLiteController,
+
+  injector: function(element) {
+    return jqLiteInheritedData(element, '$injector');
+  },
+
+  removeAttr: function(element, name) {
+    element.removeAttribute(name);
+  },
+
+  hasClass: jqLiteHasClass,
+
+  css: function(element, name, value) {
+    name = cssKebabToCamel(name);
+
+    if (isDefined(value)) {
+      element.style[name] = value;
+    } else {
+      return element.style[name];
+    }
+  },
+
+  attr: function(element, name, value) {
+    var ret;
+    var nodeType = element.nodeType;
+    if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT ||
+      !element.getAttribute) {
+      return;
+    }
+
+    var lowercasedName = lowercase(name);
+    var isBooleanAttr = BOOLEAN_ATTR[lowercasedName];
+
+    if (isDefined(value)) {
+      // setter
+
+      if (value === null || (value === false && isBooleanAttr)) {
+        element.removeAttribute(name);
+      } else {
+        element.setAttribute(name, isBooleanAttr ? lowercasedName : value);
+      }
+    } else {
+      // getter
+
+      ret = element.getAttribute(name);
+
+      if (isBooleanAttr && ret !== null) {
+        ret = lowercasedName;
+      }
+      // Normalize non-existing attributes to undefined (as jQuery).
+      return ret === null ? undefined : ret;
+    }
+  },
+
+  prop: function(element, name, value) {
+    if (isDefined(value)) {
+      element[name] = value;
+    } else {
+      return element[name];
+    }
+  },
+
+  text: (function() {
+    getText.$dv = '';
+    return getText;
+
+    function getText(element, value) {
+      if (isUndefined(value)) {
+        var nodeType = element.nodeType;
+        return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : '';
+      }
+      element.textContent = value;
+    }
+  })(),
+
+  val: function(element, value) {
+    if (isUndefined(value)) {
+      if (element.multiple && nodeName_(element) === 'select') {
+        var result = [];
+        forEach(element.options, function(option) {
+          if (option.selected) {
+            result.push(option.value || option.text);
+          }
+        });
+        return result;
+      }
+      return element.value;
+    }
+    element.value = value;
+  },
+
+  html: function(element, value) {
+    if (isUndefined(value)) {
+      return element.innerHTML;
+    }
+    jqLiteDealoc(element, true);
+    element.innerHTML = value;
+  },
+
+  empty: jqLiteEmpty
+}, function(fn, name) {
+  /**
+   * Properties: writes return selection, reads return first value
+   */
+  JQLite.prototype[name] = function(arg1, arg2) {
+    var i, key;
+    var nodeCount = this.length;
+
+    // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it
+    // in a way that survives minification.
+    // jqLiteEmpty takes no arguments but is a setter.
+    if (fn !== jqLiteEmpty &&
+        (isUndefined((fn.length === 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2))) {
+      if (isObject(arg1)) {
+
+        // we are a write, but the object properties are the key/values
+        for (i = 0; i < nodeCount; i++) {
+          if (fn === jqLiteData) {
+            // data() takes the whole object in jQuery
+            fn(this[i], arg1);
+          } else {
+            for (key in arg1) {
+              fn(this[i], key, arg1[key]);
+            }
+          }
+        }
+        // return self for chaining
+        return this;
+      } else {
+        // we are a read, so read the first child.
+        // TODO: do we still need this?
+        var value = fn.$dv;
+        // Only if we have $dv do we iterate over all, otherwise it is just the first element.
+        var jj = (isUndefined(value)) ? Math.min(nodeCount, 1) : nodeCount;
+        for (var j = 0; j < jj; j++) {
+          var nodeValue = fn(this[j], arg1, arg2);
+          value = value ? value + nodeValue : nodeValue;
+        }
+        return value;
+      }
+    } else {
+      // we are a write, so apply to all children
+      for (i = 0; i < nodeCount; i++) {
+        fn(this[i], arg1, arg2);
+      }
+      // return self for chaining
+      return this;
+    }
+  };
+});
+
+function createEventHandler(element, events) {
+  var eventHandler = function(event, type) {
+    // jQuery specific api
+    event.isDefaultPrevented = function() {
+      return event.defaultPrevented;
+    };
+
+    var eventFns = events[type || event.type];
+    var eventFnsLength = eventFns ? eventFns.length : 0;
+
+    if (!eventFnsLength) return;
+
+    if (isUndefined(event.immediatePropagationStopped)) {
+      var originalStopImmediatePropagation = event.stopImmediatePropagation;
+      event.stopImmediatePropagation = function() {
+        event.immediatePropagationStopped = true;
+
+        if (event.stopPropagation) {
+          event.stopPropagation();
+        }
+
+        if (originalStopImmediatePropagation) {
+          originalStopImmediatePropagation.call(event);
+        }
+      };
+    }
+
+    event.isImmediatePropagationStopped = function() {
+      return event.immediatePropagationStopped === true;
+    };
+
+    // Some events have special handlers that wrap the real handler
+    var handlerWrapper = eventFns.specialHandlerWrapper || defaultHandlerWrapper;
+
+    // Copy event handlers in case event handlers array is modified during execution.
+    if ((eventFnsLength > 1)) {
+      eventFns = shallowCopy(eventFns);
+    }
+
+    for (var i = 0; i < eventFnsLength; i++) {
+      if (!event.isImmediatePropagationStopped()) {
+        handlerWrapper(element, event, eventFns[i]);
+      }
+    }
+  };
+
+  // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
+  //       events on `element`
+  eventHandler.elem = element;
+  return eventHandler;
+}
+
+function defaultHandlerWrapper(element, event, handler) {
+  handler.call(element, event);
+}
+
+function specialMouseHandlerWrapper(target, event, handler) {
+  // Refer to jQuery's implementation of mouseenter & mouseleave
+  // Read about mouseenter and mouseleave:
+  // http://www.quirksmode.org/js/events_mouse.html#link8
+  var related = event.relatedTarget;
+  // For mousenter/leave call the handler if related is outside the target.
+  // NB: No relatedTarget if the mouse left/entered the browser window
+  if (!related || (related !== target && !jqLiteContains.call(target, related))) {
+    handler.call(target, event);
+  }
+}
+
+//////////////////////////////////////////
+// Functions iterating traversal.
+// These functions chain results into a single
+// selector.
+//////////////////////////////////////////
+forEach({
+  removeData: jqLiteRemoveData,
+
+  on: function jqLiteOn(element, type, fn, unsupported) {
+    if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
+
+    // Do not add event handlers to non-elements because they will not be cleaned up.
+    if (!jqLiteAcceptsData(element)) {
+      return;
+    }
+
+    var expandoStore = jqLiteExpandoStore(element, true);
+    var events = expandoStore.events;
+    var handle = expandoStore.handle;
+
+    if (!handle) {
+      handle = expandoStore.handle = createEventHandler(element, events);
+    }
+
+    // http://jsperf.com/string-indexof-vs-split
+    var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type];
+    var i = types.length;
+
+    var addHandler = function(type, specialHandlerWrapper, noEventListener) {
+      var eventFns = events[type];
+
+      if (!eventFns) {
+        eventFns = events[type] = [];
+        eventFns.specialHandlerWrapper = specialHandlerWrapper;
+        if (type !== '$destroy' && !noEventListener) {
+          element.addEventListener(type, handle);
+        }
+      }
+
+      eventFns.push(fn);
+    };
+
+    while (i--) {
+      type = types[i];
+      if (MOUSE_EVENT_MAP[type]) {
+        addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper);
+        addHandler(type, undefined, true);
+      } else {
+        addHandler(type);
+      }
+    }
+  },
+
+  off: jqLiteOff,
+
+  one: function(element, type, fn) {
+    element = jqLite(element);
+
+    //add the listener twice so that when it is called
+    //you can remove the original function and still be
+    //able to call element.off(ev, fn) normally
+    element.on(type, function onFn() {
+      element.off(type, fn);
+      element.off(type, onFn);
+    });
+    element.on(type, fn);
+  },
+
+  replaceWith: function(element, replaceNode) {
+    var index, parent = element.parentNode;
+    jqLiteDealoc(element);
+    forEach(new JQLite(replaceNode), function(node) {
+      if (index) {
+        parent.insertBefore(node, index.nextSibling);
+      } else {
+        parent.replaceChild(node, element);
+      }
+      index = node;
+    });
+  },
+
+  children: function(element) {
+    var children = [];
+    forEach(element.childNodes, function(element) {
+      if (element.nodeType === NODE_TYPE_ELEMENT) {
+        children.push(element);
+      }
+    });
+    return children;
+  },
+
+  contents: function(element) {
+    return element.contentDocument || element.childNodes || [];
+  },
+
+  append: function(element, node) {
+    var nodeType = element.nodeType;
+    if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return;
+
+    node = new JQLite(node);
+
+    for (var i = 0, ii = node.length; i < ii; i++) {
+      var child = node[i];
+      element.appendChild(child);
+    }
+  },
+
+  prepend: function(element, node) {
+    if (element.nodeType === NODE_TYPE_ELEMENT) {
+      var index = element.firstChild;
+      forEach(new JQLite(node), function(child) {
+        element.insertBefore(child, index);
+      });
+    }
+  },
+
+  wrap: function(element, wrapNode) {
+    jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]);
+  },
+
+  remove: jqLiteRemove,
+
+  detach: function(element) {
+    jqLiteRemove(element, true);
+  },
+
+  after: function(element, newElement) {
+    var index = element, parent = element.parentNode;
+
+    if (parent) {
+      newElement = new JQLite(newElement);
+
+      for (var i = 0, ii = newElement.length; i < ii; i++) {
+        var node = newElement[i];
+        parent.insertBefore(node, index.nextSibling);
+        index = node;
+      }
+    }
+  },
+
+  addClass: jqLiteAddClass,
+  removeClass: jqLiteRemoveClass,
+
+  toggleClass: function(element, selector, condition) {
+    if (selector) {
+      forEach(selector.split(' '), function(className) {
+        var classCondition = condition;
+        if (isUndefined(classCondition)) {
+          classCondition = !jqLiteHasClass(element, className);
+        }
+        (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className);
+      });
+    }
+  },
+
+  parent: function(element) {
+    var parent = element.parentNode;
+    return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null;
+  },
+
+  next: function(element) {
+    return element.nextElementSibling;
+  },
+
+  find: function(element, selector) {
+    if (element.getElementsByTagName) {
+      return element.getElementsByTagName(selector);
+    } else {
+      return [];
+    }
+  },
+
+  clone: jqLiteClone,
+
+  triggerHandler: function(element, event, extraParameters) {
+
+    var dummyEvent, eventFnsCopy, handlerArgs;
+    var eventName = event.type || event;
+    var expandoStore = jqLiteExpandoStore(element);
+    var events = expandoStore && expandoStore.events;
+    var eventFns = events && events[eventName];
+
+    if (eventFns) {
+      // Create a dummy event to pass to the handlers
+      dummyEvent = {
+        preventDefault: function() { this.defaultPrevented = true; },
+        isDefaultPrevented: function() { return this.defaultPrevented === true; },
+        stopImmediatePropagation: function() { this.immediatePropagationStopped = true; },
+        isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; },
+        stopPropagation: noop,
+        type: eventName,
+        target: element
+      };
+
+      // If a custom event was provided then extend our dummy event with it
+      if (event.type) {
+        dummyEvent = extend(dummyEvent, event);
+      }
+
+      // Copy event handlers in case event handlers array is modified during execution.
+      eventFnsCopy = shallowCopy(eventFns);
+      handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];
+
+      forEach(eventFnsCopy, function(fn) {
+        if (!dummyEvent.isImmediatePropagationStopped()) {
+          fn.apply(element, handlerArgs);
+        }
+      });
+    }
+  }
+}, function(fn, name) {
+  /**
+   * chaining functions
+   */
+  JQLite.prototype[name] = function(arg1, arg2, arg3) {
+    var value;
+
+    for (var i = 0, ii = this.length; i < ii; i++) {
+      if (isUndefined(value)) {
+        value = fn(this[i], arg1, arg2, arg3);
+        if (isDefined(value)) {
+          // any function which returns a value needs to be wrapped
+          value = jqLite(value);
+        }
+      } else {
+        jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
+      }
+    }
+    return isDefined(value) ? value : this;
+  };
+});
+
+// bind legacy bind/unbind to on/off
+JQLite.prototype.bind = JQLite.prototype.on;
+JQLite.prototype.unbind = JQLite.prototype.off;
+
+
+// Provider for private $$jqLite service
+/** @this */
+function $$jqLiteProvider() {
+  this.$get = function $$jqLite() {
+    return extend(JQLite, {
+      hasClass: function(node, classes) {
+        if (node.attr) node = node[0];
+        return jqLiteHasClass(node, classes);
+      },
+      addClass: function(node, classes) {
+        if (node.attr) node = node[0];
+        return jqLiteAddClass(node, classes);
+      },
+      removeClass: function(node, classes) {
+        if (node.attr) node = node[0];
+        return jqLiteRemoveClass(node, classes);
+      }
+    });
+  };
+}
+
+/**
+ * Computes a hash of an 'obj'.
+ * Hash of a:
+ *  string is string
+ *  number is number as string
+ *  object is either result of calling $$hashKey function on the object or uniquely generated id,
+ *         that is also assigned to the $$hashKey property of the object.
+ *
+ * @param obj
+ * @returns {string} hash string such that the same input will have the same hash string.
+ *         The resulting string key is in 'type:hashKey' format.
+ */
+function hashKey(obj, nextUidFn) {
+  var key = obj && obj.$$hashKey;
+
+  if (key) {
+    if (typeof key === 'function') {
+      key = obj.$$hashKey();
+    }
+    return key;
+  }
+
+  var objType = typeof obj;
+  if (objType === 'function' || (objType === 'object' && obj !== null)) {
+    key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)();
+  } else {
+    key = objType + ':' + obj;
+  }
+
+  return key;
+}
+
+// A minimal ES2015 Map implementation.
+// Should be bug/feature equivalent to the native implementations of supported browsers
+// (for the features required in Angular).
+// See https://kangax.github.io/compat-table/es6/#test-Map
+var nanKey = Object.create(null);
+function NgMapShim() {
+  this._keys = [];
+  this._values = [];
+  this._lastKey = NaN;
+  this._lastIndex = -1;
+}
+NgMapShim.prototype = {
+  _idx: function(key) {
+    if (key === this._lastKey) {
+      return this._lastIndex;
+    }
+    this._lastKey = key;
+    this._lastIndex = this._keys.indexOf(key);
+    return this._lastIndex;
+  },
+  _transformKey: function(key) {
+    return isNumberNaN(key) ? nanKey : key;
+  },
+  get: function(key) {
+    key = this._transformKey(key);
+    var idx = this._idx(key);
+    if (idx !== -1) {
+      return this._values[idx];
+    }
+  },
+  set: function(key, value) {
+    key = this._transformKey(key);
+    var idx = this._idx(key);
+    if (idx === -1) {
+      idx = this._lastIndex = this._keys.length;
+    }
+    this._keys[idx] = key;
+    this._values[idx] = value;
+
+    // Support: IE11
+    // Do not `return this` to simulate the partial IE11 implementation
+  },
+  delete: function(key) {
+    key = this._transformKey(key);
+    var idx = this._idx(key);
+    if (idx === -1) {
+      return false;
+    }
+    this._keys.splice(idx, 1);
+    this._values.splice(idx, 1);
+    this._lastKey = NaN;
+    this._lastIndex = -1;
+    return true;
+  }
+};
+
+// For now, always use `NgMapShim`, even if `window.Map` is available. Some native implementations
+// are still buggy (often in subtle ways) and can cause hard-to-debug failures. When native `Map`
+// implementations get more stable, we can reconsider switching to `window.Map` (when available).
+var NgMap = NgMapShim;
+
+var $$MapProvider = [/** @this */function() {
+  this.$get = [function() {
+    return NgMap;
+  }];
+}];
+
+/**
+ * @ngdoc function
+ * @module ng
+ * @name angular.injector
+ * @kind function
+ *
+ * @description
+ * Creates an injector object that can be used for retrieving services as well as for
+ * dependency injection (see {@link guide/di dependency injection}).
+ *
+ * @param {Array.<string|Function>} modules A list of module functions or their aliases. See
+ *     {@link angular.module}. The `ng` module must be explicitly added.
+ * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which
+ *     disallows argument name annotation inference.
+ * @returns {injector} Injector object. See {@link auto.$injector $injector}.
+ *
+ * @example
+ * Typical usage
+ * ```js
+ *   // create an injector
+ *   var $injector = angular.injector(['ng']);
+ *
+ *   // use the injector to kick off your application
+ *   // use the type inference to auto inject arguments, or use implicit injection
+ *   $injector.invoke(function($rootScope, $compile, $document) {
+ *     $compile($document)($rootScope);
+ *     $rootScope.$digest();
+ *   });
+ * ```
+ *
+ * Sometimes you want to get access to the injector of a currently running Angular app
+ * from outside Angular. Perhaps, you want to inject and compile some markup after the
+ * application has been bootstrapped. You can do this using the extra `injector()` added
+ * to JQuery/jqLite elements. See {@link angular.element}.
+ *
+ * *This is fairly rare but could be the case if a third party library is injecting the
+ * markup.*
+ *
+ * In the following example a new block of HTML containing a `ng-controller`
+ * directive is added to the end of the document body by JQuery. We then compile and link
+ * it into the current AngularJS scope.
+ *
+ * ```js
+ * var $div = $('<div ng-controller="MyCtrl">{{content.label}}</div>');
+ * $(document.body).append($div);
+ *
+ * angular.element(document).injector().invoke(function($compile) {
+ *   var scope = angular.element($div).scope();
+ *   $compile($div)(scope);
+ * });
+ * ```
+ */
+
+
+/**
+ * @ngdoc module
+ * @name auto
+ * @installation
+ * @description
+ *
+ * Implicit module which gets automatically added to each {@link auto.$injector $injector}.
+ */
+
+var ARROW_ARG = /^([^(]+?)=>/;
+var FN_ARGS = /^[^(]*\(\s*([^)]*)\)/m;
+var FN_ARG_SPLIT = /,/;
+var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
+var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
+var $injectorMinErr = minErr('$injector');
+
+function stringifyFn(fn) {
+  return Function.prototype.toString.call(fn);
+}
+
+function extractArgs(fn) {
+  var fnText = stringifyFn(fn).replace(STRIP_COMMENTS, ''),
+      args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
+  return args;
+}
+
+function anonFn(fn) {
+  // For anonymous functions, showing at the very least the function signature can help in
+  // debugging.
+  var args = extractArgs(fn);
+  if (args) {
+    return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')';
+  }
+  return 'fn';
+}
+
+function annotate(fn, strictDi, name) {
+  var $inject,
+      argDecl,
+      last;
+
+  if (typeof fn === 'function') {
+    if (!($inject = fn.$inject)) {
+      $inject = [];
+      if (fn.length) {
+        if (strictDi) {
+          if (!isString(name) || !name) {
+            name = fn.name || anonFn(fn);
+          }
+          throw $injectorMinErr('strictdi',
+            '{0} is not using explicit annotation and cannot be invoked in strict mode', name);
+        }
+        argDecl = extractArgs(fn);
+        forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
+          arg.replace(FN_ARG, function(all, underscore, name) {
+            $inject.push(name);
+          });
+        });
+      }
+      fn.$inject = $inject;
+    }
+  } else if (isArray(fn)) {
+    last = fn.length - 1;
+    assertArgFn(fn[last], 'fn');
+    $inject = fn.slice(0, last);
+  } else {
+    assertArgFn(fn, 'fn', true);
+  }
+  return $inject;
+}
+
+///////////////////////////////////////
+
+/**
+ * @ngdoc service
+ * @name $injector
+ *
+ * @description
+ *
+ * `$injector` is used to retrieve object instances as defined by
+ * {@link auto.$provide provider}, instantiate types, invoke methods,
+ * and load modules.
+ *
+ * The following always holds true:
+ *
+ * ```js
+ *   var $injector = angular.injector();
+ *   expect($injector.get('$injector')).toBe($injector);
+ *   expect($injector.invoke(function($injector) {
+ *     return $injector;
+ *   })).toBe($injector);
+ * ```
+ *
+ * # Injection Function Annotation
+ *
+ * JavaScript does not have annotations, and annotations are needed for dependency injection. The
+ * following are all valid ways of annotating function with injection arguments and are equivalent.
+ *
+ * ```js
+ *   // inferred (only works if code not minified/obfuscated)
+ *   $injector.invoke(function(serviceA){});
+ *
+ *   // annotated
+ *   function explicit(serviceA) {};
+ *   explicit.$inject = ['serviceA'];
+ *   $injector.invoke(explicit);
+ *
+ *   // inline
+ *   $injector.invoke(['serviceA', function(serviceA){}]);
+ * ```
+ *
+ * ## Inference
+ *
+ * In JavaScript calling `toString()` on a function returns the function definition. The definition
+ * can then be parsed and the function arguments can be extracted. This method of discovering
+ * annotations is disallowed when the injector is in strict mode.
+ * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the
+ * argument names.
+ *
+ * ## `$inject` Annotation
+ * By adding an `$inject` property onto a function the injection parameters can be specified.
+ *
+ * ## Inline
+ * As an array of injection names, where the last item in the array is the function to call.
+ */
+
+/**
+ * @ngdoc property
+ * @name $injector#modules
+ * @type {Object}
+ * @description
+ * A hash containing all the modules that have been loaded into the
+ * $injector.
+ *
+ * You can use this property to find out information about a module via the
+ * {@link angular.Module#info `myModule.info(...)`} method.
+ *
+ * For example:
+ *
+ * ```
+ * var info = $injector.modules['ngAnimate'].info();
+ * ```
+ *
+ * **Do not use this property to attempt to modify the modules after the application
+ * has been bootstrapped.**
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $injector#get
+ *
+ * @description
+ * Return an instance of the service.
+ *
+ * @param {string} name The name of the instance to retrieve.
+ * @param {string=} caller An optional string to provide the origin of the function call for error messages.
+ * @return {*} The instance.
+ */
+
+/**
+ * @ngdoc method
+ * @name $injector#invoke
+ *
+ * @description
+ * Invoke the method and supply the method arguments from the `$injector`.
+ *
+ * @param {Function|Array.<string|Function>} fn The injectable function to invoke. Function parameters are
+ *   injected according to the {@link guide/di $inject Annotation} rules.
+ * @param {Object=} self The `this` for the invoked method.
+ * @param {Object=} locals Optional object. If preset then any argument names are read from this
+ *                         object first, before the `$injector` is consulted.
+ * @returns {*} the value returned by the invoked `fn` function.
+ */
+
+/**
+ * @ngdoc method
+ * @name $injector#has
+ *
+ * @description
+ * Allows the user to query if the particular service exists.
+ *
+ * @param {string} name Name of the service to query.
+ * @returns {boolean} `true` if injector has given service.
+ */
+
+/**
+ * @ngdoc method
+ * @name $injector#instantiate
+ * @description
+ * Create a new instance of JS type. The method takes a constructor function, invokes the new
+ * operator, and supplies all of the arguments to the constructor function as specified by the
+ * constructor annotation.
+ *
+ * @param {Function} Type Annotated constructor function.
+ * @param {Object=} locals Optional object. If preset then any argument names are read from this
+ * object first, before the `$injector` is consulted.
+ * @returns {Object} new instance of `Type`.
+ */
+
+/**
+ * @ngdoc method
+ * @name $injector#annotate
+ *
+ * @description
+ * Returns an array of service names which the function is requesting for injection. This API is
+ * used by the injector to determine which services need to be injected into the function when the
+ * function is invoked. There are three ways in which the function can be annotated with the needed
+ * dependencies.
+ *
+ * # Argument names
+ *
+ * The simplest form is to extract the dependencies from the arguments of the function. This is done
+ * by converting the function into a string using `toString()` method and extracting the argument
+ * names.
+ * ```js
+ *   // Given
+ *   function MyController($scope, $route) {
+ *     // ...
+ *   }
+ *
+ *   // Then
+ *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
+ * ```
+ *
+ * You can disallow this method by using strict injection mode.
+ *
+ * This method does not work with code minification / obfuscation. For this reason the following
+ * annotation strategies are supported.
+ *
+ * # The `$inject` property
+ *
+ * If a function has an `$inject` property and its value is an array of strings, then the strings
+ * represent names of services to be injected into the function.
+ * ```js
+ *   // Given
+ *   var MyController = function(obfuscatedScope, obfuscatedRoute) {
+ *     // ...
+ *   }
+ *   // Define function dependencies
+ *   MyController['$inject'] = ['$scope', '$route'];
+ *
+ *   // Then
+ *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
+ * ```
+ *
+ * # The array notation
+ *
+ * It is often desirable to inline Injected functions and that's when setting the `$inject` property
+ * is very inconvenient. In these situations using the array notation to specify the dependencies in
+ * a way that survives minification is a better choice:
+ *
+ * ```js
+ *   // We wish to write this (not minification / obfuscation safe)
+ *   injector.invoke(function($compile, $rootScope) {
+ *     // ...
+ *   });
+ *
+ *   // We are forced to write break inlining
+ *   var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) {
+ *     // ...
+ *   };
+ *   tmpFn.$inject = ['$compile', '$rootScope'];
+ *   injector.invoke(tmpFn);
+ *
+ *   // To better support inline function the inline annotation is supported
+ *   injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
+ *     // ...
+ *   }]);
+ *
+ *   // Therefore
+ *   expect(injector.annotate(
+ *      ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}])
+ *    ).toEqual(['$compile', '$rootScope']);
+ * ```
+ *
+ * @param {Function|Array.<string|Function>} fn Function for which dependent service names need to
+ * be retrieved as described above.
+ *
+ * @param {boolean=} [strictDi=false] Disallow argument name annotation inference.
+ *
+ * @returns {Array.<string>} The names of the services which the function requires.
+ */
+
+
+
+/**
+ * @ngdoc service
+ * @name $provide
+ *
+ * @description
+ *
+ * The {@link auto.$provide $provide} service has a number of methods for registering components
+ * with the {@link auto.$injector $injector}. Many of these functions are also exposed on
+ * {@link angular.Module}.
+ *
+ * An Angular **service** is a singleton object created by a **service factory**.  These **service
+ * factories** are functions which, in turn, are created by a **service provider**.
+ * The **service providers** are constructor functions. When instantiated they must contain a
+ * property called `$get`, which holds the **service factory** function.
+ *
+ * When you request a service, the {@link auto.$injector $injector} is responsible for finding the
+ * correct **service provider**, instantiating it and then calling its `$get` **service factory**
+ * function to get the instance of the **service**.
+ *
+ * Often services have no configuration options and there is no need to add methods to the service
+ * provider.  The provider will be no more than a constructor function with a `$get` property. For
+ * these cases the {@link auto.$provide $provide} service has additional helper methods to register
+ * services without specifying a provider.
+ *
+ * * {@link auto.$provide#provider provider(name, provider)} - registers a **service provider** with the
+ *     {@link auto.$injector $injector}
+ * * {@link auto.$provide#constant constant(name, obj)} - registers a value/object that can be accessed by
+ *     providers and services.
+ * * {@link auto.$provide#value value(name, obj)} - registers a value/object that can only be accessed by
+ *     services, not providers.
+ * * {@link auto.$provide#factory factory(name, fn)} - registers a service **factory function**
+ *     that will be wrapped in a **service provider** object, whose `$get` property will contain the
+ *     given factory function.
+ * * {@link auto.$provide#service service(name, Fn)} - registers a **constructor function**
+ *     that will be wrapped in a **service provider** object, whose `$get` property will instantiate
+ *      a new object using the given constructor function.
+ * * {@link auto.$provide#decorator decorator(name, decorFn)} - registers a **decorator function** that
+ *      will be able to modify or replace the implementation of another service.
+ *
+ * See the individual methods for more information and examples.
+ */
+
+/**
+ * @ngdoc method
+ * @name $provide#provider
+ * @description
+ *
+ * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions
+ * are constructor functions, whose instances are responsible for "providing" a factory for a
+ * service.
+ *
+ * Service provider names start with the name of the service they provide followed by `Provider`.
+ * For example, the {@link ng.$log $log} service has a provider called
+ * {@link ng.$logProvider $logProvider}.
+ *
+ * Service provider objects can have additional methods which allow configuration of the provider
+ * and its service. Importantly, you can configure what kind of service is created by the `$get`
+ * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a
+ * method {@link ng.$logProvider#debugEnabled debugEnabled}
+ * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the
+ * console or not.
+ *
+ * @param {string} name The name of the instance. NOTE: the provider will be available under `name +
+                        'Provider'` key.
+ * @param {(Object|function())} provider If the provider is:
+ *
+ *   - `Object`: then it should have a `$get` method. The `$get` method will be invoked using
+ *     {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created.
+ *   - `Constructor`: a new instance of the provider will be created using
+ *     {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`.
+ *
+ * @returns {Object} registered provider instance
+
+ * @example
+ *
+ * The following example shows how to create a simple event tracking service and register it using
+ * {@link auto.$provide#provider $provide.provider()}.
+ *
+ * ```js
+ *  // Define the eventTracker provider
+ *  function EventTrackerProvider() {
+ *    var trackingUrl = '/track';
+ *
+ *    // A provider method for configuring where the tracked events should been saved
+ *    this.setTrackingUrl = function(url) {
+ *      trackingUrl = url;
+ *    };
+ *
+ *    // The service factory function
+ *    this.$get = ['$http', function($http) {
+ *      var trackedEvents = {};
+ *      return {
+ *        // Call this to track an event
+ *        event: function(event) {
+ *          var count = trackedEvents[event] || 0;
+ *          count += 1;
+ *          trackedEvents[event] = count;
+ *          return count;
+ *        },
+ *        // Call this to save the tracked events to the trackingUrl
+ *        save: function() {
+ *          $http.post(trackingUrl, trackedEvents);
+ *        }
+ *      };
+ *    }];
+ *  }
+ *
+ *  describe('eventTracker', function() {
+ *    var postSpy;
+ *
+ *    beforeEach(module(function($provide) {
+ *      // Register the eventTracker provider
+ *      $provide.provider('eventTracker', EventTrackerProvider);
+ *    }));
+ *
+ *    beforeEach(module(function(eventTrackerProvider) {
+ *      // Configure eventTracker provider
+ *      eventTrackerProvider.setTrackingUrl('/custom-track');
+ *    }));
+ *
+ *    it('tracks events', inject(function(eventTracker) {
+ *      expect(eventTracker.event('login')).toEqual(1);
+ *      expect(eventTracker.event('login')).toEqual(2);
+ *    }));
+ *
+ *    it('saves to the tracking url', inject(function(eventTracker, $http) {
+ *      postSpy = spyOn($http, 'post');
+ *      eventTracker.event('login');
+ *      eventTracker.save();
+ *      expect(postSpy).toHaveBeenCalled();
+ *      expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track');
+ *      expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track');
+ *      expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });
+ *    }));
+ *  });
+ * ```
+ */
+
+/**
+ * @ngdoc method
+ * @name $provide#factory
+ * @description
+ *
+ * Register a **service factory**, which will be called to return the service instance.
+ * This is short for registering a service where its provider consists of only a `$get` property,
+ * which is the given service factory function.
+ * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to
+ * configure your service in a provider.
+ *
+ * @param {string} name The name of the instance.
+ * @param {Function|Array.<string|Function>} $getFn The injectable $getFn for the instance creation.
+ *                      Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`.
+ * @returns {Object} registered provider instance
+ *
+ * @example
+ * Here is an example of registering a service
+ * ```js
+ *   $provide.factory('ping', ['$http', function($http) {
+ *     return function ping() {
+ *       return $http.send('/ping');
+ *     };
+ *   }]);
+ * ```
+ * You would then inject and use this service like this:
+ * ```js
+ *   someModule.controller('Ctrl', ['ping', function(ping) {
+ *     ping();
+ *   }]);
+ * ```
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $provide#service
+ * @description
+ *
+ * Register a **service constructor**, which will be invoked with `new` to create the service
+ * instance.
+ * This is short for registering a service where its provider's `$get` property is a factory
+ * function that returns an instance instantiated by the injector from the service constructor
+ * function.
+ *
+ * Internally it looks a bit like this:
+ *
+ * ```
+ * {
+ *   $get: function() {
+ *     return $injector.instantiate(constructor);
+ *   }
+ * }
+ * ```
+ *
+ *
+ * You should use {@link auto.$provide#service $provide.service(class)} if you define your service
+ * as a type/class.
+ *
+ * @param {string} name The name of the instance.
+ * @param {Function|Array.<string|Function>} constructor An injectable class (constructor function)
+ *     that will be instantiated.
+ * @returns {Object} registered provider instance
+ *
+ * @example
+ * Here is an example of registering a service using
+ * {@link auto.$provide#service $provide.service(class)}.
+ * ```js
+ *   var Ping = function($http) {
+ *     this.$http = $http;
+ *   };
+ *
+ *   Ping.$inject = ['$http'];
+ *
+ *   Ping.prototype.send = function() {
+ *     return this.$http.get('/ping');
+ *   };
+ *   $provide.service('ping', Ping);
+ * ```
+ * You would then inject and use this service like this:
+ * ```js
+ *   someModule.controller('Ctrl', ['ping', function(ping) {
+ *     ping.send();
+ *   }]);
+ * ```
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $provide#value
+ * @description
+ *
+ * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a
+ * number, an array, an object or a function. This is short for registering a service where its
+ * provider's `$get` property is a factory function that takes no arguments and returns the **value
+ * service**. That also means it is not possible to inject other services into a value service.
+ *
+ * Value services are similar to constant services, except that they cannot be injected into a
+ * module configuration function (see {@link angular.Module#config}) but they can be overridden by
+ * an Angular {@link auto.$provide#decorator decorator}.
+ *
+ * @param {string} name The name of the instance.
+ * @param {*} value The value.
+ * @returns {Object} registered provider instance
+ *
+ * @example
+ * Here are some examples of creating value services.
+ * ```js
+ *   $provide.value('ADMIN_USER', 'admin');
+ *
+ *   $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
+ *
+ *   $provide.value('halfOf', function(value) {
+ *     return value / 2;
+ *   });
+ * ```
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $provide#constant
+ * @description
+ *
+ * Register a **constant service** with the {@link auto.$injector $injector}, such as a string,
+ * a number, an array, an object or a function. Like the {@link auto.$provide#value value}, it is not
+ * possible to inject other services into a constant.
+ *
+ * But unlike {@link auto.$provide#value value}, a constant can be
+ * injected into a module configuration function (see {@link angular.Module#config}) and it cannot
+ * be overridden by an Angular {@link auto.$provide#decorator decorator}.
+ *
+ * @param {string} name The name of the constant.
+ * @param {*} value The constant value.
+ * @returns {Object} registered instance
+ *
+ * @example
+ * Here a some examples of creating constants:
+ * ```js
+ *   $provide.constant('SHARD_HEIGHT', 306);
+ *
+ *   $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);
+ *
+ *   $provide.constant('double', function(value) {
+ *     return value * 2;
+ *   });
+ * ```
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $provide#decorator
+ * @description
+ *
+ * Register a **decorator function** with the {@link auto.$injector $injector}. A decorator function
+ * intercepts the creation of a service, allowing it to override or modify the behavior of the
+ * service. The return value of the decorator function may be the original service, or a new service
+ * that replaces (or wraps and delegates to) the original service.
+ *
+ * You can find out more about using decorators in the {@link guide/decorators} guide.
+ *
+ * @param {string} name The name of the service to decorate.
+ * @param {Function|Array.<string|Function>} decorator This function will be invoked when the service needs to be
+ *    provided and should return the decorated service instance. The function is called using
+ *    the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.
+ *    Local injection arguments:
+ *
+ *    * `$delegate` - The original service instance, which can be replaced, monkey patched, configured,
+ *      decorated or delegated to.
+ *
+ * @example
+ * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
+ * calls to {@link ng.$log#error $log.warn()}.
+ * ```js
+ *   $provide.decorator('$log', ['$delegate', function($delegate) {
+ *     $delegate.warn = $delegate.error;
+ *     return $delegate;
+ *   }]);
+ * ```
+ */
+
+
+function createInjector(modulesToLoad, strictDi) {
+  strictDi = (strictDi === true);
+  var INSTANTIATING = {},
+      providerSuffix = 'Provider',
+      path = [],
+      loadedModules = new NgMap(),
+      providerCache = {
+        $provide: {
+            provider: supportObject(provider),
+            factory: supportObject(factory),
+            service: supportObject(service),
+            value: supportObject(value),
+            constant: supportObject(constant),
+            decorator: decorator
+          }
+      },
+      providerInjector = (providerCache.$injector =
+          createInternalInjector(providerCache, function(serviceName, caller) {
+            if (angular.isString(caller)) {
+              path.push(caller);
+            }
+            throw $injectorMinErr('unpr', 'Unknown provider: {0}', path.join(' <- '));
+          })),
+      instanceCache = {},
+      protoInstanceInjector =
+          createInternalInjector(instanceCache, function(serviceName, caller) {
+            var provider = providerInjector.get(serviceName + providerSuffix, caller);
+            return instanceInjector.invoke(
+                provider.$get, provider, undefined, serviceName);
+          }),
+      instanceInjector = protoInstanceInjector;
+
+  providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };
+  instanceInjector.modules = providerInjector.modules = createMap();
+  var runBlocks = loadModules(modulesToLoad);
+  instanceInjector = protoInstanceInjector.get('$injector');
+  instanceInjector.strictDi = strictDi;
+  forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); });
+
+  return instanceInjector;
+
+  ////////////////////////////////////
+  // $provider
+  ////////////////////////////////////
+
+  function supportObject(delegate) {
+    return function(key, value) {
+      if (isObject(key)) {
+        forEach(key, reverseParams(delegate));
+      } else {
+        return delegate(key, value);
+      }
+    };
+  }
+
+  function provider(name, provider_) {
+    assertNotHasOwnProperty(name, 'service');
+    if (isFunction(provider_) || isArray(provider_)) {
+      provider_ = providerInjector.instantiate(provider_);
+    }
+    if (!provider_.$get) {
+      throw $injectorMinErr('pget', 'Provider \'{0}\' must define $get factory method.', name);
+    }
+    return (providerCache[name + providerSuffix] = provider_);
+  }
+
+  function enforceReturnValue(name, factory) {
+    return /** @this */ function enforcedReturnValue() {
+      var result = instanceInjector.invoke(factory, this);
+      if (isUndefined(result)) {
+        throw $injectorMinErr('undef', 'Provider \'{0}\' must return a value from $get factory method.', name);
+      }
+      return result;
+    };
+  }
+
+  function factory(name, factoryFn, enforce) {
+    return provider(name, {
+      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
+    });
+  }
+
+  function service(name, constructor) {
+    return factory(name, ['$injector', function($injector) {
+      return $injector.instantiate(constructor);
+    }]);
+  }
+
+  function value(name, val) { return factory(name, valueFn(val), false); }
+
+  function constant(name, value) {
+    assertNotHasOwnProperty(name, 'constant');
+    providerCache[name] = value;
+    instanceCache[name] = value;
+  }
+
+  function decorator(serviceName, decorFn) {
+    var origProvider = providerInjector.get(serviceName + providerSuffix),
+        orig$get = origProvider.$get;
+
+    origProvider.$get = function() {
+      var origInstance = instanceInjector.invoke(orig$get, origProvider);
+      return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});
+    };
+  }
+
+  ////////////////////////////////////
+  // Module Loading
+  ////////////////////////////////////
+  function loadModules(modulesToLoad) {
+    assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array');
+    var runBlocks = [], moduleFn;
+    forEach(modulesToLoad, function(module) {
+      if (loadedModules.get(module)) return;
+      loadedModules.set(module, true);
+
+      function runInvokeQueue(queue) {
+        var i, ii;
+        for (i = 0, ii = queue.length; i < ii; i++) {
+          var invokeArgs = queue[i],
+              provider = providerInjector.get(invokeArgs[0]);
+
+          provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
+        }
+      }
+
+      try {
+        if (isString(module)) {
+          moduleFn = angularModule(module);
+          instanceInjector.modules[module] = moduleFn;
+          runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
+          runInvokeQueue(moduleFn._invokeQueue);
+          runInvokeQueue(moduleFn._configBlocks);
+        } else if (isFunction(module)) {
+            runBlocks.push(providerInjector.invoke(module));
+        } else if (isArray(module)) {
+            runBlocks.push(providerInjector.invoke(module));
+        } else {
+          assertArgFn(module, 'module');
+        }
+      } catch (e) {
+        if (isArray(module)) {
+          module = module[module.length - 1];
+        }
+        if (e.message && e.stack && e.stack.indexOf(e.message) === -1) {
+          // Safari & FF's stack traces don't contain error.message content
+          // unlike those of Chrome and IE
+          // So if stack doesn't contain message, we create a new string that contains both.
+          // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here.
+          // eslint-disable-next-line no-ex-assign
+          e = e.message + '\n' + e.stack;
+        }
+        throw $injectorMinErr('modulerr', 'Failed to instantiate module {0} due to:\n{1}',
+                  module, e.stack || e.message || e);
+      }
+    });
+    return runBlocks;
+  }
+
+  ////////////////////////////////////
+  // internal Injector
+  ////////////////////////////////////
+
+  function createInternalInjector(cache, factory) {
+
+    function getService(serviceName, caller) {
+      if (cache.hasOwnProperty(serviceName)) {
+        if (cache[serviceName] === INSTANTIATING) {
+          throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
+                    serviceName + ' <- ' + path.join(' <- '));
+        }
+        return cache[serviceName];
+      } else {
+        try {
+          path.unshift(serviceName);
+          cache[serviceName] = INSTANTIATING;
+          cache[serviceName] = factory(serviceName, caller);
+          return cache[serviceName];
+        } catch (err) {
+          if (cache[serviceName] === INSTANTIATING) {
+            delete cache[serviceName];
+          }
+          throw err;
+        } finally {
+          path.shift();
+        }
+      }
+    }
+
+
+    function injectionArgs(fn, locals, serviceName) {
+      var args = [],
+          $inject = createInjector.$$annotate(fn, strictDi, serviceName);
+
+      for (var i = 0, length = $inject.length; i < length; i++) {
+        var key = $inject[i];
+        if (typeof key !== 'string') {
+          throw $injectorMinErr('itkn',
+                  'Incorrect injection token! Expected service name as string, got {0}', key);
+        }
+        args.push(locals && locals.hasOwnProperty(key) ? locals[key] :
+                                                         getService(key, serviceName));
+      }
+      return args;
+    }
+
+    function isClass(func) {
+      // Support: IE 9-11 only
+      // IE 9-11 do not support classes and IE9 leaks with the code below.
+      if (msie || typeof func !== 'function') {
+        return false;
+      }
+      var result = func.$$ngIsClass;
+      if (!isBoolean(result)) {
+        // Support: Edge 12-13 only
+        // See: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6156135/
+        result = func.$$ngIsClass = /^(?:class\b|constructor\()/.test(stringifyFn(func));
+      }
+      return result;
+    }
+
+    function invoke(fn, self, locals, serviceName) {
+      if (typeof locals === 'string') {
+        serviceName = locals;
+        locals = null;
+      }
+
+      var args = injectionArgs(fn, locals, serviceName);
+      if (isArray(fn)) {
+        fn = fn[fn.length - 1];
+      }
+
+      if (!isClass(fn)) {
+        // http://jsperf.com/angularjs-invoke-apply-vs-switch
+        // #5388
+        return fn.apply(self, args);
+      } else {
+        args.unshift(null);
+        return new (Function.prototype.bind.apply(fn, args))();
+      }
+    }
+
+
+    function instantiate(Type, locals, serviceName) {
+      // Check if Type is annotated and use just the given function at n-1 as parameter
+      // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
+      var ctor = (isArray(Type) ? Type[Type.length - 1] : Type);
+      var args = injectionArgs(Type, locals, serviceName);
+      // Empty object at position 0 is ignored for invocation with `new`, but required.
+      args.unshift(null);
+      return new (Function.prototype.bind.apply(ctor, args))();
+    }
+
+
+    return {
+      invoke: invoke,
+      instantiate: instantiate,
+      get: getService,
+      annotate: createInjector.$$annotate,
+      has: function(name) {
+        return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
+      }
+    };
+  }
+}
+
+createInjector.$$annotate = annotate;
+
+/**
+ * @ngdoc provider
+ * @name $anchorScrollProvider
+ * @this
+ *
+ * @description
+ * Use `$anchorScrollProvider` to disable automatic scrolling whenever
+ * {@link ng.$location#hash $location.hash()} changes.
+ */
+function $AnchorScrollProvider() {
+
+  var autoScrollingEnabled = true;
+
+  /**
+   * @ngdoc method
+   * @name $anchorScrollProvider#disableAutoScrolling
+   *
+   * @description
+   * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to
+   * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.<br />
+   * Use this method to disable automatic scrolling.
+   *
+   * If automatic scrolling is disabled, one must explicitly call
+   * {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the
+   * current hash.
+   */
+  this.disableAutoScrolling = function() {
+    autoScrollingEnabled = false;
+  };
+
+  /**
+   * @ngdoc service
+   * @name $anchorScroll
+   * @kind function
+   * @requires $window
+   * @requires $location
+   * @requires $rootScope
+   *
+   * @description
+   * When called, it scrolls to the element related to the specified `hash` or (if omitted) to the
+   * current value of {@link ng.$location#hash $location.hash()}, according to the rules specified
+   * in the
+   * [HTML5 spec](http://www.w3.org/html/wg/drafts/html/master/browsers.html#an-indicated-part-of-the-document).
+   *
+   * It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to
+   * match any anchor whenever it changes. This can be disabled by calling
+   * {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}.
+   *
+   * Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a
+   * vertical scroll-offset (either fixed or dynamic).
+   *
+   * @param {string=} hash The hash specifying the element to scroll to. If omitted, the value of
+   *                       {@link ng.$location#hash $location.hash()} will be used.
+   *
+   * @property {(number|function|jqLite)} yOffset
+   * If set, specifies a vertical scroll-offset. This is often useful when there are fixed
+   * positioned elements at the top of the page, such as navbars, headers etc.
+   *
+   * `yOffset` can be specified in various ways:
+   * - **number**: A fixed number of pixels to be used as offset.<br /><br />
+   * - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return
+   *   a number representing the offset (in pixels).<br /><br />
+   * - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from
+   *   the top of the page to the element's bottom will be used as offset.<br />
+   *   **Note**: The element will be taken into account only as long as its `position` is set to
+   *   `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust
+   *   their height and/or positioning according to the viewport's size.
+   *
+   * <br />
+   * <div class="alert alert-warning">
+   * In order for `yOffset` to work properly, scrolling should take place on the document's root and
+   * not some child element.
+   * </div>
+   *
+   * @example
+     <example module="anchorScrollExample" name="anchor-scroll">
+       <file name="index.html">
+         <div id="scrollArea" ng-controller="ScrollController">
+           <a ng-click="gotoBottom()">Go to bottom</a>
+           <a id="bottom"></a> You're at the bottom!
+         </div>
+       </file>
+       <file name="script.js">
+         angular.module('anchorScrollExample', [])
+           .controller('ScrollController', ['$scope', '$location', '$anchorScroll',
+             function($scope, $location, $anchorScroll) {
+               $scope.gotoBottom = function() {
+                 // set the location.hash to the id of
+                 // the element you wish to scroll to.
+                 $location.hash('bottom');
+
+                 // call $anchorScroll()
+                 $anchorScroll();
+               };
+             }]);
+       </file>
+       <file name="style.css">
+         #scrollArea {
+           height: 280px;
+           overflow: auto;
+         }
+
+         #bottom {
+           display: block;
+           margin-top: 2000px;
+         }
+       </file>
+     </example>
+   *
+   * <hr />
+   * The example below illustrates the use of a vertical scroll-offset (specified as a fixed value).
+   * See {@link ng.$anchorScroll#yOffset $anchorScroll.yOffset} for more details.
+   *
+   * @example
+     <example module="anchorScrollOffsetExample" name="anchor-scroll-offset">
+       <file name="index.html">
+         <div class="fixed-header" ng-controller="headerCtrl">
+           <a href="" ng-click="gotoAnchor(x)" ng-repeat="x in [1,2,3,4,5]">
+             Go to anchor {{x}}
+           </a>
+         </div>
+         <div id="anchor{{x}}" class="anchor" ng-repeat="x in [1,2,3,4,5]">
+           Anchor {{x}} of 5
+         </div>
+       </file>
+       <file name="script.js">
+         angular.module('anchorScrollOffsetExample', [])
+           .run(['$anchorScroll', function($anchorScroll) {
+             $anchorScroll.yOffset = 50;   // always scroll by 50 extra pixels
+           }])
+           .controller('headerCtrl', ['$anchorScroll', '$location', '$scope',
+             function($anchorScroll, $location, $scope) {
+               $scope.gotoAnchor = function(x) {
+                 var newHash = 'anchor' + x;
+                 if ($location.hash() !== newHash) {
+                   // set the $location.hash to `newHash` and
+                   // $anchorScroll will automatically scroll to it
+                   $location.hash('anchor' + x);
+                 } else {
+                   // call $anchorScroll() explicitly,
+                   // since $location.hash hasn't changed
+                   $anchorScroll();
+                 }
+               };
+             }
+           ]);
+       </file>
+       <file name="style.css">
+         body {
+           padding-top: 50px;
+         }
+
+         .anchor {
+           border: 2px dashed DarkOrchid;
+           padding: 10px 10px 200px 10px;
+         }
+
+         .fixed-header {
+           background-color: rgba(0, 0, 0, 0.2);
+           height: 50px;
+           position: fixed;
+           top: 0; left: 0; right: 0;
+         }
+
+         .fixed-header > a {
+           display: inline-block;
+           margin: 5px 15px;
+         }
+       </file>
+     </example>
+   */
+  this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
+    var document = $window.document;
+
+    // Helper function to get first anchor from a NodeList
+    // (using `Array#some()` instead of `angular#forEach()` since it's more performant
+    //  and working in all supported browsers.)
+    function getFirstAnchor(list) {
+      var result = null;
+      Array.prototype.some.call(list, function(element) {
+        if (nodeName_(element) === 'a') {
+          result = element;
+          return true;
+        }
+      });
+      return result;
+    }
+
+    function getYOffset() {
+
+      var offset = scroll.yOffset;
+
+      if (isFunction(offset)) {
+        offset = offset();
+      } else if (isElement(offset)) {
+        var elem = offset[0];
+        var style = $window.getComputedStyle(elem);
+        if (style.position !== 'fixed') {
+          offset = 0;
+        } else {
+          offset = elem.getBoundingClientRect().bottom;
+        }
+      } else if (!isNumber(offset)) {
+        offset = 0;
+      }
+
+      return offset;
+    }
+
+    function scrollTo(elem) {
+      if (elem) {
+        elem.scrollIntoView();
+
+        var offset = getYOffset();
+
+        if (offset) {
+          // `offset` is the number of pixels we should scroll UP in order to align `elem` properly.
+          // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the
+          // top of the viewport.
+          //
+          // IF the number of pixels from the top of `elem` to the end of the page's content is less
+          // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some
+          // way down the page.
+          //
+          // This is often the case for elements near the bottom of the page.
+          //
+          // In such cases we do not need to scroll the whole `offset` up, just the difference between
+          // the top of the element and the offset, which is enough to align the top of `elem` at the
+          // desired position.
+          var elemTop = elem.getBoundingClientRect().top;
+          $window.scrollBy(0, elemTop - offset);
+        }
+      } else {
+        $window.scrollTo(0, 0);
+      }
+    }
+
+    function scroll(hash) {
+      // Allow numeric hashes
+      hash = isString(hash) ? hash : isNumber(hash) ? hash.toString() : $location.hash();
+      var elm;
+
+      // empty hash, scroll to the top of the page
+      if (!hash) scrollTo(null);
+
+      // element with given id
+      else if ((elm = document.getElementById(hash))) scrollTo(elm);
+
+      // first anchor with given name :-D
+      else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);
+
+      // no element and hash === 'top', scroll to the top of the page
+      else if (hash === 'top') scrollTo(null);
+    }
+
+    // does not scroll when user clicks on anchor link that is currently on
+    // (no url change, no $location.hash() change), browser native does scroll
+    if (autoScrollingEnabled) {
+      $rootScope.$watch(function autoScrollWatch() {return $location.hash();},
+        function autoScrollWatchAction(newVal, oldVal) {
+          // skip the initial scroll if $location.hash is empty
+          if (newVal === oldVal && newVal === '') return;
+
+          jqLiteDocumentLoaded(function() {
+            $rootScope.$evalAsync(scroll);
+          });
+        });
+    }
+
+    return scroll;
+  }];
+}
+
+var $animateMinErr = minErr('$animate');
+var ELEMENT_NODE = 1;
+var NG_ANIMATE_CLASSNAME = 'ng-animate';
+
+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 extractElementNode(element) {
+  for (var i = 0; i < element.length; i++) {
+    var elm = element[i];
+    if (elm.nodeType === ELEMENT_NODE) {
+      return elm;
+    }
+  }
+}
+
+function splitClasses(classes) {
+  if (isString(classes)) {
+    classes = classes.split(' ');
+  }
+
+  // Use createMap() to prevent class assumptions involving property names in
+  // Object.prototype
+  var obj = createMap();
+  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;
+}
+
+// if any other type of options value besides an Object value is
+// passed into the $animate.method() animation then this helper code
+// will be run which will ignore it. While this patch is not the
+// greatest solution to this, a lot of existing plugins depend on
+// $animate to either call the callback (< 1.2) or return a promise
+// that can be changed. This helper function ensures that the options
+// are wiped clean incase a callback function is provided.
+function prepareAnimateOptions(options) {
+  return isObject(options)
+      ? options
+      : {};
+}
+
+var $$CoreAnimateJsProvider = /** @this */ function() {
+  this.$get = noop;
+};
+
+// this is prefixed with Core since it conflicts with
+// the animateQueueProvider defined in ngAnimate/animateQueue.js
+var $$CoreAnimateQueueProvider = /** @this */ function() {
+  var postDigestQueue = new NgMap();
+  var postDigestElements = [];
+
+  this.$get = ['$$AnimateRunner', '$rootScope',
+       function($$AnimateRunner,   $rootScope) {
+    return {
+      enabled: noop,
+      on: noop,
+      off: noop,
+      pin: noop,
+
+      push: function(element, event, options, domOperation) {
+        if (domOperation) {
+          domOperation();
+        }
+
+        options = options || {};
+        if (options.from) {
+          element.css(options.from);
+        }
+        if (options.to) {
+          element.css(options.to);
+        }
+
+        if (options.addClass || options.removeClass) {
+          addRemoveClassesPostDigest(element, options.addClass, options.removeClass);
+        }
+
+        var runner = new $$AnimateRunner();
+
+        // since there are no animations to run the runner needs to be
+        // notified that the animation call is complete.
+        runner.complete();
+        return runner;
+      }
+    };
+
+
+    function updateData(data, classes, value) {
+      var changed = false;
+      if (classes) {
+        classes = isString(classes) ? classes.split(' ') :
+                  isArray(classes) ? classes : [];
+        forEach(classes, function(className) {
+          if (className) {
+            changed = true;
+            data[className] = value;
+          }
+        });
+      }
+      return changed;
+    }
+
+    function handleCSSClassChanges() {
+      forEach(postDigestElements, function(element) {
+        var data = postDigestQueue.get(element);
+        if (data) {
+          var existing = splitClasses(element.attr('class'));
+          var toAdd = '';
+          var toRemove = '';
+          forEach(data, function(status, className) {
+            var hasClass = !!existing[className];
+            if (status !== hasClass) {
+              if (status) {
+                toAdd += (toAdd.length ? ' ' : '') + className;
+              } else {
+                toRemove += (toRemove.length ? ' ' : '') + className;
+              }
+            }
+          });
+
+          forEach(element, function(elm) {
+            if (toAdd) {
+              jqLiteAddClass(elm, toAdd);
+            }
+            if (toRemove) {
+              jqLiteRemoveClass(elm, toRemove);
+            }
+          });
+          postDigestQueue.delete(element);
+        }
+      });
+      postDigestElements.length = 0;
+    }
+
+
+    function addRemoveClassesPostDigest(element, add, remove) {
+      var data = postDigestQueue.get(element) || {};
+
+      var classesAdded = updateData(data, add, true);
+      var classesRemoved = updateData(data, remove, false);
+
+      if (classesAdded || classesRemoved) {
+
+        postDigestQueue.set(element, data);
+        postDigestElements.push(element);
+
+        if (postDigestElements.length === 1) {
+          $rootScope.$$postDigest(handleCSSClassChanges);
+        }
+      }
+    }
+  }];
+};
+
+/**
+ * @ngdoc provider
+ * @name $animateProvider
+ *
+ * @description
+ * Default implementation of $animate that doesn't perform any animations, instead just
+ * synchronously performs DOM updates and resolves the returned runner promise.
+ *
+ * In order to enable animations the `ngAnimate` module has to be loaded.
+ *
+ * To see the functional implementation check out `src/ngAnimate/animate.js`.
+ */
+var $AnimateProvider = ['$provide', /** @this */ function($provide) {
+  var provider = this;
+  var classNameFilter = null;
+
+  this.$$registeredAnimations = Object.create(null);
+
+   /**
+   * @ngdoc method
+   * @name $animateProvider#register
+   *
+   * @description
+   * Registers a new injectable animation factory function. The factory function produces the
+   * animation object which contains callback functions for each event that is expected to be
+   * animated.
+   *
+   *   * `eventFn`: `function(element, ... , doneFunction, options)`
+   *   The element to animate, the `doneFunction` and the options fed into the animation. Depending
+   *   on the type of animation additional arguments will be injected into the animation function. The
+   *   list below explains the function signatures for the different animation methods:
+   *
+   *   - setClass: function(element, addedClasses, removedClasses, doneFunction, options)
+   *   - addClass: function(element, addedClasses, doneFunction, options)
+   *   - removeClass: function(element, removedClasses, doneFunction, options)
+   *   - enter, leave, move: function(element, doneFunction, options)
+   *   - animate: function(element, fromStyles, toStyles, doneFunction, options)
+   *
+   *   Make sure to trigger the `doneFunction` once the animation is fully complete.
+   *
+   * ```js
+   *   return {
+   *     //enter, leave, move signature
+   *     eventFn : function(element, done, options) {
+   *       //code to run the animation
+   *       //once complete, then run done()
+   *       return function endFunction(wasCancelled) {
+   *         //code to cancel the animation
+   *       }
+   *     }
+   *   }
+   * ```
+   *
+   * @param {string} name The name of the animation (this is what the class-based CSS value will be compared to).
+   * @param {Function} factory The factory function that will be executed to return the animation
+   *                           object.
+   */
+  this.register = function(name, factory) {
+    if (name && name.charAt(0) !== '.') {
+      throw $animateMinErr('notcsel', 'Expecting class selector starting with \'.\' got \'{0}\'.', name);
+    }
+
+    var key = name + '-animation';
+    provider.$$registeredAnimations[name.substr(1)] = key;
+    $provide.factory(key, factory);
+  };
+
+  /**
+   * @ngdoc method
+   * @name $animateProvider#classNameFilter
+   *
+   * @description
+   * Sets and/or returns the CSS class regular expression that is checked when performing
+   * an animation. Upon bootstrap the classNameFilter value is not set at all and will
+   * therefore enable $animate to attempt to perform an animation on any element that is triggered.
+   * When setting the `classNameFilter` value, animations will only be performed on elements
+   * that successfully match the filter expression. This in turn can boost performance
+   * for low-powered devices as well as applications containing a lot of structural operations.
+   * @param {RegExp=} expression The className expression which will be checked against all animations
+   * @return {RegExp} The current CSS className expression value. If null then there is no expression value
+   */
+  this.classNameFilter = function(expression) {
+    if (arguments.length === 1) {
+      classNameFilter = (expression instanceof RegExp) ? expression : null;
+      if (classNameFilter) {
+        var reservedRegex = new RegExp('[(\\s|\\/)]' + NG_ANIMATE_CLASSNAME + '[(\\s|\\/)]');
+        if (reservedRegex.test(classNameFilter.toString())) {
+          classNameFilter = null;
+          throw $animateMinErr('nongcls', '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME);
+        }
+      }
+    }
+    return classNameFilter;
+  };
+
+  this.$get = ['$$animateQueue', function($$animateQueue) {
+    function domInsert(element, parentElement, afterElement) {
+      // if for some reason the previous element was removed
+      // from the dom sometime before this code runs then let's
+      // just stick to using the parent element as the anchor
+      if (afterElement) {
+        var afterNode = extractElementNode(afterElement);
+        if (afterNode && !afterNode.parentNode && !afterNode.previousElementSibling) {
+          afterElement = null;
+        }
+      }
+      if (afterElement) {
+        afterElement.after(element);
+      } else {
+        parentElement.prepend(element);
+      }
+    }
+
+    /**
+     * @ngdoc service
+     * @name $animate
+     * @description The $animate service exposes a series of DOM utility methods that provide support
+     * for animation hooks. The default behavior is the application of DOM operations, however,
+     * when an animation is detected (and animations are enabled), $animate will do the heavy lifting
+     * to ensure that animation runs with the triggered DOM operation.
+     *
+     * By default $animate doesn't trigger any animations. This is because the `ngAnimate` module isn't
+     * included and only when it is active then the animation hooks that `$animate` triggers will be
+     * functional. Once active then all structural `ng-` directives will trigger animations as they perform
+     * their DOM-related operations (enter, leave and move). Other directives such as `ngClass`,
+     * `ngShow`, `ngHide` and `ngMessages` also provide support for animations.
+     *
+     * It is recommended that the`$animate` service is always used when executing DOM-related procedures within directives.
+     *
+     * To learn more about enabling animation support, click here to visit the
+     * {@link ngAnimate ngAnimate module page}.
+     */
+    return {
+      // we don't call it directly since non-existant arguments may
+      // be interpreted as null within the sub enabled function
+
+      /**
+       *
+       * @ngdoc method
+       * @name $animate#on
+       * @kind function
+       * @description Sets up an event listener to fire whenever the animation event (enter, leave, move, etc...)
+       *    has fired on the given element or among any of its children. Once the listener is fired, the provided callback
+       *    is fired with the following params:
+       *
+       * ```js
+       * $animate.on('enter', container,
+       *    function callback(element, phase) {
+       *      // cool we detected an enter animation within the container
+       *    }
+       * );
+       * ```
+       *
+       * @param {string} event the animation event that will be captured (e.g. enter, leave, move, addClass, removeClass, etc...)
+       * @param {DOMElement} container the container element that will capture each of the animation events that are fired on itself
+       *     as well as among its children
+       * @param {Function} callback the callback function that will be fired when the listener is triggered
+       *
+       * The arguments present in the callback function are:
+       * * `element` - The captured DOM element that the animation was fired on.
+       * * `phase` - The phase of the animation. The two possible phases are **start** (when the animation starts) and **close** (when it ends).
+       */
+      on: $$animateQueue.on,
+
+      /**
+       *
+       * @ngdoc method
+       * @name $animate#off
+       * @kind function
+       * @description Deregisters an event listener based on the event which has been associated with the provided element. This method
+       * can be used in three different ways depending on the arguments:
+       *
+       * ```js
+       * // remove all the animation event listeners listening for `enter`
+       * $animate.off('enter');
+       *
+       * // remove listeners for all animation events from the container element
+       * $animate.off(container);
+       *
+       * // remove all the animation event listeners listening for `enter` on the given element and its children
+       * $animate.off('enter', container);
+       *
+       * // remove the event listener function provided by `callback` that is set
+       * // to listen for `enter` on the given `container` as well as its children
+       * $animate.off('enter', container, callback);
+       * ```
+       *
+       * @param {string|DOMElement} event|container the animation event (e.g. enter, leave, move,
+       * addClass, removeClass, etc...), or the container element. If it is the element, all other
+       * arguments are ignored.
+       * @param {DOMElement=} container the container element the event listener was placed on
+       * @param {Function=} callback the callback function that was registered as the listener
+       */
+      off: $$animateQueue.off,
+
+      /**
+       * @ngdoc method
+       * @name $animate#pin
+       * @kind function
+       * @description Associates the provided element with a host parent element to allow the element to be animated even if it exists
+       *    outside of the DOM structure of the Angular application. By doing so, any animation triggered via `$animate` can be issued on the
+       *    element despite being outside the realm of the application or within another application. Say for example if the application
+       *    was bootstrapped on an element that is somewhere inside of the `<body>` tag, but we wanted to allow for an element to be situated
+       *    as a direct child of `document.body`, then this can be achieved by pinning the element via `$animate.pin(element)`. Keep in mind
+       *    that calling `$animate.pin(element, parentElement)` will not actually insert into the DOM anywhere; it will just create the association.
+       *
+       *    Note that this feature is only active when the `ngAnimate` module is used.
+       *
+       * @param {DOMElement} element the external element that will be pinned
+       * @param {DOMElement} parentElement the host parent element that will be associated with the external element
+       */
+      pin: $$animateQueue.pin,
+
+      /**
+       *
+       * @ngdoc method
+       * @name $animate#enabled
+       * @kind function
+       * @description Used to get and set whether animations are enabled or not on the entire application or on an element and its children. This
+       * function can be called in four ways:
+       *
+       * ```js
+       * // returns true or false
+       * $animate.enabled();
+       *
+       * // changes the enabled state for all animations
+       * $animate.enabled(false);
+       * $animate.enabled(true);
+       *
+       * // returns true or false if animations are enabled for an element
+       * $animate.enabled(element);
+       *
+       * // changes the enabled state for an element and its children
+       * $animate.enabled(element, true);
+       * $animate.enabled(element, false);
+       * ```
+       *
+       * @param {DOMElement=} element the element that will be considered for checking/setting the enabled state
+       * @param {boolean=} enabled whether or not the animations will be enabled for the element
+       *
+       * @return {boolean} whether or not animations are enabled
+       */
+      enabled: $$animateQueue.enabled,
+
+      /**
+       * @ngdoc method
+       * @name $animate#cancel
+       * @kind function
+       * @description Cancels the provided animation.
+       *
+       * @param {Promise} animationPromise The animation promise that is returned when an animation is started.
+       */
+      cancel: function(runner) {
+        if (runner.end) {
+          runner.end();
+        }
+      },
+
+      /**
+       *
+       * @ngdoc method
+       * @name $animate#enter
+       * @kind function
+       * @description Inserts the element into the DOM either after the `after` element (if provided) or
+       *   as the first child within the `parent` element and then triggers an animation.
+       *   A promise is returned that will be resolved during the next digest once the animation
+       *   has completed.
+       *
+       * @param {DOMElement} element the element which will be inserted into the DOM
+       * @param {DOMElement} parent the parent element which will append the element as
+       *   a child (so long as the after element is not present)
+       * @param {DOMElement=} after the sibling element after which the element will be appended
+       * @param {object=} options an optional collection of options/styles that will be applied to the element.
+       *   The object can have the following properties:
+       *
+       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
+       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
+       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
+       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
+       *
+       * @return {Promise} the animation callback promise
+       */
+      enter: function(element, parent, after, options) {
+        parent = parent && jqLite(parent);
+        after = after && jqLite(after);
+        parent = parent || after.parent();
+        domInsert(element, parent, after);
+        return $$animateQueue.push(element, 'enter', prepareAnimateOptions(options));
+      },
+
+      /**
+       *
+       * @ngdoc method
+       * @name $animate#move
+       * @kind function
+       * @description Inserts (moves) the element into its new position in the DOM either after
+       *   the `after` element (if provided) or as the first child within the `parent` element
+       *   and then triggers an animation. A promise is returned that will be resolved
+       *   during the next digest once the animation has completed.
+       *
+       * @param {DOMElement} element the element which will be moved into the new DOM position
+       * @param {DOMElement} parent the parent element which will append the element as
+       *   a child (so long as the after element is not present)
+       * @param {DOMElement=} after the sibling element after which the element will be appended
+       * @param {object=} options an optional collection of options/styles that will be applied to the element.
+       *   The object can have the following properties:
+       *
+       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
+       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
+       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
+       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
+       *
+       * @return {Promise} the animation callback promise
+       */
+      move: function(element, parent, after, options) {
+        parent = parent && jqLite(parent);
+        after = after && jqLite(after);
+        parent = parent || after.parent();
+        domInsert(element, parent, after);
+        return $$animateQueue.push(element, 'move', prepareAnimateOptions(options));
+      },
+
+      /**
+       * @ngdoc method
+       * @name $animate#leave
+       * @kind function
+       * @description Triggers an animation and then removes the element from the DOM.
+       * When the function is called a promise is returned that will be resolved during the next
+       * digest once the animation has completed.
+       *
+       * @param {DOMElement} element the element which will be removed from the DOM
+       * @param {object=} options an optional collection of options/styles that will be applied to the element.
+       *   The object can have the following properties:
+       *
+       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
+       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
+       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
+       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
+       *
+       * @return {Promise} the animation callback promise
+       */
+      leave: function(element, options) {
+        return $$animateQueue.push(element, 'leave', prepareAnimateOptions(options), function() {
+          element.remove();
+        });
+      },
+
+      /**
+       * @ngdoc method
+       * @name $animate#addClass
+       * @kind function
+       *
+       * @description Triggers an addClass animation surrounding the addition of the provided CSS class(es). Upon
+       *   execution, the addClass operation will only be handled after the next digest and it will not trigger an
+       *   animation if element already contains the CSS class or if the class is removed at a later step.
+       *   Note that class-based animations are treated differently compared to structural animations
+       *   (like enter, move and leave) since the CSS classes may be added/removed at different points
+       *   depending if CSS or JavaScript animations are used.
+       *
+       * @param {DOMElement} element the element which the CSS classes will be applied to
+       * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces)
+       * @param {object=} options an optional collection of options/styles that will be applied to the element.
+       *   The object can have the following properties:
+       *
+       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
+       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
+       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
+       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
+       *
+       * @return {Promise} the animation callback promise
+       */
+      addClass: function(element, className, options) {
+        options = prepareAnimateOptions(options);
+        options.addClass = mergeClasses(options.addclass, className);
+        return $$animateQueue.push(element, 'addClass', options);
+      },
+
+      /**
+       * @ngdoc method
+       * @name $animate#removeClass
+       * @kind function
+       *
+       * @description Triggers a removeClass animation surrounding the removal of the provided CSS class(es). Upon
+       *   execution, the removeClass operation will only be handled after the next digest and it will not trigger an
+       *   animation if element does not contain the CSS class or if the class is added at a later step.
+       *   Note that class-based animations are treated differently compared to structural animations
+       *   (like enter, move and leave) since the CSS classes may be added/removed at different points
+       *   depending if CSS or JavaScript animations are used.
+       *
+       * @param {DOMElement} element the element which the CSS classes will be applied to
+       * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces)
+       * @param {object=} options an optional collection of options/styles that will be applied to the element.
+       *   The object can have the following properties:
+       *
+       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
+       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
+       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
+       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
+       *
+       * @return {Promise} the animation callback promise
+       */
+      removeClass: function(element, className, options) {
+        options = prepareAnimateOptions(options);
+        options.removeClass = mergeClasses(options.removeClass, className);
+        return $$animateQueue.push(element, 'removeClass', options);
+      },
+
+      /**
+       * @ngdoc method
+       * @name $animate#setClass
+       * @kind function
+       *
+       * @description Performs both the addition and removal of a CSS classes on an element and (during the process)
+       *    triggers an animation surrounding the class addition/removal. Much like `$animate.addClass` and
+       *    `$animate.removeClass`, `setClass` will only evaluate the classes being added/removed once a digest has
+       *    passed. Note that class-based animations are treated differently compared to structural animations
+       *    (like enter, move and leave) since the CSS classes may be added/removed at different points
+       *    depending if CSS or JavaScript animations are used.
+       *
+       * @param {DOMElement} element the element which the CSS classes will be applied to
+       * @param {string} add the CSS class(es) that will be added (multiple classes are separated via spaces)
+       * @param {string} remove the CSS class(es) that will be removed (multiple classes are separated via spaces)
+       * @param {object=} options an optional collection of options/styles that will be applied to the element.
+       *   The object can have the following properties:
+       *
+       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
+       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
+       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
+       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
+       *
+       * @return {Promise} the animation callback promise
+       */
+      setClass: function(element, add, remove, options) {
+        options = prepareAnimateOptions(options);
+        options.addClass = mergeClasses(options.addClass, add);
+        options.removeClass = mergeClasses(options.removeClass, remove);
+        return $$animateQueue.push(element, 'setClass', options);
+      },
+
+      /**
+       * @ngdoc method
+       * @name $animate#animate
+       * @kind function
+       *
+       * @description Performs an inline animation on the element which applies the provided to and from CSS styles to the element.
+       * If any detected CSS transition, keyframe or JavaScript matches the provided className value, then the animation will take
+       * on the provided styles. For example, if a transition animation is set for the given className, then the provided `from` and
+       * `to` styles will be applied alongside the given transition. If the CSS style provided in `from` does not have a corresponding
+       * style in `to`, the style in `from` is applied immediately, and no animation is run.
+       * If a JavaScript animation is detected then the provided styles will be given in as function parameters into the `animate`
+       * method (or as part of the `options` parameter):
+       *
+       * ```js
+       * ngModule.animation('.my-inline-animation', function() {
+       *   return {
+       *     animate : function(element, from, to, done, options) {
+       *       //animation
+       *       done();
+       *     }
+       *   }
+       * });
+       * ```
+       *
+       * @param {DOMElement} element the element which the CSS styles will be applied to
+       * @param {object} from the from (starting) CSS styles that will be applied to the element and across the animation.
+       * @param {object} to the to (destination) CSS styles that will be applied to the element and across the animation.
+       * @param {string=} className an optional CSS class that will be applied to the element for the duration of the animation. If
+       *    this value is left as empty then a CSS class of `ng-inline-animate` will be applied to the element.
+       *    (Note that if no animation is detected then this value will not be applied to the element.)
+       * @param {object=} options an optional collection of options/styles that will be applied to the element.
+       *   The object can have the following properties:
+       *
+       *   - **addClass** - `{string}` - space-separated CSS classes to add to element
+       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`
+       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element
+       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`
+       *
+       * @return {Promise} the animation callback promise
+       */
+      animate: function(element, from, to, className, options) {
+        options = prepareAnimateOptions(options);
+        options.from = options.from ? extend(options.from, from) : from;
+        options.to   = options.to   ? extend(options.to, to)     : to;
+
+        className = className || 'ng-inline-animate';
+        options.tempClasses = mergeClasses(options.tempClasses, className);
+        return $$animateQueue.push(element, 'animate', options);
+      }
+    };
+  }];
+}];
+
+var $$AnimateAsyncRunFactoryProvider = /** @this */ function() {
+  this.$get = ['$$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) {
+        if (passed) {
+          callback();
+        } else {
+          waitForTick(callback);
+        }
+      };
+    };
+  }];
+};
+
+var $$AnimateRunnerFactoryProvider = /** @this */ function() {
+  this.$get = ['$q', '$sniffer', '$$animateAsyncRun', '$$isDocumentHidden', '$timeout',
+       function($q,   $sniffer,   $$animateAsyncRun,   $$isDocumentHidden,   $timeout) {
+
+    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);
+
+      var rafTick = $$animateAsyncRun();
+      var timeoutTick = function(fn) {
+        $timeout(fn, 0, false);
+      };
+
+      this._doneCallbacks = [];
+      this._tick = function(fn) {
+        if ($$isDocumentHidden()) {
+          timeoutTick(fn);
+        } else {
+          rafTick(fn);
+        }
+      };
+      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) {
+              if (status === false) {
+                reject();
+              } else {
+                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._tick(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;
+  }];
+};
+
+/* exported $CoreAnimateCssProvider */
+
+/**
+ * @ngdoc service
+ * @name $animateCss
+ * @kind object
+ * @this
+ *
+ * @description
+ * This is the core version of `$animateCss`. By default, only when the `ngAnimate` is included,
+ * then the `$animateCss` service will actually perform animations.
+ *
+ * Click here {@link ngAnimate.$animateCss to read the documentation for $animateCss}.
+ */
+var $CoreAnimateCssProvider = function() {
+  this.$get = ['$$rAF', '$q', '$$AnimateRunner', function($$rAF, $q, $$AnimateRunner) {
+
+    return function(element, initialOptions) {
+      // all of the animation functions should create
+      // a copy of the options data, however, if a
+      // parent service has already created a copy then
+      // we should stick to using that
+      var options = initialOptions || {};
+      if (!options.$$prepared) {
+        options = copy(options);
+      }
+
+      // there is no point in applying the styles since
+      // there is no animation that goes on at all in
+      // this version of $animateCss.
+      if (options.cleanupStyles) {
+        options.from = options.to = null;
+      }
+
+      if (options.from) {
+        element.css(options.from);
+        options.from = null;
+      }
+
+      var closed, runner = new $$AnimateRunner();
+      return {
+        start: run,
+        end: run
+      };
+
+      function run() {
+        $$rAF(function() {
+          applyAnimationContents();
+          if (!closed) {
+            runner.complete();
+          }
+          closed = true;
+        });
+        return runner;
+      }
+
+      function applyAnimationContents() {
+        if (options.addClass) {
+          element.addClass(options.addClass);
+          options.addClass = null;
+        }
+        if (options.removeClass) {
+          element.removeClass(options.removeClass);
+          options.removeClass = null;
+        }
+        if (options.to) {
+          element.css(options.to);
+          options.to = null;
+        }
+      }
+    };
+  }];
+};
+
+/* global stripHash: true */
+
+/**
+ * ! This is a private undocumented service !
+ *
+ * @name $browser
+ * @requires $log
+ * @description
+ * This object has two goals:
+ *
+ * - hide all the global state in the browser caused by the window object
+ * - abstract away all the browser specific features and inconsistencies
+ *
+ * For tests we provide {@link ngMock.$browser mock implementation} of the `$browser`
+ * service, which can be used for convenient testing of the application without the interaction with
+ * the real browser apis.
+ */
+/**
+ * @param {object} window The global window object.
+ * @param {object} document jQuery wrapped document.
+ * @param {object} $log window.console or an object with the same interface.
+ * @param {object} $sniffer $sniffer service
+ */
+function Browser(window, document, $log, $sniffer) {
+  var self = this,
+      location = window.location,
+      history = window.history,
+      setTimeout = window.setTimeout,
+      clearTimeout = window.clearTimeout,
+      pendingDeferIds = {};
+
+  self.isMock = false;
+
+  var outstandingRequestCount = 0;
+  var outstandingRequestCallbacks = [];
+
+  // TODO(vojta): remove this temporary api
+  self.$$completeOutstandingRequest = completeOutstandingRequest;
+  self.$$incOutstandingRequestCount = function() { outstandingRequestCount++; };
+
+  /**
+   * Executes the `fn` function(supports currying) and decrements the `outstandingRequestCallbacks`
+   * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed.
+   */
+  function completeOutstandingRequest(fn) {
+    try {
+      fn.apply(null, sliceArgs(arguments, 1));
+    } finally {
+      outstandingRequestCount--;
+      if (outstandingRequestCount === 0) {
+        while (outstandingRequestCallbacks.length) {
+          try {
+            outstandingRequestCallbacks.pop()();
+          } catch (e) {
+            $log.error(e);
+          }
+        }
+      }
+    }
+  }
+
+  function getHash(url) {
+    var index = url.indexOf('#');
+    return index === -1 ? '' : url.substr(index);
+  }
+
+  /**
+   * @private
+   * Note: this method is used only by scenario runner
+   * TODO(vojta): prefix this method with $$ ?
+   * @param {function()} callback Function that will be called when no outstanding request
+   */
+  self.notifyWhenNoOutstandingRequests = function(callback) {
+    if (outstandingRequestCount === 0) {
+      callback();
+    } else {
+      outstandingRequestCallbacks.push(callback);
+    }
+  };
+
+  //////////////////////////////////////////////////////////////
+  // URL API
+  //////////////////////////////////////////////////////////////
+
+  var cachedState, lastHistoryState,
+      lastBrowserUrl = location.href,
+      baseElement = document.find('base'),
+      pendingLocation = null,
+      getCurrentState = !$sniffer.history ? noop : function getCurrentState() {
+        try {
+          return history.state;
+        } catch (e) {
+          // MSIE can reportedly throw when there is no state (UNCONFIRMED).
+        }
+      };
+
+  cacheState();
+
+  /**
+   * @name $browser#url
+   *
+   * @description
+   * GETTER:
+   * Without any argument, this method just returns current value of location.href.
+   *
+   * SETTER:
+   * With at least one argument, this method sets url to new value.
+   * If html5 history api supported, pushState/replaceState is used, otherwise
+   * location.href/location.replace is used.
+   * Returns its own instance to allow chaining
+   *
+   * NOTE: this api is intended for use only by the $location service. Please use the
+   * {@link ng.$location $location service} to change url.
+   *
+   * @param {string} url New url (when used as setter)
+   * @param {boolean=} replace Should new url replace current history record?
+   * @param {object=} state object to use with pushState/replaceState
+   */
+  self.url = function(url, replace, state) {
+    // In modern browsers `history.state` is `null` by default; treating it separately
+    // from `undefined` would cause `$browser.url('/foo')` to change `history.state`
+    // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.
+    if (isUndefined(state)) {
+      state = null;
+    }
+
+    // Android Browser BFCache causes location, history reference to become stale.
+    if (location !== window.location) location = window.location;
+    if (history !== window.history) history = window.history;
+
+    // setter
+    if (url) {
+      var sameState = lastHistoryState === state;
+
+      // Don't change anything if previous and current URLs and states match. This also prevents
+      // IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.
+      // See https://github.com/angular/angular.js/commit/ffb2701
+      if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {
+        return self;
+      }
+      var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);
+      lastBrowserUrl = url;
+      lastHistoryState = state;
+      // Don't use history API if only the hash changed
+      // due to a bug in IE10/IE11 which leads
+      // to not firing a `hashchange` nor `popstate` event
+      // in some cases (see #9143).
+      if ($sniffer.history && (!sameBase || !sameState)) {
+        history[replace ? 'replaceState' : 'pushState'](state, '', url);
+        cacheState();
+      } else {
+        if (!sameBase) {
+          pendingLocation = url;
+        }
+        if (replace) {
+          location.replace(url);
+        } else if (!sameBase) {
+          location.href = url;
+        } else {
+          location.hash = getHash(url);
+        }
+        if (location.href !== url) {
+          pendingLocation = url;
+        }
+      }
+      if (pendingLocation) {
+        pendingLocation = url;
+      }
+      return self;
+    // getter
+    } else {
+      // - pendingLocation is needed as browsers don't allow to read out
+      //   the new location.href if a reload happened or if there is a bug like in iOS 9 (see
+      //   https://openradar.appspot.com/22186109).
+      // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
+      return pendingLocation || location.href.replace(/%27/g,'\'');
+    }
+  };
+
+  /**
+   * @name $browser#state
+   *
+   * @description
+   * This method is a getter.
+   *
+   * Return history.state or null if history.state is undefined.
+   *
+   * @returns {object} state
+   */
+  self.state = function() {
+    return cachedState;
+  };
+
+  var urlChangeListeners = [],
+      urlChangeInit = false;
+
+  function cacheStateAndFireUrlChange() {
+    pendingLocation = null;
+    fireStateOrUrlChange();
+  }
+
+  // This variable should be used *only* inside the cacheState function.
+  var lastCachedState = null;
+  function cacheState() {
+    // This should be the only place in $browser where `history.state` is read.
+    cachedState = getCurrentState();
+    cachedState = isUndefined(cachedState) ? null : cachedState;
+
+    // Prevent callbacks fo fire twice if both hashchange & popstate were fired.
+    if (equals(cachedState, lastCachedState)) {
+      cachedState = lastCachedState;
+    }
+
+    lastCachedState = cachedState;
+    lastHistoryState = cachedState;
+  }
+
+  function fireStateOrUrlChange() {
+    var prevLastHistoryState = lastHistoryState;
+    cacheState();
+
+    if (lastBrowserUrl === self.url() && prevLastHistoryState === cachedState) {
+      return;
+    }
+
+    lastBrowserUrl = self.url();
+    lastHistoryState = cachedState;
+    forEach(urlChangeListeners, function(listener) {
+      listener(self.url(), cachedState);
+    });
+  }
+
+  /**
+   * @name $browser#onUrlChange
+   *
+   * @description
+   * Register callback function that will be called, when url changes.
+   *
+   * It's only called when the url is changed from outside of angular:
+   * - user types different url into address bar
+   * - user clicks on history (forward/back) button
+   * - user clicks on a link
+   *
+   * It's not called when url is changed by $browser.url() method
+   *
+   * The listener gets called with new url as parameter.
+   *
+   * NOTE: this api is intended for use only by the $location service. Please use the
+   * {@link ng.$location $location service} to monitor url changes in angular apps.
+   *
+   * @param {function(string)} listener Listener function to be called when url changes.
+   * @return {function(string)} Returns the registered listener fn - handy if the fn is anonymous.
+   */
+  self.onUrlChange = function(callback) {
+    // TODO(vojta): refactor to use node's syntax for events
+    if (!urlChangeInit) {
+      // We listen on both (hashchange/popstate) when available, as some browsers don't
+      // fire popstate when user changes the address bar and don't fire hashchange when url
+      // changed by push/replaceState
+
+      // html5 history api - popstate event
+      if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange);
+      // hashchange event
+      jqLite(window).on('hashchange', cacheStateAndFireUrlChange);
+
+      urlChangeInit = true;
+    }
+
+    urlChangeListeners.push(callback);
+    return callback;
+  };
+
+  /**
+   * @private
+   * Remove popstate and hashchange handler from window.
+   *
+   * NOTE: this api is intended for use only by $rootScope.
+   */
+  self.$$applicationDestroyed = function() {
+    jqLite(window).off('hashchange popstate', cacheStateAndFireUrlChange);
+  };
+
+  /**
+   * Checks whether the url has changed outside of Angular.
+   * Needs to be exported to be able to check for changes that have been done in sync,
+   * as hashchange/popstate events fire in async.
+   */
+  self.$$checkUrlChange = fireStateOrUrlChange;
+
+  //////////////////////////////////////////////////////////////
+  // Misc API
+  //////////////////////////////////////////////////////////////
+
+  /**
+   * @name $browser#baseHref
+   *
+   * @description
+   * Returns current <base href>
+   * (always relative - without domain)
+   *
+   * @returns {string} The current base href
+   */
+  self.baseHref = function() {
+    var href = baseElement.attr('href');
+    return href ? href.replace(/^(https?:)?\/\/[^/]*/, '') : '';
+  };
+
+  /**
+   * @name $browser#defer
+   * @param {function()} fn A function, who's execution should be deferred.
+   * @param {number=} [delay=0] of milliseconds to defer the function execution.
+   * @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`.
+   *
+   * @description
+   * Executes a fn asynchronously via `setTimeout(fn, delay)`.
+   *
+   * Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using
+   * `setTimeout` in tests, the fns are queued in an array, which can be programmatically flushed
+   * via `$browser.defer.flush()`.
+   *
+   */
+  self.defer = function(fn, delay) {
+    var timeoutId;
+    outstandingRequestCount++;
+    timeoutId = setTimeout(function() {
+      delete pendingDeferIds[timeoutId];
+      completeOutstandingRequest(fn);
+    }, delay || 0);
+    pendingDeferIds[timeoutId] = true;
+    return timeoutId;
+  };
+
+
+  /**
+   * @name $browser#defer.cancel
+   *
+   * @description
+   * Cancels a deferred task identified with `deferId`.
+   *
+   * @param {*} deferId Token returned by the `$browser.defer` function.
+   * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
+   *                    canceled.
+   */
+  self.defer.cancel = function(deferId) {
+    if (pendingDeferIds[deferId]) {
+      delete pendingDeferIds[deferId];
+      clearTimeout(deferId);
+      completeOutstandingRequest(noop);
+      return true;
+    }
+    return false;
+  };
+
+}
+
+/** @this */
+function $BrowserProvider() {
+  this.$get = ['$window', '$log', '$sniffer', '$document',
+      function($window, $log, $sniffer, $document) {
+        return new Browser($window, $document, $log, $sniffer);
+      }];
+}
+
+/**
+ * @ngdoc service
+ * @name $cacheFactory
+ * @this
+ *
+ * @description
+ * Factory that constructs {@link $cacheFactory.Cache Cache} objects and gives access to
+ * them.
+ *
+ * ```js
+ *
+ *  var cache = $cacheFactory('cacheId');
+ *  expect($cacheFactory.get('cacheId')).toBe(cache);
+ *  expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
+ *
+ *  cache.put("key", "value");
+ *  cache.put("another key", "another value");
+ *
+ *  // We've specified no options on creation
+ *  expect(cache.info()).toEqual({id: 'cacheId', size: 2});
+ *
+ * ```
+ *
+ *
+ * @param {string} cacheId Name or id of the newly created cache.
+ * @param {object=} options Options object that specifies the cache behavior. Properties:
+ *
+ *   - `{number=}` `capacity` — turns the cache into LRU cache.
+ *
+ * @returns {object} Newly created cache object with the following set of methods:
+ *
+ * - `{object}` `info()` — Returns id, size, and options of cache.
+ * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns
+ *   it.
+ * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
+ * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
+ * - `{void}` `removeAll()` — Removes all cached values.
+ * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory.
+ *
+ * @example
+   <example module="cacheExampleApp" name="cache-factory">
+     <file name="index.html">
+       <div ng-controller="CacheController">
+         <input ng-model="newCacheKey" placeholder="Key">
+         <input ng-model="newCacheValue" placeholder="Value">
+         <button ng-click="put(newCacheKey, newCacheValue)">Cache</button>
+
+         <p ng-if="keys.length">Cached Values</p>
+         <div ng-repeat="key in keys">
+           <span ng-bind="key"></span>
+           <span>: </span>
+           <b ng-bind="cache.get(key)"></b>
+         </div>
+
+         <p>Cache Info</p>
+         <div ng-repeat="(key, value) in cache.info()">
+           <span ng-bind="key"></span>
+           <span>: </span>
+           <b ng-bind="value"></b>
+         </div>
+       </div>
+     </file>
+     <file name="script.js">
+       angular.module('cacheExampleApp', []).
+         controller('CacheController', ['$scope', '$cacheFactory', function($scope, $cacheFactory) {
+           $scope.keys = [];
+           $scope.cache = $cacheFactory('cacheId');
+           $scope.put = function(key, value) {
+             if (angular.isUndefined($scope.cache.get(key))) {
+               $scope.keys.push(key);
+             }
+             $scope.cache.put(key, angular.isUndefined(value) ? null : value);
+           };
+         }]);
+     </file>
+     <file name="style.css">
+       p {
+         margin: 10px 0 3px;
+       }
+     </file>
+   </example>
+ */
+function $CacheFactoryProvider() {
+
+  this.$get = function() {
+    var caches = {};
+
+    function cacheFactory(cacheId, options) {
+      if (cacheId in caches) {
+        throw minErr('$cacheFactory')('iid', 'CacheId \'{0}\' is already taken!', cacheId);
+      }
+
+      var size = 0,
+          stats = extend({}, options, {id: cacheId}),
+          data = createMap(),
+          capacity = (options && options.capacity) || Number.MAX_VALUE,
+          lruHash = createMap(),
+          freshEnd = null,
+          staleEnd = null;
+
+      /**
+       * @ngdoc type
+       * @name $cacheFactory.Cache
+       *
+       * @description
+       * A cache object used to store and retrieve data, primarily used by
+       * {@link $http $http} and the {@link ng.directive:script script} directive to cache
+       * templates and other data.
+       *
+       * ```js
+       *  angular.module('superCache')
+       *    .factory('superCache', ['$cacheFactory', function($cacheFactory) {
+       *      return $cacheFactory('super-cache');
+       *    }]);
+       * ```
+       *
+       * Example test:
+       *
+       * ```js
+       *  it('should behave like a cache', inject(function(superCache) {
+       *    superCache.put('key', 'value');
+       *    superCache.put('another key', 'another value');
+       *
+       *    expect(superCache.info()).toEqual({
+       *      id: 'super-cache',
+       *      size: 2
+       *    });
+       *
+       *    superCache.remove('another key');
+       *    expect(superCache.get('another key')).toBeUndefined();
+       *
+       *    superCache.removeAll();
+       *    expect(superCache.info()).toEqual({
+       *      id: 'super-cache',
+       *      size: 0
+       *    });
+       *  }));
+       * ```
+       */
+      return (caches[cacheId] = {
+
+        /**
+         * @ngdoc method
+         * @name $cacheFactory.Cache#put
+         * @kind function
+         *
+         * @description
+         * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be
+         * retrieved later, and incrementing the size of the cache if the key was not already
+         * present in the cache. If behaving like an LRU cache, it will also remove stale
+         * entries from the set.
+         *
+         * It will not insert undefined values into the cache.
+         *
+         * @param {string} key the key under which the cached data is stored.
+         * @param {*} value the value to store alongside the key. If it is undefined, the key
+         *    will not be stored.
+         * @returns {*} the value stored.
+         */
+        put: function(key, value) {
+          if (isUndefined(value)) return;
+          if (capacity < Number.MAX_VALUE) {
+            var lruEntry = lruHash[key] || (lruHash[key] = {key: key});
+
+            refresh(lruEntry);
+          }
+
+          if (!(key in data)) size++;
+          data[key] = value;
+
+          if (size > capacity) {
+            this.remove(staleEnd.key);
+          }
+
+          return value;
+        },
+
+        /**
+         * @ngdoc method
+         * @name $cacheFactory.Cache#get
+         * @kind function
+         *
+         * @description
+         * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object.
+         *
+         * @param {string} key the key of the data to be retrieved
+         * @returns {*} the value stored.
+         */
+        get: function(key) {
+          if (capacity < Number.MAX_VALUE) {
+            var lruEntry = lruHash[key];
+
+            if (!lruEntry) return;
+
+            refresh(lruEntry);
+          }
+
+          return data[key];
+        },
+
+
+        /**
+         * @ngdoc method
+         * @name $cacheFactory.Cache#remove
+         * @kind function
+         *
+         * @description
+         * Removes an entry from the {@link $cacheFactory.Cache Cache} object.
+         *
+         * @param {string} key the key of the entry to be removed
+         */
+        remove: function(key) {
+          if (capacity < Number.MAX_VALUE) {
+            var lruEntry = lruHash[key];
+
+            if (!lruEntry) return;
+
+            if (lruEntry === freshEnd) freshEnd = lruEntry.p;
+            if (lruEntry === staleEnd) staleEnd = lruEntry.n;
+            link(lruEntry.n,lruEntry.p);
+
+            delete lruHash[key];
+          }
+
+          if (!(key in data)) return;
+
+          delete data[key];
+          size--;
+        },
+
+
+        /**
+         * @ngdoc method
+         * @name $cacheFactory.Cache#removeAll
+         * @kind function
+         *
+         * @description
+         * Clears the cache object of any entries.
+         */
+        removeAll: function() {
+          data = createMap();
+          size = 0;
+          lruHash = createMap();
+          freshEnd = staleEnd = null;
+        },
+
+
+        /**
+         * @ngdoc method
+         * @name $cacheFactory.Cache#destroy
+         * @kind function
+         *
+         * @description
+         * Destroys the {@link $cacheFactory.Cache Cache} object entirely,
+         * removing it from the {@link $cacheFactory $cacheFactory} set.
+         */
+        destroy: function() {
+          data = null;
+          stats = null;
+          lruHash = null;
+          delete caches[cacheId];
+        },
+
+
+        /**
+         * @ngdoc method
+         * @name $cacheFactory.Cache#info
+         * @kind function
+         *
+         * @description
+         * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}.
+         *
+         * @returns {object} an object with the following properties:
+         *   <ul>
+         *     <li>**id**: the id of the cache instance</li>
+         *     <li>**size**: the number of entries kept in the cache instance</li>
+         *     <li>**...**: any additional properties from the options object when creating the
+         *       cache.</li>
+         *   </ul>
+         */
+        info: function() {
+          return extend({}, stats, {size: size});
+        }
+      });
+
+
+      /**
+       * makes the `entry` the freshEnd of the LRU linked list
+       */
+      function refresh(entry) {
+        if (entry !== freshEnd) {
+          if (!staleEnd) {
+            staleEnd = entry;
+          } else if (staleEnd === entry) {
+            staleEnd = entry.n;
+          }
+
+          link(entry.n, entry.p);
+          link(entry, freshEnd);
+          freshEnd = entry;
+          freshEnd.n = null;
+        }
+      }
+
+
+      /**
+       * bidirectionally links two entries of the LRU linked list
+       */
+      function link(nextEntry, prevEntry) {
+        if (nextEntry !== prevEntry) {
+          if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify
+          if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify
+        }
+      }
+    }
+
+
+  /**
+   * @ngdoc method
+   * @name $cacheFactory#info
+   *
+   * @description
+   * Get information about all the caches that have been created
+   *
+   * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`
+   */
+    cacheFactory.info = function() {
+      var info = {};
+      forEach(caches, function(cache, cacheId) {
+        info[cacheId] = cache.info();
+      });
+      return info;
+    };
+
+
+  /**
+   * @ngdoc method
+   * @name $cacheFactory#get
+   *
+   * @description
+   * Get access to a cache object by the `cacheId` used when it was created.
+   *
+   * @param {string} cacheId Name or id of a cache to access.
+   * @returns {object} Cache object identified by the cacheId or undefined if no such cache.
+   */
+    cacheFactory.get = function(cacheId) {
+      return caches[cacheId];
+    };
+
+
+    return cacheFactory;
+  };
+}
+
+/**
+ * @ngdoc service
+ * @name $templateCache
+ * @this
+ *
+ * @description
+ * The first time a template is used, it is loaded in the template cache for quick retrieval. You
+ * can load templates directly into the cache in a `script` tag, or by consuming the
+ * `$templateCache` service directly.
+ *
+ * Adding via the `script` tag:
+ *
+ * ```html
+ *   <script type="text/ng-template" id="templateId.html">
+ *     <p>This is the content of the template</p>
+ *   </script>
+ * ```
+ *
+ * **Note:** the `script` tag containing the template does not need to be included in the `head` of
+ * the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE,
+ * element with ng-app attribute), otherwise the template will be ignored.
+ *
+ * Adding via the `$templateCache` service:
+ *
+ * ```js
+ * var myApp = angular.module('myApp', []);
+ * myApp.run(function($templateCache) {
+ *   $templateCache.put('templateId.html', 'This is the content of the template');
+ * });
+ * ```
+ *
+ * To retrieve the template later, simply use it in your component:
+ * ```js
+ * myApp.component('myComponent', {
+ *    templateUrl: 'templateId.html'
+ * });
+ * ```
+ *
+ * or get it via the `$templateCache` service:
+ * ```js
+ * $templateCache.get('templateId.html')
+ * ```
+ *
+ * See {@link ng.$cacheFactory $cacheFactory}.
+ *
+ */
+function $TemplateCacheProvider() {
+  this.$get = ['$cacheFactory', function($cacheFactory) {
+    return $cacheFactory('templates');
+  }];
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *     Any commits to this file should be reviewed with security in mind.  *
+ *   Changes to this file can potentially create security vulnerabilities. *
+ *          An approval from 2 Core members with history of modifying      *
+ *                         this file is required.                          *
+ *                                                                         *
+ *  Does the change somehow allow for arbitrary javascript to be executed? *
+ *    Or allows for someone to change the prototype of built-in objects?   *
+ *     Or gives undesired access to variables like document or window?    *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE!
+ *
+ * DOM-related variables:
+ *
+ * - "node" - DOM Node
+ * - "element" - DOM Element or Node
+ * - "$node" or "$element" - jqLite-wrapped node or element
+ *
+ *
+ * Compiler related stuff:
+ *
+ * - "linkFn" - linking fn of a single directive
+ * - "nodeLinkFn" - function that aggregates all linking fns for a particular node
+ * - "childLinkFn" -  function that aggregates all linking fns for child nodes of a particular node
+ * - "compositeLinkFn" - function that aggregates all linking fns for a compilation root (nodeList)
+ */
+
+
+/**
+ * @ngdoc service
+ * @name $compile
+ * @kind function
+ *
+ * @description
+ * Compiles an HTML string or DOM into a template and produces a template function, which
+ * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together.
+ *
+ * The compilation is a process of walking the DOM tree and matching DOM elements to
+ * {@link ng.$compileProvider#directive directives}.
+ *
+ * <div class="alert alert-warning">
+ * **Note:** This document is an in-depth reference of all directive options.
+ * For a gentle introduction to directives with examples of common use cases,
+ * see the {@link guide/directive directive guide}.
+ * </div>
+ *
+ * ## Comprehensive Directive API
+ *
+ * There are many different options for a directive.
+ *
+ * The difference resides in the return value of the factory function.
+ * You can either return a {@link $compile#directive-definition-object Directive Definition Object (see below)}
+ * that defines the directive properties, or just the `postLink` function (all other properties will have
+ * the default values).
+ *
+ * <div class="alert alert-success">
+ * **Best Practice:** It's recommended to use the "directive definition object" form.
+ * </div>
+ *
+ * Here's an example directive declared with a Directive Definition Object:
+ *
+ * ```js
+ *   var myModule = angular.module(...);
+ *
+ *   myModule.directive('directiveName', function factory(injectables) {
+ *     var directiveDefinitionObject = {
+ *       {@link $compile#-priority- priority}: 0,
+ *       {@link $compile#-template- template}: '<div></div>', // or // function(tElement, tAttrs) { ... },
+ *       // or
+ *       // {@link $compile#-templateurl- templateUrl}: 'directive.html', // or // function(tElement, tAttrs) { ... },
+ *       {@link $compile#-transclude- transclude}: false,
+ *       {@link $compile#-restrict- restrict}: 'A',
+ *       {@link $compile#-templatenamespace- templateNamespace}: 'html',
+ *       {@link $compile#-scope- scope}: false,
+ *       {@link $compile#-controller- controller}: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
+ *       {@link $compile#-controlleras- controllerAs}: 'stringIdentifier',
+ *       {@link $compile#-bindtocontroller- bindToController}: false,
+ *       {@link $compile#-require- require}: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
+ *       {@link $compile#-multielement- multiElement}: false,
+ *       {@link $compile#-compile- compile}: function compile(tElement, tAttrs, transclude) {
+ *         return {
+ *            {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },
+ *            {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }
+ *         }
+ *         // or
+ *         // return function postLink( ... ) { ... }
+ *       },
+ *       // or
+ *       // {@link $compile#-link- link}: {
+ *       //  {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },
+ *       //  {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }
+ *       // }
+ *       // or
+ *       // {@link $compile#-link- link}: function postLink( ... ) { ... }
+ *     };
+ *     return directiveDefinitionObject;
+ *   });
+ * ```
+ *
+ * <div class="alert alert-warning">
+ * **Note:** Any unspecified options will use the default value. You can see the default values below.
+ * </div>
+ *
+ * Therefore the above can be simplified as:
+ *
+ * ```js
+ *   var myModule = angular.module(...);
+ *
+ *   myModule.directive('directiveName', function factory(injectables) {
+ *     var directiveDefinitionObject = {
+ *       link: function postLink(scope, iElement, iAttrs) { ... }
+ *     };
+ *     return directiveDefinitionObject;
+ *     // or
+ *     // return function postLink(scope, iElement, iAttrs) { ... }
+ *   });
+ * ```
+ *
+ * ### Life-cycle hooks
+ * Directive controllers can provide the following methods that are called by Angular at points in the life-cycle of the
+ * directive:
+ * * `$onInit()` - Called on each controller after all the controllers on an element have been constructed and
+ *   had their bindings initialized (and before the pre &amp; post linking functions for the directives on
+ *   this element). This is a good place to put initialization code for your controller.
+ * * `$onChanges(changesObj)` - Called whenever one-way (`<`) or interpolation (`@`) bindings are updated. The
+ *   `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an
+ *   object of the form `{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a
+ *   component such as cloning the bound value to prevent accidental mutation of the outer value. Note that this will
+ *   also be called when your bindings are initialized.
+ * * `$doCheck()` - Called on each turn of the digest cycle. Provides an opportunity to detect and act on
+ *   changes. Any actions that you wish to take in response to the changes that you detect must be
+ *   invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
+ *   could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
+ *   be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
+ *   if detecting changes, you must store the previous value(s) for comparison to the current values.
+ * * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
+ *   external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in
+ *   the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent
+ *   components will have their `$onDestroy()` hook called before child components.
+ * * `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link
+ *   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
+ *   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
+ *   they are waiting for their template to load asynchronously and their own compilation and linking has been
+ *   suspended until that occurs.
+ *
+ * #### Comparison with Angular 2 life-cycle hooks
+ * Angular 2 also uses life-cycle hooks for its components. While the Angular 1 life-cycle hooks are similar there are
+ * some differences that you should be aware of, especially when it comes to moving your code from Angular 1 to Angular 2:
+ *
+ * * Angular 1 hooks are prefixed with `$`, such as `$onInit`. Angular 2 hooks are prefixed with `ng`, such as `ngOnInit`.
+ * * Angular 1 hooks can be defined on the controller prototype or added to the controller inside its constructor.
+ *   In Angular 2 you can only define hooks on the prototype of the Component class.
+ * * Due to the differences in change-detection, you may get many more calls to `$doCheck` in Angular 1 than you would to
+ *   `ngDoCheck` in Angular 2
+ * * Changes to the model inside `$doCheck` will trigger new turns of the digest loop, which will cause the changes to be
+ *   propagated throughout the application.
+ *   Angular 2 does not allow the `ngDoCheck` hook to trigger a change outside of the component. It will either throw an
+ *   error or do nothing depending upon the state of `enableProdMode()`.
+ *
+ * #### Life-cycle hook examples
+ *
+ * This example shows how you can check for mutations to a Date object even though the identity of the object
+ * has not changed.
+ *
+ * <example name="doCheckDateExample" module="do-check-module">
+ *   <file name="app.js">
+ *     angular.module('do-check-module', [])
+ *       .component('app', {
+ *         template:
+ *           'Month: <input ng-model="$ctrl.month" ng-change="$ctrl.updateDate()">' +
+ *           'Date: {{ $ctrl.date }}' +
+ *           '<test date="$ctrl.date"></test>',
+ *         controller: function() {
+ *           this.date = new Date();
+ *           this.month = this.date.getMonth();
+ *           this.updateDate = function() {
+ *             this.date.setMonth(this.month);
+ *           };
+ *         }
+ *       })
+ *       .component('test', {
+ *         bindings: { date: '<' },
+ *         template:
+ *           '<pre>{{ $ctrl.log | json }}</pre>',
+ *         controller: function() {
+ *           var previousValue;
+ *           this.log = [];
+ *           this.$doCheck = function() {
+ *             var currentValue = this.date && this.date.valueOf();
+ *             if (previousValue !== currentValue) {
+ *               this.log.push('doCheck: date mutated: ' + this.date);
+ *               previousValue = currentValue;
+ *             }
+ *           };
+ *         }
+ *       });
+ *   </file>
+ *   <file name="index.html">
+ *     <app></app>
+ *   </file>
+ * </example>
+ *
+ * This example show how you might use `$doCheck` to trigger changes in your component's inputs even if the
+ * actual identity of the component doesn't change. (Be aware that cloning and deep equality checks on large
+ * arrays or objects can have a negative impact on your application performance)
+ *
+ * <example name="doCheckArrayExample" module="do-check-module">
+ *   <file name="index.html">
+ *     <div ng-init="items = []">
+ *       <button ng-click="items.push(items.length)">Add Item</button>
+ *       <button ng-click="items = []">Reset Items</button>
+ *       <pre>{{ items }}</pre>
+ *       <test items="items"></test>
+ *     </div>
+ *   </file>
+ *   <file name="app.js">
+ *      angular.module('do-check-module', [])
+ *        .component('test', {
+ *          bindings: { items: '<' },
+ *          template:
+ *            '<pre>{{ $ctrl.log | json }}</pre>',
+ *          controller: function() {
+ *            this.log = [];
+ *
+ *            this.$doCheck = function() {
+ *              if (this.items_ref !== this.items) {
+ *                this.log.push('doCheck: items changed');
+ *                this.items_ref = this.items;
+ *              }
+ *              if (!angular.equals(this.items_clone, this.items)) {
+ *                this.log.push('doCheck: items mutated');
+ *                this.items_clone = angular.copy(this.items);
+ *              }
+ *            };
+ *          }
+ *        });
+ *   </file>
+ * </example>
+ *
+ *
+ * ### Directive Definition Object
+ *
+ * The directive definition object provides instructions to the {@link ng.$compile
+ * compiler}. The attributes are:
+ *
+ * #### `multiElement`
+ * When this property is set to true (default is `false`), the HTML compiler will collect DOM nodes between
+ * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
+ * together as the directive elements. It is recommended that this feature be used on directives
+ * which are not strictly behavioral (such as {@link ngClick}), and which
+ * do not manipulate or replace child nodes (such as {@link ngInclude}).
+ *
+ * #### `priority`
+ * When there are multiple directives defined on a single DOM element, sometimes it
+ * is necessary to specify the order in which the directives are applied. The `priority` is used
+ * to sort the directives before their `compile` functions get called. Priority is defined as a
+ * number. Directives with greater numerical `priority` are compiled first. Pre-link functions
+ * are also run in priority order, but post-link functions are run in reverse order. The order
+ * of directives with the same priority is undefined. The default priority is `0`.
+ *
+ * #### `terminal`
+ * If set to true then the current `priority` will be the last set of directives
+ * which will execute (any directives at the current priority will still execute
+ * as the order of execution on same `priority` is undefined). Note that expressions
+ * and other directives used in the directive's template will also be excluded from execution.
+ *
+ * #### `scope`
+ * The scope property can be `false`, `true`, or an object:
+ *
+ * * **`false` (default):** No scope will be created for the directive. The directive will use its
+ * parent's scope.
+ *
+ * * **`true`:** A new child scope that prototypically inherits from its parent will be created for
+ * the directive's element. If multiple directives on the same element request a new scope,
+ * only one new scope is created.
+ *
+ * * **`{...}` (an object hash):** A new "isolate" scope is created for the directive's template.
+ * The 'isolate' scope differs from normal scope in that it does not prototypically
+ * inherit from its parent scope. This is useful when creating reusable components, which should not
+ * accidentally read or modify data in the parent scope. Note that an isolate scope
+ * directive without a `template` or `templateUrl` will not apply the isolate scope
+ * to its children elements.
+ *
+ * The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the
+ * directive's element. These local properties are useful for aliasing values for templates. The keys in
+ * the object hash map to the name of the property on the isolate scope; the values define how the property
+ * is bound to the parent scope, via matching attributes on the directive's element:
+ *
+ * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is
+ *   always a string since DOM attributes are strings. If no `attr` name is specified then the
+ *   attribute name is assumed to be the same as the local name. Given `<my-component
+ *   my-attr="hello {{name}}">` and the isolate scope definition `scope: { localName:'@myAttr' }`,
+ *   the directive's scope property `localName` will reflect the interpolated value of `hello
+ *   {{name}}`. As the `name` attribute changes so will the `localName` property on the directive's
+ *   scope. The `name` is read from the parent scope (not the directive's scope).
+ *
+ * * `=` or `=attr` - set up a bidirectional binding between a local scope property and an expression
+ *   passed via the attribute `attr`. The expression is evaluated in the context of the parent scope.
+ *   If no `attr` name is specified then the attribute name is assumed to be the same as the local
+ *   name. Given `<my-component my-attr="parentModel">` and the isolate scope definition `scope: {
+ *   localModel: '=myAttr' }`, the property `localModel` on the directive's scope will reflect the
+ *   value of `parentModel` on the parent scope. Changes to `parentModel` will be reflected in
+ *   `localModel` and vice versa. Optional attributes should be marked as such with a question mark:
+ *   `=?` or `=?attr`. If the binding expression is non-assignable, or if the attribute isn't
+ *   optional and doesn't exist, an exception ({@link error/$compile/nonassign `$compile:nonassign`})
+ *   will be thrown upon discovering changes to the local value, since it will be impossible to sync
+ *   them back to the parent scope. By default, the {@link ng.$rootScope.Scope#$watch `$watch`}
+ *   method is used for tracking changes, and the equality check is based on object identity.
+ *   However, if an object literal or an array literal is passed as the binding expression, the
+ *   equality check is done by value (using the {@link angular.equals} function). It's also possible
+ *   to watch the evaluated value shallowly with {@link ng.$rootScope.Scope#$watchCollection
+ *   `$watchCollection`}: use `=*` or `=*attr` (`=*?` or `=*?attr` if the attribute is optional).
+ *
+  * * `<` or `<attr` - set up a one-way (one-directional) binding between a local scope property and an
+ *   expression passed via the attribute `attr`. The expression is evaluated in the context of the
+ *   parent scope. If no `attr` name is specified then the attribute name is assumed to be the same as the
+ *   local name. You can also make the binding optional by adding `?`: `<?` or `<?attr`.
+ *
+ *   For example, given `<my-component my-attr="parentModel">` and directive definition of
+ *   `scope: { localModel:'<myAttr' }`, then the isolated scope property `localModel` will reflect the
+ *   value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
+ *   in `localModel`, but changes in `localModel` will not reflect in `parentModel`. There are however
+ *   two caveats:
+ *     1. one-way binding does not copy the value from the parent to the isolate scope, it simply
+ *     sets the same value. That means if your bound value is an object, changes to its properties
+ *     in the isolated scope will be reflected in the parent scope (because both reference the same object).
+ *     2. one-way binding watches changes to the **identity** of the parent value. That means the
+ *     {@link ng.$rootScope.Scope#$watch `$watch`} on the parent value only fires if the reference
+ *     to the value has changed. In most cases, this should not be of concern, but can be important
+ *     to know if you one-way bind to an object, and then replace that object in the isolated scope.
+ *     If you now change a property of the object in your parent scope, the change will not be
+ *     propagated to the isolated scope, because the identity of the object on the parent scope
+ *     has not changed. Instead you must assign a new object.
+ *
+ *   One-way binding is useful if you do not plan to propagate changes to your isolated scope bindings
+ *   back to the parent. However, it does not make this completely impossible.
+ *
+ * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope. If
+ *   no `attr` name is specified then the attribute name is assumed to be the same as the local name.
+ *   Given `<my-component my-attr="count = count + value">` and the isolate scope definition `scope: {
+ *   localFn:'&myAttr' }`, the isolate scope property `localFn` will point to a function wrapper for
+ *   the `count = count + value` expression. Often it's desirable to pass data from the isolated scope
+ *   via an expression to the parent scope. This can be done by passing a map of local variable names
+ *   and values into the expression wrapper fn. For example, if the expression is `increment(amount)`
+ *   then we can specify the amount value by calling the `localFn` as `localFn({amount: 22})`.
+ *
+ * In general it's possible to apply more than one directive to one element, but there might be limitations
+ * depending on the type of scope required by the directives. The following points will help explain these limitations.
+ * For simplicity only two directives are taken into account, but it is also applicable for several directives:
+ *
+ * * **no scope** + **no scope** => Two directives which don't require their own scope will use their parent's scope
+ * * **child scope** + **no scope** =>  Both directives will share one single child scope
+ * * **child scope** + **child scope** =>  Both directives will share one single child scope
+ * * **isolated scope** + **no scope** =>  The isolated directive will use it's own created isolated scope. The other directive will use
+ * its parent's scope
+ * * **isolated scope** + **child scope** =>  **Won't work!** Only one scope can be related to one element. Therefore these directives cannot
+ * be applied to the same element.
+ * * **isolated scope** + **isolated scope**  =>  **Won't work!** Only one scope can be related to one element. Therefore these directives
+ * cannot be applied to the same element.
+ *
+ *
+ * #### `bindToController`
+ * This property is used to bind scope properties directly to the controller. It can be either
+ * `true` or an object hash with the same format as the `scope` property.
+ *
+ * When an isolate scope is used for a directive (see above), `bindToController: true` will
+ * allow a component to have its properties bound to the controller, rather than to scope.
+ *
+ * After the controller is instantiated, the initial values of the isolate scope bindings will be bound to the controller
+ * properties. You can access these bindings once they have been initialized by providing a controller method called
+ * `$onInit`, which is called after all the controllers on an element have been constructed and had their bindings
+ * initialized.
+ *
+ * <div class="alert alert-warning">
+ * **Deprecation warning:** although bindings for non-ES6 class controllers are currently
+ * bound to `this` before the controller constructor is called, this use is now deprecated. Please place initialization
+ * code that relies upon bindings inside a `$onInit` method on the controller, instead.
+ * </div>
+ *
+ * It is also possible to set `bindToController` to an object hash with the same format as the `scope` property.
+ * This will set up the scope bindings to the controller directly. Note that `scope` can still be used
+ * to define which kind of scope is created. By default, no scope is created. Use `scope: {}` to create an isolate
+ * scope (useful for component directives).
+ *
+ * If both `bindToController` and `scope` are defined and have object hashes, `bindToController` overrides `scope`.
+ *
+ *
+ * #### `controller`
+ * Controller constructor function. The controller is instantiated before the
+ * pre-linking phase and can be accessed by other directives (see
+ * `require` attribute). This allows the directives to communicate with each other and augment
+ * each other's behavior. The controller is injectable (and supports bracket notation) with the following locals:
+ *
+ * * `$scope` - Current scope associated with the element
+ * * `$element` - Current element
+ * * `$attrs` - Current attributes object for the element
+ * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:
+ *   `function([scope], cloneLinkingFn, futureParentElement, slotName)`:
+ *    * `scope`: (optional) override the scope.
+ *    * `cloneLinkingFn`: (optional) argument to create clones of the original transcluded content.
+ *    * `futureParentElement` (optional):
+ *        * defines the parent to which the `cloneLinkingFn` will add the cloned elements.
+ *        * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.
+ *        * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)
+ *          and when the `cloneLinkingFn` is passed,
+ *          as those elements need to created and cloned in a special way when they are defined outside their
+ *          usual containers (e.g. like `<svg>`).
+ *        * See also the `directive.templateNamespace` property.
+ *    * `slotName`: (optional) the name of the slot to transclude. If falsy (e.g. `null`, `undefined` or `''`)
+ *      then the default transclusion is provided.
+ *    The `$transclude` function also has a method on it, `$transclude.isSlotFilled(slotName)`, which returns
+ *    `true` if the specified slot contains content (i.e. one or more DOM nodes).
+ *
+ * #### `require`
+ * Require another directive and inject its controller as the fourth argument to the linking function. The
+ * `require` property can be a string, an array or an object:
+ * * a **string** containing the name of the directive to pass to the linking function
+ * * an **array** containing the names of directives to pass to the linking function. The argument passed to the
+ * linking function will be an array of controllers in the same order as the names in the `require` property
+ * * an **object** whose property values are the names of the directives to pass to the linking function. The argument
+ * passed to the linking function will also be an object with matching keys, whose values will hold the corresponding
+ * controllers.
+ *
+ * If the `require` property is an object and `bindToController` is truthy, then the required controllers are
+ * bound to the controller using the keys of the `require` property. This binding occurs after all the controllers
+ * have been constructed but before `$onInit` is called.
+ * If the name of the required controller is the same as the local name (the key), the name can be
+ * omitted. For example, `{parentDir: '^^'}` is equivalent to `{parentDir: '^^parentDir'}`.
+ * See the {@link $compileProvider#component} helper for an example of how this can be used.
+ * If no such required directive(s) can be found, or if the directive does not have a controller, then an error is
+ * raised (unless no link function is specified and the required controllers are not being bound to the directive
+ * controller, in which case error checking is skipped). The name can be prefixed with:
+ *
+ * * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
+ * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
+ * * `^` - Locate the required controller by searching the element and its parents. Throw an error if not found.
+ * * `^^` - Locate the required controller by searching the element's parents. Throw an error if not found.
+ * * `?^` - Attempt to locate the required controller by searching the element and its parents or pass
+ *   `null` to the `link` fn if not found.
+ * * `?^^` - Attempt to locate the required controller by searching the element's parents, or pass
+ *   `null` to the `link` fn if not found.
+ *
+ *
+ * #### `controllerAs`
+ * Identifier name for a reference to the controller in the directive's scope.
+ * This allows the controller to be referenced from the directive template. This is especially
+ * useful when a directive is used as component, i.e. with an `isolate` scope. It's also possible
+ * to use it in a directive without an `isolate` / `new` scope, but you need to be aware that the
+ * `controllerAs` reference might overwrite a property that already exists on the parent scope.
+ *
+ *
+ * #### `restrict`
+ * String of subset of `EACM` which restricts the directive to a specific directive
+ * declaration style. If omitted, the defaults (elements and attributes) are used.
+ *
+ * * `E` - Element name (default): `<my-directive></my-directive>`
+ * * `A` - Attribute (default): `<div my-directive="exp"></div>`
+ * * `C` - Class: `<div class="my-directive: exp;"></div>`
+ * * `M` - Comment: `<!-- directive: my-directive exp -->`
+ *
+ *
+ * #### `templateNamespace`
+ * String representing the document type used by the markup in the template.
+ * AngularJS needs this information as those elements need to be created and cloned
+ * in a special way when they are defined outside their usual containers like `<svg>` and `<math>`.
+ *
+ * * `html` - All root nodes in the template are HTML. Root nodes may also be
+ *   top-level elements such as `<svg>` or `<math>`.
+ * * `svg` - The root nodes in the template are SVG elements (excluding `<math>`).
+ * * `math` - The root nodes in the template are MathML elements (excluding `<svg>`).
+ *
+ * If no `templateNamespace` is specified, then the namespace is considered to be `html`.
+ *
+ * #### `template`
+ * HTML markup that may:
+ * * Replace the contents of the directive's element (default).
+ * * Replace the directive's element itself (if `replace` is true - DEPRECATED).
+ * * Wrap the contents of the directive's element (if `transclude` is true).
+ *
+ * Value may be:
+ *
+ * * A string. For example `<div red-on-hover>{{delete_str}}</div>`.
+ * * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile`
+ *   function api below) and returns a string value.
+ *
+ *
+ * #### `templateUrl`
+ * This is similar to `template` but the template is loaded from the specified URL, asynchronously.
+ *
+ * Because template loading is asynchronous the compiler will suspend compilation of directives on that element
+ * for later when the template has been resolved.  In the meantime it will continue to compile and link
+ * sibling and parent elements as though this element had not contained any directives.
+ *
+ * The compiler does not suspend the entire compilation to wait for templates to be loaded because this
+ * would result in the whole app "stalling" until all templates are loaded asynchronously - even in the
+ * case when only one deeply nested directive has `templateUrl`.
+ *
+ * Template loading is asynchronous even if the template has been preloaded into the {@link $templateCache}
+ *
+ * You can specify `templateUrl` as a string representing the URL or as a function which takes two
+ * arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns
+ * a string value representing the url.  In either case, the template URL is passed through {@link
+ * $sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}.
+ *
+ *
+ * #### `replace` ([*DEPRECATED*!], will be removed in next major release - i.e. v2.0)
+ * specify what the template should replace. Defaults to `false`.
+ *
+ * * `true` - the template will replace the directive's element.
+ * * `false` - the template will replace the contents of the directive's element.
+ *
+ * The replacement process migrates all of the attributes / classes from the old element to the new
+ * one. See the {@link guide/directive#template-expanding-directive
+ * Directives Guide} for an example.
+ *
+ * There are very few scenarios where element replacement is required for the application function,
+ * the main one being reusable custom components that are used within SVG contexts
+ * (because SVG doesn't work with custom elements in the DOM tree).
+ *
+ * #### `transclude`
+ * Extract the contents of the element where the directive appears and make it available to the directive.
+ * The contents are compiled and provided to the directive as a **transclusion function**. See the
+ * {@link $compile#transclusion Transclusion} section below.
+ *
+ *
+ * #### `compile`
+ *
+ * ```js
+ *   function compile(tElement, tAttrs, transclude) { ... }
+ * ```
+ *
+ * The compile function deals with transforming the template DOM. Since most directives do not do
+ * template transformation, it is not used often. The compile function takes the following arguments:
+ *
+ *   * `tElement` - template element - The element where the directive has been declared. It is
+ *     safe to do template transformation on the element and child elements only.
+ *
+ *   * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared
+ *     between all directive compile functions.
+ *
+ *   * `transclude` -  [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)`
+ *
+ * <div class="alert alert-warning">
+ * **Note:** The template instance and the link instance may be different objects if the template has
+ * been cloned. For this reason it is **not** safe to do anything other than DOM transformations that
+ * apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration
+ * should be done in a linking function rather than in a compile function.
+ * </div>
+
+ * <div class="alert alert-warning">
+ * **Note:** The compile function cannot handle directives that recursively use themselves in their
+ * own templates or compile functions. Compiling these directives results in an infinite loop and
+ * stack overflow errors.
+ *
+ * This can be avoided by manually using $compile in the postLink function to imperatively compile
+ * a directive's template instead of relying on automatic template compilation via `template` or
+ * `templateUrl` declaration or manual compilation inside the compile function.
+ * </div>
+ *
+ * <div class="alert alert-danger">
+ * **Note:** The `transclude` function that is passed to the compile function is deprecated, as it
+ *   e.g. does not know about the right outer scope. Please use the transclude function that is passed
+ *   to the link function instead.
+ * </div>
+
+ * A compile function can have a return value which can be either a function or an object.
+ *
+ * * returning a (post-link) function - is equivalent to registering the linking function via the
+ *   `link` property of the config object when the compile function is empty.
+ *
+ * * returning an object with function(s) registered via `pre` and `post` properties - allows you to
+ *   control when a linking function should be called during the linking phase. See info about
+ *   pre-linking and post-linking functions below.
+ *
+ *
+ * #### `link`
+ * This property is used only if the `compile` property is not defined.
+ *
+ * ```js
+ *   function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
+ * ```
+ *
+ * The link function is responsible for registering DOM listeners as well as updating the DOM. It is
+ * executed after the template has been cloned. This is where most of the directive logic will be
+ * put.
+ *
+ *   * `scope` - {@link ng.$rootScope.Scope Scope} - The scope to be used by the
+ *     directive for registering {@link ng.$rootScope.Scope#$watch watches}.
+ *
+ *   * `iElement` - instance element - The element where the directive is to be used. It is safe to
+ *     manipulate the children of the element only in `postLink` function since the children have
+ *     already been linked.
+ *
+ *   * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared
+ *     between all directive linking functions.
+ *
+ *   * `controller` - the directive's required controller instance(s) - Instances are shared
+ *     among all directives, which allows the directives to use the controllers as a communication
+ *     channel. The exact value depends on the directive's `require` property:
+ *       * no controller(s) required: the directive's own controller, or `undefined` if it doesn't have one
+ *       * `string`: the controller instance
+ *       * `array`: array of controller instances
+ *
+ *     If a required controller cannot be found, and it is optional, the instance is `null`,
+ *     otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown.
+ *
+ *     Note that you can also require the directive's own controller - it will be made available like
+ *     any other controller.
+ *
+ *   * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
+ *     This is the same as the `$transclude` parameter of directive controllers,
+ *     see {@link ng.$compile#-controller- the controller section for details}.
+ *     `function([scope], cloneLinkingFn, futureParentElement)`.
+ *
+ * #### Pre-linking function
+ *
+ * Executed before the child elements are linked. Not safe to do DOM transformation since the
+ * compiler linking function will fail to locate the correct elements for linking.
+ *
+ * #### Post-linking function
+ *
+ * Executed after the child elements are linked.
+ *
+ * Note that child elements that contain `templateUrl` directives will not have been compiled
+ * and linked since they are waiting for their template to load asynchronously and their own
+ * compilation and linking has been suspended until that occurs.
+ *
+ * It is safe to do DOM transformation in the post-linking function on elements that are not waiting
+ * for their async templates to be resolved.
+ *
+ *
+ * ### Transclusion
+ *
+ * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and
+ * copying them to another part of the DOM, while maintaining their connection to the original AngularJS
+ * scope from where they were taken.
+ *
+ * Transclusion is used (often with {@link ngTransclude}) to insert the
+ * original contents of a directive's element into a specified place in the template of the directive.
+ * The benefit of transclusion, over simply moving the DOM elements manually, is that the transcluded
+ * content has access to the properties on the scope from which it was taken, even if the directive
+ * has isolated scope.
+ * See the {@link guide/directive#creating-a-directive-that-wraps-other-elements Directives Guide}.
+ *
+ * This makes it possible for the widget to have private state for its template, while the transcluded
+ * content has access to its originating scope.
+ *
+ * <div class="alert alert-warning">
+ * **Note:** When testing an element transclude directive you must not place the directive at the root of the
+ * DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives
+ * Testing Transclusion Directives}.
+ * </div>
+ *
+ * There are three kinds of transclusion depending upon whether you want to transclude just the contents of the
+ * directive's element, the entire element or multiple parts of the element contents:
+ *
+ * * `true` - transclude the content (i.e. the child nodes) of the directive's element.
+ * * `'element'` - transclude the whole of the directive's element including any directives on this
+ *   element that defined at a lower priority than this directive. When used, the `template`
+ *   property is ignored.
+ * * **`{...}` (an object hash):** - map elements of the content onto transclusion "slots" in the template.
+ *
+ * **Mult-slot transclusion** is declared by providing an object for the `transclude` property.
+ *
+ * This object is a map where the keys are the name of the slot to fill and the value is an element selector
+ * used to match the HTML to the slot. The element selector should be in normalized form (e.g. `myElement`)
+ * and will match the standard element variants (e.g. `my-element`, `my:element`, `data-my-element`, etc).
+ *
+ * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}
+ *
+ * If the element selector is prefixed with a `?` then that slot is optional.
+ *
+ * For example, the transclude object `{ slotA: '?myCustomElement' }` maps `<my-custom-element>` elements to
+ * the `slotA` slot, which can be accessed via the `$transclude` function or via the {@link ngTransclude} directive.
+ *
+ * Slots that are not marked as optional (`?`) will trigger a compile time error if there are no matching elements
+ * in the transclude content. If you wish to know if an optional slot was filled with content, then you can call
+ * `$transclude.isSlotFilled(slotName)` on the transclude function passed to the directive's link function and
+ * injectable into the directive's controller.
+ *
+ *
+ * #### Transclusion Functions
+ *
+ * When a directive requests transclusion, the compiler extracts its contents and provides a **transclusion
+ * function** to the directive's `link` function and `controller`. This transclusion function is a special
+ * **linking function** that will return the compiled contents linked to a new transclusion scope.
+ *
+ * <div class="alert alert-info">
+ * If you are just using {@link ngTransclude} then you don't need to worry about this function, since
+ * ngTransclude will deal with it for us.
+ * </div>
+ *
+ * If you want to manually control the insertion and removal of the transcluded content in your directive
+ * then you must use this transclude function. When you call a transclude function it returns a a jqLite/JQuery
+ * object that contains the compiled DOM, which is linked to the correct transclusion scope.
+ *
+ * When you call a transclusion function you can pass in a **clone attach function**. This function accepts
+ * two parameters, `function(clone, scope) { ... }`, where the `clone` is a fresh compiled copy of your transcluded
+ * content and the `scope` is the newly created transclusion scope, which the clone will be linked to.
+ *
+ * <div class="alert alert-info">
+ * **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a transclude function
+ * since you then get a fresh clone of the original DOM and also have access to the new transclusion scope.
+ * </div>
+ *
+ * It is normal practice to attach your transcluded content (`clone`) to the DOM inside your **clone
+ * attach function**:
+ *
+ * ```js
+ * var transcludedContent, transclusionScope;
+ *
+ * $transclude(function(clone, scope) {
+ *   element.append(clone);
+ *   transcludedContent = clone;
+ *   transclusionScope = scope;
+ * });
+ * ```
+ *
+ * Later, if you want to remove the transcluded content from your DOM then you should also destroy the
+ * associated transclusion scope:
+ *
+ * ```js
+ * transcludedContent.remove();
+ * transclusionScope.$destroy();
+ * ```
+ *
+ * <div class="alert alert-info">
+ * **Best Practice**: if you intend to add and remove transcluded content manually in your directive
+ * (by calling the transclude function to get the DOM and calling `element.remove()` to remove it),
+ * then you are also responsible for calling `$destroy` on the transclusion scope.
+ * </div>
+ *
+ * The built-in DOM manipulation directives, such as {@link ngIf}, {@link ngSwitch} and {@link ngRepeat}
+ * automatically destroy their transcluded clones as necessary so you do not need to worry about this if
+ * you are simply using {@link ngTransclude} to inject the transclusion into your directive.
+ *
+ *
+ * #### Transclusion Scopes
+ *
+ * When you call a transclude function it returns a DOM fragment that is pre-bound to a **transclusion
+ * scope**. This scope is special, in that it is a child of the directive's scope (and so gets destroyed
+ * when the directive's scope gets destroyed) but it inherits the properties of the scope from which it
+ * was taken.
+ *
+ * For example consider a directive that uses transclusion and isolated scope. The DOM hierarchy might look
+ * like this:
+ *
+ * ```html
+ * <div ng-app>
+ *   <div isolate>
+ *     <div transclusion>
+ *     </div>
+ *   </div>
+ * </div>
+ * ```
+ *
+ * The `$parent` scope hierarchy will look like this:
+ *
+   ```
+   - $rootScope
+     - isolate
+       - transclusion
+   ```
+ *
+ * but the scopes will inherit prototypically from different scopes to their `$parent`.
+ *
+   ```
+   - $rootScope
+     - transclusion
+   - isolate
+   ```
+ *
+ *
+ * ### Attributes
+ *
+ * The {@link ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the
+ * `link()` or `compile()` functions. It has a variety of uses.
+ *
+ * * *Accessing normalized attribute names:* Directives like 'ngBind' can be expressed in many ways:
+ *   'ng:bind', `data-ng-bind`, or 'x-ng-bind'. The attributes object allows for normalized access
+ *   to the attributes.
+ *
+ * * *Directive inter-communication:* All directives share the same instance of the attributes
+ *   object which allows the directives to use the attributes object as inter directive
+ *   communication.
+ *
+ * * *Supports interpolation:* Interpolation attributes are assigned to the attribute object
+ *   allowing other directives to read the interpolated value.
+ *
+ * * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes
+ *   that contain interpolation (e.g. `src="{{bar}}"`). Not only is this very efficient but it's also
+ *   the only way to easily get the actual value because during the linking phase the interpolation
+ *   hasn't been evaluated yet and so the value is at this time set to `undefined`.
+ *
+ * ```js
+ * function linkingFn(scope, elm, attrs, ctrl) {
+ *   // get the attribute value
+ *   console.log(attrs.ngModel);
+ *
+ *   // change the attribute
+ *   attrs.$set('ngModel', 'new value');
+ *
+ *   // observe changes to interpolated attribute
+ *   attrs.$observe('ngModel', function(value) {
+ *     console.log('ngModel has changed value to ' + value);
+ *   });
+ * }
+ * ```
+ *
+ * ## Example
+ *
+ * <div class="alert alert-warning">
+ * **Note**: Typically directives are registered with `module.directive`. The example below is
+ * to illustrate how `$compile` works.
+ * </div>
+ *
+ <example module="compileExample" name="compile">
+   <file name="index.html">
+    <script>
+      angular.module('compileExample', [], function($compileProvider) {
+        // configure new 'compile' directive by passing a directive
+        // factory function. The factory function injects the '$compile'
+        $compileProvider.directive('compile', function($compile) {
+          // directive factory creates a link function
+          return function(scope, element, attrs) {
+            scope.$watch(
+              function(scope) {
+                 // watch the 'compile' expression for changes
+                return scope.$eval(attrs.compile);
+              },
+              function(value) {
+                // when the 'compile' expression changes
+                // assign it into the current DOM
+                element.html(value);
+
+                // compile the new DOM and link it to the current
+                // scope.
+                // NOTE: we only compile .childNodes so that
+                // we don't get into infinite loop compiling ourselves
+                $compile(element.contents())(scope);
+              }
+            );
+          };
+        });
+      })
+      .controller('GreeterController', ['$scope', function($scope) {
+        $scope.name = 'Angular';
+        $scope.html = 'Hello {{name}}';
+      }]);
+    </script>
+    <div ng-controller="GreeterController">
+      <input ng-model="name"> <br/>
+      <textarea ng-model="html"></textarea> <br/>
+      <div compile="html"></div>
+    </div>
+   </file>
+   <file name="protractor.js" type="protractor">
+     it('should auto compile', function() {
+       var textarea = $('textarea');
+       var output = $('div[compile]');
+       // The initial state reads 'Hello Angular'.
+       expect(output.getText()).toBe('Hello Angular');
+       textarea.clear();
+       textarea.sendKeys('{{name}}!');
+       expect(output.getText()).toBe('Angular!');
+     });
+   </file>
+ </example>
+
+ *
+ *
+ * @param {string|DOMElement} element Element or HTML string to compile into a template function.
+ * @param {function(angular.Scope, cloneAttachFn=)} transclude function available to directives - DEPRECATED.
+ *
+ * <div class="alert alert-danger">
+ * **Note:** Passing a `transclude` function to the $compile function is deprecated, as it
+ *   e.g. will not use the right outer scope. Please pass the transclude function as a
+ *   `parentBoundTranscludeFn` to the link function instead.
+ * </div>
+ *
+ * @param {number} maxPriority only apply directives lower than given priority (Only effects the
+ *                 root element(s), not their children)
+ * @returns {function(scope, cloneAttachFn=, options=)} a link function which is used to bind template
+ * (a DOM element/tree) to a scope. Where:
+ *
+ *  * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to.
+ *  * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the
+ *  `template` and call the `cloneAttachFn` function allowing the caller to attach the
+ *  cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is
+ *  called as: <br/> `cloneAttachFn(clonedElement, scope)` where:
+ *
+ *      * `clonedElement` - is a clone of the original `element` passed into the compiler.
+ *      * `scope` - is the current scope with which the linking function is working with.
+ *
+ *  * `options` - An optional object hash with linking options. If `options` is provided, then the following
+ *  keys may be used to control linking behavior:
+ *
+ *      * `parentBoundTranscludeFn` - the transclude function made available to
+ *        directives; if given, it will be passed through to the link functions of
+ *        directives found in `element` during compilation.
+ *      * `transcludeControllers` - an object hash with keys that map controller names
+ *        to a hash with the key `instance`, which maps to the controller instance;
+ *        if given, it will make the controllers available to directives on the compileNode:
+ *        ```
+ *        {
+ *          parent: {
+ *            instance: parentControllerInstance
+ *          }
+ *        }
+ *        ```
+ *      * `futureParentElement` - defines the parent to which the `cloneAttachFn` will add
+ *        the cloned elements; only needed for transcludes that are allowed to contain non html
+ *        elements (e.g. SVG elements). See also the directive.controller property.
+ *
+ * Calling the linking function returns the element of the template. It is either the original
+ * element passed in, or the clone of the element if the `cloneAttachFn` is provided.
+ *
+ * After linking the view is not updated until after a call to $digest which typically is done by
+ * Angular automatically.
+ *
+ * If you need access to the bound view, there are two ways to do it:
+ *
+ * - If you are not asking the linking function to clone the template, create the DOM element(s)
+ *   before you send them to the compiler and keep this reference around.
+ *   ```js
+ *     var element = $compile('<p>{{total}}</p>')(scope);
+ *   ```
+ *
+ * - if on the other hand, you need the element to be cloned, the view reference from the original
+ *   example would not point to the clone, but rather to the original template that was cloned. In
+ *   this case, you can access the clone via the cloneAttachFn:
+ *   ```js
+ *     var templateElement = angular.element('<p>{{total}}</p>'),
+ *         scope = ....;
+ *
+ *     var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {
+ *       //attach the clone to DOM document at the right place
+ *     });
+ *
+ *     //now we have reference to the cloned DOM via `clonedElement`
+ *   ```
+ *
+ *
+ * For information on how the compiler works, see the
+ * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide.
+ *
+ * @knownIssue
+ *
+ * ### Double Compilation
+ *
+   Double compilation occurs when an already compiled part of the DOM gets
+   compiled again. This is an undesired effect and can lead to misbehaving directives, performance issues,
+   and memory leaks. Refer to the Compiler Guide {@link guide/compiler#double-compilation-and-how-to-avoid-it
+   section on double compilation} for an in-depth explanation and ways to avoid it.
+ *
+ */
+
+var $compileMinErr = minErr('$compile');
+
+function UNINITIALIZED_VALUE() {}
+var _UNINITIALIZED_VALUE = new UNINITIALIZED_VALUE();
+
+/**
+ * @ngdoc provider
+ * @name $compileProvider
+ *
+ * @description
+ */
+$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];
+/** @this */
+function $CompileProvider($provide, $$sanitizeUriProvider) {
+  var hasDirectives = {},
+      Suffix = 'Directive',
+      COMMENT_DIRECTIVE_REGEXP = /^\s*directive:\s*([\w-]+)\s+(.*)$/,
+      CLASS_DIRECTIVE_REGEXP = /(([\w-]+)(?::([^;]+))?;?)/,
+      ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),
+      REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/;
+
+  // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
+  // The assumption is that future DOM event attribute names will begin with
+  // 'on' and be composed of only English letters.
+  var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
+  var bindingCache = createMap();
+
+  function parseIsolateBindings(scope, directiveName, isController) {
+    var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*([\w$]*)\s*$/;
+
+    var bindings = createMap();
+
+    forEach(scope, function(definition, scopeName) {
+      if (definition in bindingCache) {
+        bindings[scopeName] = bindingCache[definition];
+        return;
+      }
+      var match = definition.match(LOCAL_REGEXP);
+
+      if (!match) {
+        throw $compileMinErr('iscp',
+            'Invalid {3} for directive \'{0}\'.' +
+            ' Definition: {... {1}: \'{2}\' ...}',
+            directiveName, scopeName, definition,
+            (isController ? 'controller bindings definition' :
+            'isolate scope definition'));
+      }
+
+      bindings[scopeName] = {
+        mode: match[1][0],
+        collection: match[2] === '*',
+        optional: match[3] === '?',
+        attrName: match[4] || scopeName
+      };
+      if (match[4]) {
+        bindingCache[definition] = bindings[scopeName];
+      }
+    });
+
+    return bindings;
+  }
+
+  function parseDirectiveBindings(directive, directiveName) {
+    var bindings = {
+      isolateScope: null,
+      bindToController: null
+    };
+    if (isObject(directive.scope)) {
+      if (directive.bindToController === true) {
+        bindings.bindToController = parseIsolateBindings(directive.scope,
+                                                         directiveName, true);
+        bindings.isolateScope = {};
+      } else {
+        bindings.isolateScope = parseIsolateBindings(directive.scope,
+                                                     directiveName, false);
+      }
+    }
+    if (isObject(directive.bindToController)) {
+      bindings.bindToController =
+          parseIsolateBindings(directive.bindToController, directiveName, true);
+    }
+    if (bindings.bindToController && !directive.controller) {
+      // There is no controller
+      throw $compileMinErr('noctrl',
+            'Cannot bind to controller without directive \'{0}\'s controller.',
+            directiveName);
+    }
+    return bindings;
+  }
+
+  function assertValidDirectiveName(name) {
+    var letter = name.charAt(0);
+    if (!letter || letter !== lowercase(letter)) {
+      throw $compileMinErr('baddir', 'Directive/Component name \'{0}\' is invalid. The first character must be a lowercase letter', name);
+    }
+    if (name !== name.trim()) {
+      throw $compileMinErr('baddir',
+            'Directive/Component name \'{0}\' is invalid. The name should not contain leading or trailing whitespaces',
+            name);
+    }
+  }
+
+  function getDirectiveRequire(directive) {
+    var require = directive.require || (directive.controller && directive.name);
+
+    if (!isArray(require) && isObject(require)) {
+      forEach(require, function(value, key) {
+        var match = value.match(REQUIRE_PREFIX_REGEXP);
+        var name = value.substring(match[0].length);
+        if (!name) require[key] = match[0] + key;
+      });
+    }
+
+    return require;
+  }
+
+  function getDirectiveRestrict(restrict, name) {
+    if (restrict && !(isString(restrict) && /[EACM]/.test(restrict))) {
+      throw $compileMinErr('badrestrict',
+          'Restrict property \'{0}\' of directive \'{1}\' is invalid',
+          restrict,
+          name);
+    }
+
+    return restrict || 'EA';
+  }
+
+  /**
+   * @ngdoc method
+   * @name $compileProvider#directive
+   * @kind function
+   *
+   * @description
+   * Register a new directive with the compiler.
+   *
+   * @param {string|Object} name Name of the directive in camel-case (i.e. <code>ngBind</code> which
+   *    will match as <code>ng-bind</code>), or an object map of directives where the keys are the
+   *    names and the values are the factories.
+   * @param {Function|Array} directiveFactory An injectable directive factory function. See the
+   *    {@link guide/directive directive guide} and the {@link $compile compile API} for more info.
+   * @returns {ng.$compileProvider} Self for chaining.
+   */
+  this.directive = function registerDirective(name, directiveFactory) {
+    assertArg(name, 'name');
+    assertNotHasOwnProperty(name, 'directive');
+    if (isString(name)) {
+      assertValidDirectiveName(name);
+      assertArg(directiveFactory, 'directiveFactory');
+      if (!hasDirectives.hasOwnProperty(name)) {
+        hasDirectives[name] = [];
+        $provide.factory(name + Suffix, ['$injector', '$exceptionHandler',
+          function($injector, $exceptionHandler) {
+            var directives = [];
+            forEach(hasDirectives[name], function(directiveFactory, index) {
+              try {
+                var directive = $injector.invoke(directiveFactory);
+                if (isFunction(directive)) {
+                  directive = { compile: valueFn(directive) };
+                } else if (!directive.compile && directive.link) {
+                  directive.compile = valueFn(directive.link);
+                }
+                directive.priority = directive.priority || 0;
+                directive.index = index;
+                directive.name = directive.name || name;
+                directive.require = getDirectiveRequire(directive);
+                directive.restrict = getDirectiveRestrict(directive.restrict, name);
+                directive.$$moduleName = directiveFactory.$$moduleName;
+                directives.push(directive);
+              } catch (e) {
+                $exceptionHandler(e);
+              }
+            });
+            return directives;
+          }]);
+      }
+      hasDirectives[name].push(directiveFactory);
+    } else {
+      forEach(name, reverseParams(registerDirective));
+    }
+    return this;
+  };
+
+  /**
+   * @ngdoc method
+   * @name $compileProvider#component
+   * @module ng
+   * @param {string} name Name of the component in camelCase (i.e. `myComp` which will match `<my-comp>`)
+   * @param {Object} options Component definition object (a simplified
+   *    {@link ng.$compile#directive-definition-object directive definition object}),
+   *    with the following properties (all optional):
+   *
+   *    - `controller` – `{(string|function()=}` – controller constructor function that should be
+   *      associated with newly created scope or the name of a {@link ng.$compile#-controller-
+   *      registered controller} if passed as a string. An empty `noop` function by default.
+   *    - `controllerAs` – `{string=}` – identifier name for to reference the controller in the component's scope.
+   *      If present, the controller will be published to scope under the `controllerAs` name.
+   *      If not present, this will default to be `$ctrl`.
+   *    - `template` – `{string=|function()=}` – html template as a string or a function that
+   *      returns an html template as a string which should be used as the contents of this component.
+   *      Empty string by default.
+   *
+   *      If `template` is a function, then it is {@link auto.$injector#invoke injected} with
+   *      the following locals:
+   *
+   *      - `$element` - Current element
+   *      - `$attrs` - Current attributes object for the element
+   *
+   *    - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
+   *      template that should be used  as the contents of this component.
+   *
+   *      If `templateUrl` is a function, then it is {@link auto.$injector#invoke injected} with
+   *      the following locals:
+   *
+   *      - `$element` - Current element
+   *      - `$attrs` - Current attributes object for the element
+   *
+   *    - `bindings` – `{object=}` – defines bindings between DOM attributes and component properties.
+   *      Component properties are always bound to the component controller and not to the scope.
+   *      See {@link ng.$compile#-bindtocontroller- `bindToController`}.
+   *    - `transclude` – `{boolean=}` – whether {@link $compile#transclusion content transclusion} is enabled.
+   *      Disabled by default.
+   *    - `require` - `{Object<string, string>=}` - requires the controllers of other directives and binds them to
+   *      this component's controller. The object keys specify the property names under which the required
+   *      controllers (object values) will be bound. See {@link ng.$compile#-require- `require`}.
+   *    - `$...` – additional properties to attach to the directive factory function and the controller
+   *      constructor function. (This is used by the component router to annotate)
+   *
+   * @returns {ng.$compileProvider} the compile provider itself, for chaining of function calls.
+   * @description
+   * Register a **component definition** with the compiler. This is a shorthand for registering a special
+   * type of directive, which represents a self-contained UI component in your application. Such components
+   * are always isolated (i.e. `scope: {}`) and are always restricted to elements (i.e. `restrict: 'E'`).
+   *
+   * Component definitions are very simple and do not require as much configuration as defining general
+   * directives. Component definitions usually consist only of a template and a controller backing it.
+   *
+   * In order to make the definition easier, components enforce best practices like use of `controllerAs`,
+   * `bindToController`. They always have **isolate scope** and are restricted to elements.
+   *
+   * Here are a few examples of how you would usually define components:
+   *
+   * ```js
+   *   var myMod = angular.module(...);
+   *   myMod.component('myComp', {
+   *     template: '<div>My name is {{$ctrl.name}}</div>',
+   *     controller: function() {
+   *       this.name = 'shahar';
+   *     }
+   *   });
+   *
+   *   myMod.component('myComp', {
+   *     template: '<div>My name is {{$ctrl.name}}</div>',
+   *     bindings: {name: '@'}
+   *   });
+   *
+   *   myMod.component('myComp', {
+   *     templateUrl: 'views/my-comp.html',
+   *     controller: 'MyCtrl',
+   *     controllerAs: 'ctrl',
+   *     bindings: {name: '@'}
+   *   });
+   *
+   * ```
+   * For more examples, and an in-depth guide, see the {@link guide/component component guide}.
+   *
+   * <br />
+   * See also {@link ng.$compileProvider#directive $compileProvider.directive()}.
+   */
+  this.component = function registerComponent(name, options) {
+    var controller = options.controller || function() {};
+
+    function factory($injector) {
+      function makeInjectable(fn) {
+        if (isFunction(fn) || isArray(fn)) {
+          return /** @this */ function(tElement, tAttrs) {
+            return $injector.invoke(fn, this, {$element: tElement, $attrs: tAttrs});
+          };
+        } else {
+          return fn;
+        }
+      }
+
+      var template = (!options.template && !options.templateUrl ? '' : options.template);
+      var ddo = {
+        controller: controller,
+        controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',
+        template: makeInjectable(template),
+        templateUrl: makeInjectable(options.templateUrl),
+        transclude: options.transclude,
+        scope: {},
+        bindToController: options.bindings || {},
+        restrict: 'E',
+        require: options.require
+      };
+
+      // Copy annotations (starting with $) over to the DDO
+      forEach(options, function(val, key) {
+        if (key.charAt(0) === '$') ddo[key] = val;
+      });
+
+      return ddo;
+    }
+
+    // TODO(pete) remove the following `forEach` before we release 1.6.0
+    // The component-router@0.2.0 looks for the annotations on the controller constructor
+    // Nothing in Angular looks for annotations on the factory function but we can't remove
+    // it from 1.5.x yet.
+
+    // Copy any annotation properties (starting with $) over to the factory and controller constructor functions
+    // These could be used by libraries such as the new component router
+    forEach(options, function(val, key) {
+      if (key.charAt(0) === '$') {
+        factory[key] = val;
+        // Don't try to copy over annotations to named controller
+        if (isFunction(controller)) controller[key] = val;
+      }
+    });
+
+    factory.$inject = ['$injector'];
+
+    return this.directive(name, factory);
+  };
+
+
+  /**
+   * @ngdoc method
+   * @name $compileProvider#aHrefSanitizationWhitelist
+   * @kind function
+   *
+   * @description
+   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
+   * urls during a[href] sanitization.
+   *
+   * The sanitization is a security measure aimed at preventing XSS attacks via html links.
+   *
+   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
+   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
+   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
+   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
+   *
+   * @param {RegExp=} regexp New regexp to whitelist urls with.
+   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
+   *    chaining otherwise.
+   */
+  this.aHrefSanitizationWhitelist = function(regexp) {
+    if (isDefined(regexp)) {
+      $$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);
+      return this;
+    } else {
+      return $$sanitizeUriProvider.aHrefSanitizationWhitelist();
+    }
+  };
+
+
+  /**
+   * @ngdoc method
+   * @name $compileProvider#imgSrcSanitizationWhitelist
+   * @kind function
+   *
+   * @description
+   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
+   * urls during img[src] sanitization.
+   *
+   * The sanitization is a security measure aimed at prevent XSS attacks via html links.
+   *
+   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into
+   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
+   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
+   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
+   *
+   * @param {RegExp=} regexp New regexp to whitelist urls with.
+   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
+   *    chaining otherwise.
+   */
+  this.imgSrcSanitizationWhitelist = function(regexp) {
+    if (isDefined(regexp)) {
+      $$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);
+      return this;
+    } else {
+      return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();
+    }
+  };
+
+  /**
+   * @ngdoc method
+   * @name  $compileProvider#debugInfoEnabled
+   *
+   * @param {boolean=} enabled update the debugInfoEnabled state if provided, otherwise just return the
+   * current debugInfoEnabled state
+   * @returns {*} current value if used as getter or itself (chaining) if used as setter
+   *
+   * @kind function
+   *
+   * @description
+   * Call this method to enable/disable various debug runtime information in the compiler such as adding
+   * binding information and a reference to the current scope on to DOM elements.
+   * If enabled, the compiler will add the following to DOM elements that have been bound to the scope
+   * * `ng-binding` CSS class
+   * * `$binding` data property containing an array of the binding expressions
+   *
+   * You may want to disable this in production for a significant performance boost. See
+   * {@link guide/production#disabling-debug-data Disabling Debug Data} for more.
+   *
+   * The default value is true.
+   */
+  var debugInfoEnabled = true;
+  this.debugInfoEnabled = function(enabled) {
+    if (isDefined(enabled)) {
+      debugInfoEnabled = enabled;
+      return this;
+    }
+    return debugInfoEnabled;
+  };
+
+  /**
+   * @ngdoc method
+   * @name  $compileProvider#preAssignBindingsEnabled
+   *
+   * @param {boolean=} enabled update the preAssignBindingsEnabled state if provided, otherwise just return the
+   * current preAssignBindingsEnabled state
+   * @returns {*} current value if used as getter or itself (chaining) if used as setter
+   *
+   * @kind function
+   *
+   * @description
+   * Call this method to enable/disable whether directive controllers are assigned bindings before
+   * calling the controller's constructor.
+   * If enabled (true), the compiler assigns the value of each of the bindings to the
+   * properties of the controller object before the constructor of this object is called.
+   *
+   * If disabled (false), the compiler calls the constructor first before assigning bindings.
+   *
+   * The default value is true in Angular 1.5.x but will switch to false in Angular 1.6.x.
+   */
+  var preAssignBindingsEnabled = false;
+  this.preAssignBindingsEnabled = function(enabled) {
+    if (isDefined(enabled)) {
+      preAssignBindingsEnabled = enabled;
+      return this;
+    }
+    return preAssignBindingsEnabled;
+  };
+
+
+  var TTL = 10;
+  /**
+   * @ngdoc method
+   * @name $compileProvider#onChangesTtl
+   * @description
+   *
+   * Sets the number of times `$onChanges` hooks can trigger new changes before giving up and
+   * assuming that the model is unstable.
+   *
+   * The current default is 10 iterations.
+   *
+   * In complex applications it's possible that dependencies between `$onChanges` hooks and bindings will result
+   * in several iterations of calls to these hooks. However if an application needs more than the default 10
+   * iterations to stabilize then you should investigate what is causing the model to continuously change during
+   * the `$onChanges` hook execution.
+   *
+   * Increasing the TTL could have performance implications, so you should not change it without proper justification.
+   *
+   * @param {number} limit The number of `$onChanges` hook iterations.
+   * @returns {number|object} the current limit (or `this` if called as a setter for chaining)
+   */
+  this.onChangesTtl = function(value) {
+    if (arguments.length) {
+      TTL = value;
+      return this;
+    }
+    return TTL;
+  };
+
+  var commentDirectivesEnabledConfig = true;
+  /**
+   * @ngdoc method
+   * @name $compileProvider#commentDirectivesEnabled
+   * @description
+   *
+   * It indicates to the compiler
+   * whether or not directives on comments should be compiled.
+   * Defaults to `true`.
+   *
+   * Calling this function with false disables the compilation of directives
+   * on comments for the whole application.
+   * This results in a compilation performance gain,
+   * as the compiler doesn't have to check comments when looking for directives.
+   * This should however only be used if you are sure that no comment directives are used in
+   * the application (including any 3rd party directives).
+   *
+   * @param {boolean} enabled `false` if the compiler may ignore directives on comments
+   * @returns {boolean|object} the current value (or `this` if called as a setter for chaining)
+   */
+  this.commentDirectivesEnabled = function(value) {
+    if (arguments.length) {
+      commentDirectivesEnabledConfig = value;
+      return this;
+    }
+    return commentDirectivesEnabledConfig;
+  };
+
+
+  var cssClassDirectivesEnabledConfig = true;
+  /**
+   * @ngdoc method
+   * @name $compileProvider#cssClassDirectivesEnabled
+   * @description
+   *
+   * It indicates to the compiler
+   * whether or not directives on element classes should be compiled.
+   * Defaults to `true`.
+   *
+   * Calling this function with false disables the compilation of directives
+   * on element classes for the whole application.
+   * This results in a compilation performance gain,
+   * as the compiler doesn't have to check element classes when looking for directives.
+   * This should however only be used if you are sure that no class directives are used in
+   * the application (including any 3rd party directives).
+   *
+   * @param {boolean} enabled `false` if the compiler may ignore directives on element classes
+   * @returns {boolean|object} the current value (or `this` if called as a setter for chaining)
+   */
+  this.cssClassDirectivesEnabled = function(value) {
+    if (arguments.length) {
+      cssClassDirectivesEnabledConfig = value;
+      return this;
+    }
+    return cssClassDirectivesEnabledConfig;
+  };
+
+  this.$get = [
+            '$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',
+            '$controller', '$rootScope', '$sce', '$animate', '$$sanitizeUri',
+    function($injector,   $interpolate,   $exceptionHandler,   $templateRequest,   $parse,
+             $controller,   $rootScope,   $sce,   $animate,   $$sanitizeUri) {
+
+    var SIMPLE_ATTR_NAME = /^\w/;
+    var specialAttrHolder = window.document.createElement('div');
+
+
+    var commentDirectivesEnabled = commentDirectivesEnabledConfig;
+    var cssClassDirectivesEnabled = cssClassDirectivesEnabledConfig;
+
+
+    var onChangesTtl = TTL;
+    // The onChanges hooks should all be run together in a single digest
+    // When changes occur, the call to trigger their hooks will be added to this queue
+    var onChangesQueue;
+
+    // This function is called in a $$postDigest to trigger all the onChanges hooks in a single digest
+    function flushOnChangesQueue() {
+      try {
+        if (!(--onChangesTtl)) {
+          // We have hit the TTL limit so reset everything
+          onChangesQueue = undefined;
+          throw $compileMinErr('infchng', '{0} $onChanges() iterations reached. Aborting!\n', TTL);
+        }
+        // We must run this hook in an apply since the $$postDigest runs outside apply
+        $rootScope.$apply(function() {
+          var errors = [];
+          for (var i = 0, ii = onChangesQueue.length; i < ii; ++i) {
+            try {
+              onChangesQueue[i]();
+            } catch (e) {
+              errors.push(e);
+            }
+          }
+          // Reset the queue to trigger a new schedule next time there is a change
+          onChangesQueue = undefined;
+          if (errors.length) {
+            throw errors;
+          }
+        });
+      } finally {
+        onChangesTtl++;
+      }
+    }
+
+
+    function Attributes(element, attributesToCopy) {
+      if (attributesToCopy) {
+        var keys = Object.keys(attributesToCopy);
+        var i, l, key;
+
+        for (i = 0, l = keys.length; i < l; i++) {
+          key = keys[i];
+          this[key] = attributesToCopy[key];
+        }
+      } else {
+        this.$attr = {};
+      }
+
+      this.$$element = element;
+    }
+
+    Attributes.prototype = {
+      /**
+       * @ngdoc method
+       * @name $compile.directive.Attributes#$normalize
+       * @kind function
+       *
+       * @description
+       * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with `x-` or
+       * `data-`) to its normalized, camelCase form.
+       *
+       * Also there is special case for Moz prefix starting with upper case letter.
+       *
+       * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}
+       *
+       * @param {string} name Name to normalize
+       */
+      $normalize: directiveNormalize,
+
+
+      /**
+       * @ngdoc method
+       * @name $compile.directive.Attributes#$addClass
+       * @kind function
+       *
+       * @description
+       * Adds the CSS class value specified by the classVal parameter to the element. If animations
+       * are enabled then an animation will be triggered for the class addition.
+       *
+       * @param {string} classVal The className value that will be added to the element
+       */
+      $addClass: function(classVal) {
+        if (classVal && classVal.length > 0) {
+          $animate.addClass(this.$$element, classVal);
+        }
+      },
+
+      /**
+       * @ngdoc method
+       * @name $compile.directive.Attributes#$removeClass
+       * @kind function
+       *
+       * @description
+       * Removes the CSS class value specified by the classVal parameter from the element. If
+       * animations are enabled then an animation will be triggered for the class removal.
+       *
+       * @param {string} classVal The className value that will be removed from the element
+       */
+      $removeClass: function(classVal) {
+        if (classVal && classVal.length > 0) {
+          $animate.removeClass(this.$$element, classVal);
+        }
+      },
+
+      /**
+       * @ngdoc method
+       * @name $compile.directive.Attributes#$updateClass
+       * @kind function
+       *
+       * @description
+       * Adds and removes the appropriate CSS class values to the element based on the difference
+       * between the new and old CSS class values (specified as newClasses and oldClasses).
+       *
+       * @param {string} newClasses The current CSS className value
+       * @param {string} oldClasses The former CSS className value
+       */
+      $updateClass: function(newClasses, oldClasses) {
+        var toAdd = tokenDifference(newClasses, oldClasses);
+        if (toAdd && toAdd.length) {
+          $animate.addClass(this.$$element, toAdd);
+        }
+
+        var toRemove = tokenDifference(oldClasses, newClasses);
+        if (toRemove && toRemove.length) {
+          $animate.removeClass(this.$$element, toRemove);
+        }
+      },
+
+      /**
+       * Set a normalized attribute on the element in a way such that all directives
+       * can share the attribute. This function properly handles boolean attributes.
+       * @param {string} key Normalized key. (ie ngAttribute)
+       * @param {string|boolean} value The value to set. If `null` attribute will be deleted.
+       * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute.
+       *     Defaults to true.
+       * @param {string=} attrName Optional none normalized name. Defaults to key.
+       */
+      $set: function(key, value, writeAttr, attrName) {
+        // TODO: decide whether or not to throw an error if "class"
+        //is set through this function since it may cause $updateClass to
+        //become unstable.
+
+        var node = this.$$element[0],
+            booleanKey = getBooleanAttrName(node, key),
+            aliasedKey = getAliasedAttrName(key),
+            observer = key,
+            nodeName;
+
+        if (booleanKey) {
+          this.$$element.prop(key, value);
+          attrName = booleanKey;
+        } else if (aliasedKey) {
+          this[aliasedKey] = value;
+          observer = aliasedKey;
+        }
+
+        this[key] = value;
+
+        // translate normalized key to actual key
+        if (attrName) {
+          this.$attr[key] = attrName;
+        } else {
+          attrName = this.$attr[key];
+          if (!attrName) {
+            this.$attr[key] = attrName = snake_case(key, '-');
+          }
+        }
+
+        nodeName = nodeName_(this.$$element);
+
+        if ((nodeName === 'a' && (key === 'href' || key === 'xlinkHref')) ||
+            (nodeName === 'img' && key === 'src')) {
+          // sanitize a[href] and img[src] values
+          this[key] = value = $$sanitizeUri(value, key === 'src');
+        } else if (nodeName === 'img' && key === 'srcset' && isDefined(value)) {
+          // sanitize img[srcset] values
+          var result = '';
+
+          // first check if there are spaces because it's not the same pattern
+          var trimmedSrcset = trim(value);
+          //                (   999x   ,|   999w   ,|   ,|,   )
+          var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
+          var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;
+
+          // split srcset into tuple of uri and descriptor except for the last item
+          var rawUris = trimmedSrcset.split(pattern);
+
+          // for each tuples
+          var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
+          for (var i = 0; i < nbrUrisWith2parts; i++) {
+            var innerIdx = i * 2;
+            // sanitize the uri
+            result += $$sanitizeUri(trim(rawUris[innerIdx]), true);
+            // add the descriptor
+            result += (' ' + trim(rawUris[innerIdx + 1]));
+          }
+
+          // split the last item into uri and descriptor
+          var lastTuple = trim(rawUris[i * 2]).split(/\s/);
+
+          // sanitize the last uri
+          result += $$sanitizeUri(trim(lastTuple[0]), true);
+
+          // and add the last descriptor if any
+          if (lastTuple.length === 2) {
+            result += (' ' + trim(lastTuple[1]));
+          }
+          this[key] = value = result;
+        }
+
+        if (writeAttr !== false) {
+          if (value === null || isUndefined(value)) {
+            this.$$element.removeAttr(attrName);
+          } else {
+            if (SIMPLE_ATTR_NAME.test(attrName)) {
+              this.$$element.attr(attrName, value);
+            } else {
+              setSpecialAttr(this.$$element[0], attrName, value);
+            }
+          }
+        }
+
+        // fire observers
+        var $$observers = this.$$observers;
+        if ($$observers) {
+          forEach($$observers[observer], function(fn) {
+            try {
+              fn(value);
+            } catch (e) {
+              $exceptionHandler(e);
+            }
+          });
+        }
+      },
+
+
+      /**
+       * @ngdoc method
+       * @name $compile.directive.Attributes#$observe
+       * @kind function
+       *
+       * @description
+       * Observes an interpolated attribute.
+       *
+       * The observer function will be invoked once during the next `$digest` following
+       * compilation. The observer is then invoked whenever the interpolated value
+       * changes.
+       *
+       * @param {string} key Normalized key. (ie ngAttribute) .
+       * @param {function(interpolatedValue)} fn Function that will be called whenever
+                the interpolated value of the attribute changes.
+       *        See the {@link guide/interpolation#how-text-and-attribute-bindings-work Interpolation
+       *        guide} for more info.
+       * @returns {function()} Returns a deregistration function for this observer.
+       */
+      $observe: function(key, fn) {
+        var attrs = this,
+            $$observers = (attrs.$$observers || (attrs.$$observers = createMap())),
+            listeners = ($$observers[key] || ($$observers[key] = []));
+
+        listeners.push(fn);
+        $rootScope.$evalAsync(function() {
+          if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) {
+            // no one registered attribute interpolation function, so lets call it manually
+            fn(attrs[key]);
+          }
+        });
+
+        return function() {
+          arrayRemove(listeners, fn);
+        };
+      }
+    };
+
+    function setSpecialAttr(element, attrName, value) {
+      // Attributes names that do not start with letters (such as `(click)`) cannot be set using `setAttribute`
+      // so we have to jump through some hoops to get such an attribute
+      // https://github.com/angular/angular.js/pull/13318
+      specialAttrHolder.innerHTML = '<span ' + attrName + '>';
+      var attributes = specialAttrHolder.firstChild.attributes;
+      var attribute = attributes[0];
+      // We have to remove the attribute from its container element before we can add it to the destination element
+      attributes.removeNamedItem(attribute.name);
+      attribute.value = value;
+      element.attributes.setNamedItem(attribute);
+    }
+
+    function safeAddClass($element, className) {
+      try {
+        $element.addClass(className);
+      } catch (e) {
+        // ignore, since it means that we are trying to set class on
+        // SVG element, where class name is read-only.
+      }
+    }
+
+
+    var startSymbol = $interpolate.startSymbol(),
+        endSymbol = $interpolate.endSymbol(),
+        denormalizeTemplate = (startSymbol === '{{' && endSymbol  === '}}')
+            ? identity
+            : function denormalizeTemplate(template) {
+              return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
+        },
+        NG_ATTR_BINDING = /^ngAttr[A-Z]/;
+    var MULTI_ELEMENT_DIR_RE = /^(.+)Start$/;
+
+    compile.$$addBindingInfo = debugInfoEnabled ? function $$addBindingInfo($element, binding) {
+      var bindings = $element.data('$binding') || [];
+
+      if (isArray(binding)) {
+        bindings = bindings.concat(binding);
+      } else {
+        bindings.push(binding);
+      }
+
+      $element.data('$binding', bindings);
+    } : noop;
+
+    compile.$$addBindingClass = debugInfoEnabled ? function $$addBindingClass($element) {
+      safeAddClass($element, 'ng-binding');
+    } : noop;
+
+    compile.$$addScopeInfo = debugInfoEnabled ? function $$addScopeInfo($element, scope, isolated, noTemplate) {
+      var dataName = isolated ? (noTemplate ? '$isolateScopeNoTemplate' : '$isolateScope') : '$scope';
+      $element.data(dataName, scope);
+    } : noop;
+
+    compile.$$addScopeClass = debugInfoEnabled ? function $$addScopeClass($element, isolated) {
+      safeAddClass($element, isolated ? 'ng-isolate-scope' : 'ng-scope');
+    } : noop;
+
+    compile.$$createComment = function(directiveName, comment) {
+      var content = '';
+      if (debugInfoEnabled) {
+        content = ' ' + (directiveName || '') + ': ';
+        if (comment) content += comment + ' ';
+      }
+      return window.document.createComment(content);
+    };
+
+    return compile;
+
+    //================================
+
+    function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective,
+                        previousCompileContext) {
+      if (!($compileNodes instanceof jqLite)) {
+        // jquery always rewraps, whereas we need to preserve the original selector so that we can
+        // modify it.
+        $compileNodes = jqLite($compileNodes);
+      }
+      var compositeLinkFn =
+              compileNodes($compileNodes, transcludeFn, $compileNodes,
+                           maxPriority, ignoreDirective, previousCompileContext);
+      compile.$$addScopeClass($compileNodes);
+      var namespace = null;
+      return function publicLinkFn(scope, cloneConnectFn, options) {
+        if (!$compileNodes) {
+          throw $compileMinErr('multilink', 'This element has already been linked.');
+        }
+        assertArg(scope, 'scope');
+
+        if (previousCompileContext && previousCompileContext.needsNewScope) {
+          // A parent directive did a replace and a directive on this element asked
+          // for transclusion, which caused us to lose a layer of element on which
+          // we could hold the new transclusion scope, so we will create it manually
+          // here.
+          scope = scope.$parent.$new();
+        }
+
+        options = options || {};
+        var parentBoundTranscludeFn = options.parentBoundTranscludeFn,
+          transcludeControllers = options.transcludeControllers,
+          futureParentElement = options.futureParentElement;
+
+        // When `parentBoundTranscludeFn` is passed, it is a
+        // `controllersBoundTransclude` function (it was previously passed
+        // as `transclude` to directive.link) so we must unwrap it to get
+        // its `boundTranscludeFn`
+        if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) {
+          parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude;
+        }
+
+        if (!namespace) {
+          namespace = detectNamespaceForChildElements(futureParentElement);
+        }
+        var $linkNode;
+        if (namespace !== 'html') {
+          // When using a directive with replace:true and templateUrl the $compileNodes
+          // (or a child element inside of them)
+          // might change, so we need to recreate the namespace adapted compileNodes
+          // for call to the link function.
+          // Note: This will already clone the nodes...
+          $linkNode = jqLite(
+            wrapTemplate(namespace, jqLite('<div>').append($compileNodes).html())
+          );
+        } else if (cloneConnectFn) {
+          // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
+          // and sometimes changes the structure of the DOM.
+          $linkNode = JQLitePrototype.clone.call($compileNodes);
+        } else {
+          $linkNode = $compileNodes;
+        }
+
+        if (transcludeControllers) {
+          for (var controllerName in transcludeControllers) {
+            $linkNode.data('$' + controllerName + 'Controller', transcludeControllers[controllerName].instance);
+          }
+        }
+
+        compile.$$addScopeInfo($linkNode, scope);
+
+        if (cloneConnectFn) cloneConnectFn($linkNode, scope);
+        if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);
+
+        if (!cloneConnectFn) {
+          $compileNodes = compositeLinkFn = null;
+        }
+        return $linkNode;
+      };
+    }
+
+    function detectNamespaceForChildElements(parentElement) {
+      // TODO: Make this detect MathML as well...
+      var node = parentElement && parentElement[0];
+      if (!node) {
+        return 'html';
+      } else {
+        return nodeName_(node) !== 'foreignobject' && toString.call(node).match(/SVG/) ? 'svg' : 'html';
+      }
+    }
+
+    /**
+     * Compile function matches each node in nodeList against the directives. Once all directives
+     * for a particular node are collected their compile functions are executed. The compile
+     * functions return values - the linking functions - are combined into a composite linking
+     * function, which is the a linking function for the node.
+     *
+     * @param {NodeList} nodeList an array of nodes or NodeList to compile
+     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the
+     *        scope argument is auto-generated to the new child of the transcluded parent scope.
+     * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then
+     *        the rootElement must be set the jqLite collection of the compile root. This is
+     *        needed so that the jqLite collection items can be replaced with widgets.
+     * @param {number=} maxPriority Max directive priority.
+     * @returns {Function} A composite linking function of all of the matched directives or null.
+     */
+    function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,
+                            previousCompileContext) {
+      var linkFns = [],
+          // `nodeList` can be either an element's `.childNodes` (live NodeList)
+          // or a jqLite/jQuery collection or an array
+          notLiveList = isArray(nodeList) || (nodeList instanceof jqLite),
+          attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound;
+
+
+      for (var i = 0; i < nodeList.length; i++) {
+        attrs = new Attributes();
+
+        // Support: IE 11 only
+        // Workaround for #11781 and #14924
+        if (msie === 11) {
+          mergeConsecutiveTextNodes(nodeList, i, notLiveList);
+        }
+
+        // We must always refer to `nodeList[i]` hereafter,
+        // since the nodes can be replaced underneath us.
+        directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined,
+                                        ignoreDirective);
+
+        nodeLinkFn = (directives.length)
+            ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement,
+                                      null, [], [], previousCompileContext)
+            : null;
+
+        if (nodeLinkFn && nodeLinkFn.scope) {
+          compile.$$addScopeClass(attrs.$$element);
+        }
+
+        childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||
+                      !(childNodes = nodeList[i].childNodes) ||
+                      !childNodes.length)
+            ? null
+            : compileNodes(childNodes,
+                 nodeLinkFn ? (
+                  (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement)
+                     && nodeLinkFn.transclude) : transcludeFn);
+
+        if (nodeLinkFn || childLinkFn) {
+          linkFns.push(i, nodeLinkFn, childLinkFn);
+          linkFnFound = true;
+          nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;
+        }
+
+        //use the previous context only for the first element in the virtual group
+        previousCompileContext = null;
+      }
+
+      // return a linking function if we have found anything, null otherwise
+      return linkFnFound ? compositeLinkFn : null;
+
+      function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {
+        var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn;
+        var stableNodeList;
+
+
+        if (nodeLinkFnFound) {
+          // copy nodeList so that if a nodeLinkFn removes or adds an element at this DOM level our
+          // offsets don't get screwed up
+          var nodeListLength = nodeList.length;
+          stableNodeList = new Array(nodeListLength);
+
+          // create a sparse array by only copying the elements which have a linkFn
+          for (i = 0; i < linkFns.length; i += 3) {
+            idx = linkFns[i];
+            stableNodeList[idx] = nodeList[idx];
+          }
+        } else {
+          stableNodeList = nodeList;
+        }
+
+        for (i = 0, ii = linkFns.length; i < ii;) {
+          node = stableNodeList[linkFns[i++]];
+          nodeLinkFn = linkFns[i++];
+          childLinkFn = linkFns[i++];
+
+          if (nodeLinkFn) {
+            if (nodeLinkFn.scope) {
+              childScope = scope.$new();
+              compile.$$addScopeInfo(jqLite(node), childScope);
+            } else {
+              childScope = scope;
+            }
+
+            if (nodeLinkFn.transcludeOnThisElement) {
+              childBoundTranscludeFn = createBoundTranscludeFn(
+                  scope, nodeLinkFn.transclude, parentBoundTranscludeFn);
+
+            } else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {
+              childBoundTranscludeFn = parentBoundTranscludeFn;
+
+            } else if (!parentBoundTranscludeFn && transcludeFn) {
+              childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn);
+
+            } else {
+              childBoundTranscludeFn = null;
+            }
+
+            nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);
+
+          } else if (childLinkFn) {
+            childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn);
+          }
+        }
+      }
+    }
+
+    function mergeConsecutiveTextNodes(nodeList, idx, notLiveList) {
+      var node = nodeList[idx];
+      var parent = node.parentNode;
+      var sibling;
+
+      if (node.nodeType !== NODE_TYPE_TEXT) {
+        return;
+      }
+
+      while (true) {
+        sibling = parent ? node.nextSibling : nodeList[idx + 1];
+        if (!sibling || sibling.nodeType !== NODE_TYPE_TEXT) {
+          break;
+        }
+
+        node.nodeValue = node.nodeValue + sibling.nodeValue;
+
+        if (sibling.parentNode) {
+          sibling.parentNode.removeChild(sibling);
+        }
+        if (notLiveList && sibling === nodeList[idx + 1]) {
+          nodeList.splice(idx + 1, 1);
+        }
+      }
+    }
+
+    function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
+      function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {
+
+        if (!transcludedScope) {
+          transcludedScope = scope.$new(false, containingScope);
+          transcludedScope.$$transcluded = true;
+        }
+
+        return transcludeFn(transcludedScope, cloneFn, {
+          parentBoundTranscludeFn: previousBoundTranscludeFn,
+          transcludeControllers: controllers,
+          futureParentElement: futureParentElement
+        });
+      }
+
+      // We need  to attach the transclusion slots onto the `boundTranscludeFn`
+      // so that they are available inside the `controllersBoundTransclude` function
+      var boundSlots = boundTranscludeFn.$$slots = createMap();
+      for (var slotName in transcludeFn.$$slots) {
+        if (transcludeFn.$$slots[slotName]) {
+          boundSlots[slotName] = createBoundTranscludeFn(scope, transcludeFn.$$slots[slotName], previousBoundTranscludeFn);
+        } else {
+          boundSlots[slotName] = null;
+        }
+      }
+
+      return boundTranscludeFn;
+    }
+
+    /**
+     * Looks for directives on the given node and adds them to the directive collection which is
+     * sorted.
+     *
+     * @param node Node to search.
+     * @param directives An array to which the directives are added to. This array is sorted before
+     *        the function returns.
+     * @param attrs The shared attrs object which is used to populate the normalized attributes.
+     * @param {number=} maxPriority Max directive priority.
+     */
+    function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
+      var nodeType = node.nodeType,
+          attrsMap = attrs.$attr,
+          match,
+          nodeName,
+          className;
+
+      switch (nodeType) {
+        case NODE_TYPE_ELEMENT: /* Element */
+
+          nodeName = nodeName_(node);
+
+          // use the node name: <directive>
+          addDirective(directives,
+              directiveNormalize(nodeName), 'E', maxPriority, ignoreDirective);
+
+          // iterate over the attributes
+          for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,
+                   j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
+            var attrStartName = false;
+            var attrEndName = false;
+
+            attr = nAttrs[j];
+            name = attr.name;
+            value = attr.value;
+
+            // support ngAttr attribute binding
+            ngAttrName = directiveNormalize(name);
+            isNgAttr = NG_ATTR_BINDING.test(ngAttrName);
+            if (isNgAttr) {
+              name = name.replace(PREFIX_REGEXP, '')
+                .substr(8).replace(/_(.)/g, function(match, letter) {
+                  return letter.toUpperCase();
+                });
+            }
+
+            var multiElementMatch = ngAttrName.match(MULTI_ELEMENT_DIR_RE);
+            if (multiElementMatch && directiveIsMultiElement(multiElementMatch[1])) {
+              attrStartName = name;
+              attrEndName = name.substr(0, name.length - 5) + 'end';
+              name = name.substr(0, name.length - 6);
+            }
+
+            nName = directiveNormalize(name.toLowerCase());
+            attrsMap[nName] = name;
+            if (isNgAttr || !attrs.hasOwnProperty(nName)) {
+                attrs[nName] = value;
+                if (getBooleanAttrName(node, nName)) {
+                  attrs[nName] = true; // presence means true
+                }
+            }
+            addAttrInterpolateDirective(node, directives, value, nName, isNgAttr);
+            addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName,
+                          attrEndName);
+          }
+
+          if (nodeName === 'input' && node.getAttribute('type') === 'hidden') {
+            // Hidden input elements can have strange behaviour when navigating back to the page
+            // This tells the browser not to try to cache and reinstate previous values
+            node.setAttribute('autocomplete', 'off');
+          }
+
+          // use class as directive
+          if (!cssClassDirectivesEnabled) break;
+          className = node.className;
+          if (isObject(className)) {
+              // Maybe SVGAnimatedString
+              className = className.animVal;
+          }
+          if (isString(className) && className !== '') {
+            while ((match = CLASS_DIRECTIVE_REGEXP.exec(className))) {
+              nName = directiveNormalize(match[2]);
+              if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) {
+                attrs[nName] = trim(match[3]);
+              }
+              className = className.substr(match.index + match[0].length);
+            }
+          }
+          break;
+        case NODE_TYPE_TEXT: /* Text Node */
+          addTextInterpolateDirective(directives, node.nodeValue);
+          break;
+        case NODE_TYPE_COMMENT: /* Comment */
+          if (!commentDirectivesEnabled) break;
+          collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective);
+          break;
+      }
+
+      directives.sort(byPriority);
+      return directives;
+    }
+
+    function collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
+      // function created because of performance, try/catch disables
+      // the optimization of the whole function #14848
+      try {
+        var match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue);
+        if (match) {
+          var nName = directiveNormalize(match[1]);
+          if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) {
+            attrs[nName] = trim(match[2]);
+          }
+        }
+      } catch (e) {
+        // turns out that under some circumstances IE9 throws errors when one attempts to read
+        // comment's node value.
+        // Just ignore it and continue. (Can't seem to reproduce in test case.)
+      }
+    }
+
+    /**
+     * Given a node with a directive-start it collects all of the siblings until it finds
+     * directive-end.
+     * @param node
+     * @param attrStart
+     * @param attrEnd
+     * @returns {*}
+     */
+    function groupScan(node, attrStart, attrEnd) {
+      var nodes = [];
+      var depth = 0;
+      if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {
+        do {
+          if (!node) {
+            throw $compileMinErr('uterdir',
+                      'Unterminated attribute, found \'{0}\' but no matching \'{1}\' found.',
+                      attrStart, attrEnd);
+          }
+          if (node.nodeType === NODE_TYPE_ELEMENT) {
+            if (node.hasAttribute(attrStart)) depth++;
+            if (node.hasAttribute(attrEnd)) depth--;
+          }
+          nodes.push(node);
+          node = node.nextSibling;
+        } while (depth > 0);
+      } else {
+        nodes.push(node);
+      }
+
+      return jqLite(nodes);
+    }
+
+    /**
+     * Wrapper for linking function which converts normal linking function into a grouped
+     * linking function.
+     * @param linkFn
+     * @param attrStart
+     * @param attrEnd
+     * @returns {Function}
+     */
+    function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
+      return function groupedElementsLink(scope, element, attrs, controllers, transcludeFn) {
+        element = groupScan(element[0], attrStart, attrEnd);
+        return linkFn(scope, element, attrs, controllers, transcludeFn);
+      };
+    }
+
+    /**
+     * A function generator that is used to support both eager and lazy compilation
+     * linking function.
+     * @param eager
+     * @param $compileNodes
+     * @param transcludeFn
+     * @param maxPriority
+     * @param ignoreDirective
+     * @param previousCompileContext
+     * @returns {Function}
+     */
+    function compilationGenerator(eager, $compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) {
+      var compiled;
+
+      if (eager) {
+        return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
+      }
+      return /** @this */ function lazyCompilation() {
+        if (!compiled) {
+          compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
+
+          // Null out all of these references in order to make them eligible for garbage collection
+          // since this is a potentially long lived closure
+          $compileNodes = transcludeFn = previousCompileContext = null;
+        }
+        return compiled.apply(this, arguments);
+      };
+    }
+
+    /**
+     * Once the directives have been collected, their compile functions are executed. This method
+     * is responsible for inlining directive templates as well as terminating the application
+     * of the directives if the terminal directive has been reached.
+     *
+     * @param {Array} directives Array of collected directives to execute their compile function.
+     *        this needs to be pre-sorted by priority order.
+     * @param {Node} compileNode The raw DOM node to apply the compile functions to
+     * @param {Object} templateAttrs The shared attribute function
+     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the
+     *                                                  scope argument is auto-generated to the new
+     *                                                  child of the transcluded parent scope.
+     * @param {JQLite} jqCollection If we are working on the root of the compile tree then this
+     *                              argument has the root jqLite array so that we can replace nodes
+     *                              on it.
+     * @param {Object=} originalReplaceDirective An optional directive that will be ignored when
+     *                                           compiling the transclusion.
+     * @param {Array.<Function>} preLinkFns
+     * @param {Array.<Function>} postLinkFns
+     * @param {Object} previousCompileContext Context used for previous compilation of the current
+     *                                        node
+     * @returns {Function} linkFn
+     */
+    function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn,
+                                   jqCollection, originalReplaceDirective, preLinkFns, postLinkFns,
+                                   previousCompileContext) {
+      previousCompileContext = previousCompileContext || {};
+
+      var terminalPriority = -Number.MAX_VALUE,
+          newScopeDirective = previousCompileContext.newScopeDirective,
+          controllerDirectives = previousCompileContext.controllerDirectives,
+          newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
+          templateDirective = previousCompileContext.templateDirective,
+          nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
+          hasTranscludeDirective = false,
+          hasTemplate = false,
+          hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,
+          $compileNode = templateAttrs.$$element = jqLite(compileNode),
+          directive,
+          directiveName,
+          $template,
+          replaceDirective = originalReplaceDirective,
+          childTranscludeFn = transcludeFn,
+          linkFn,
+          didScanForMultipleTransclusion = false,
+          mightHaveMultipleTransclusionError = false,
+          directiveValue;
+
+      // executes all directives on the current element
+      for (var i = 0, ii = directives.length; i < ii; i++) {
+        directive = directives[i];
+        var attrStart = directive.$$start;
+        var attrEnd = directive.$$end;
+
+        // collect multiblock sections
+        if (attrStart) {
+          $compileNode = groupScan(compileNode, attrStart, attrEnd);
+        }
+        $template = undefined;
+
+        if (terminalPriority > directive.priority) {
+          break; // prevent further processing of directives
+        }
+
+        directiveValue = directive.scope;
+
+        if (directiveValue) {
+
+          // skip the check for directives with async templates, we'll check the derived sync
+          // directive when the template arrives
+          if (!directive.templateUrl) {
+            if (isObject(directiveValue)) {
+              // This directive is trying to add an isolated scope.
+              // Check that there is no scope of any kind already
+              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective || newScopeDirective,
+                                directive, $compileNode);
+              newIsolateScopeDirective = directive;
+            } else {
+              // This directive is trying to add a child scope.
+              // Check that there is no isolated scope already
+              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive,
+                                $compileNode);
+            }
+          }
+
+          newScopeDirective = newScopeDirective || directive;
+        }
+
+        directiveName = directive.name;
+
+        // If we encounter a condition that can result in transclusion on the directive,
+        // then scan ahead in the remaining directives for others that may cause a multiple
+        // transclusion error to be thrown during the compilation process.  If a matching directive
+        // is found, then we know that when we encounter a transcluded directive, we need to eagerly
+        // compile the `transclude` function rather than doing it lazily in order to throw
+        // exceptions at the correct time
+        if (!didScanForMultipleTransclusion && ((directive.replace && (directive.templateUrl || directive.template))
+            || (directive.transclude && !directive.$$tlb))) {
+                var candidateDirective;
+
+                for (var scanningIndex = i + 1; (candidateDirective = directives[scanningIndex++]);) {
+                    if ((candidateDirective.transclude && !candidateDirective.$$tlb)
+                        || (candidateDirective.replace && (candidateDirective.templateUrl || candidateDirective.template))) {
+                        mightHaveMultipleTransclusionError = true;
+                        break;
+                    }
+                }
+
+                didScanForMultipleTransclusion = true;
+        }
+
+        if (!directive.templateUrl && directive.controller) {
+          controllerDirectives = controllerDirectives || createMap();
+          assertNoDuplicate('\'' + directiveName + '\' controller',
+              controllerDirectives[directiveName], directive, $compileNode);
+          controllerDirectives[directiveName] = directive;
+        }
+
+        directiveValue = directive.transclude;
+
+        if (directiveValue) {
+          hasTranscludeDirective = true;
+
+          // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
+          // This option should only be used by directives that know how to safely handle element transclusion,
+          // where the transcluded nodes are added or replaced after linking.
+          if (!directive.$$tlb) {
+            assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
+            nonTlbTranscludeDirective = directive;
+          }
+
+          if (directiveValue === 'element') {
+            hasElementTranscludeDirective = true;
+            terminalPriority = directive.priority;
+            $template = $compileNode;
+            $compileNode = templateAttrs.$$element =
+                jqLite(compile.$$createComment(directiveName, templateAttrs[directiveName]));
+            compileNode = $compileNode[0];
+            replaceWith(jqCollection, sliceArgs($template), compileNode);
+
+            // Support: Chrome < 50
+            // https://github.com/angular/angular.js/issues/14041
+
+            // In the versions of V8 prior to Chrome 50, the document fragment that is created
+            // in the `replaceWith` function is improperly garbage collected despite still
+            // being referenced by the `parentNode` property of all of the child nodes.  By adding
+            // a reference to the fragment via a different property, we can avoid that incorrect
+            // behavior.
+            // TODO: remove this line after Chrome 50 has been released
+            $template[0].$$parentNode = $template[0].parentNode;
+
+            childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority,
+                                        replaceDirective && replaceDirective.name, {
+                                          // Don't pass in:
+                                          // - controllerDirectives - otherwise we'll create duplicates controllers
+                                          // - newIsolateScopeDirective or templateDirective - combining templates with
+                                          //   element transclusion doesn't make sense.
+                                          //
+                                          // We need only nonTlbTranscludeDirective so that we prevent putting transclusion
+                                          // on the same element more than once.
+                                          nonTlbTranscludeDirective: nonTlbTranscludeDirective
+                                        });
+          } else {
+
+            var slots = createMap();
+
+            if (!isObject(directiveValue)) {
+              $template = jqLite(jqLiteClone(compileNode)).contents();
+            } else {
+
+              // We have transclusion slots,
+              // collect them up, compile them and store their transclusion functions
+              $template = [];
+
+              var slotMap = createMap();
+              var filledSlots = createMap();
+
+              // Parse the element selectors
+              forEach(directiveValue, function(elementSelector, slotName) {
+                // If an element selector starts with a ? then it is optional
+                var optional = (elementSelector.charAt(0) === '?');
+                elementSelector = optional ? elementSelector.substring(1) : elementSelector;
+
+                slotMap[elementSelector] = slotName;
+
+                // We explicitly assign `null` since this implies that a slot was defined but not filled.
+                // Later when calling boundTransclusion functions with a slot name we only error if the
+                // slot is `undefined`
+                slots[slotName] = null;
+
+                // filledSlots contains `true` for all slots that are either optional or have been
+                // filled. This is used to check that we have not missed any required slots
+                filledSlots[slotName] = optional;
+              });
+
+              // Add the matching elements into their slot
+              forEach($compileNode.contents(), function(node) {
+                var slotName = slotMap[directiveNormalize(nodeName_(node))];
+                if (slotName) {
+                  filledSlots[slotName] = true;
+                  slots[slotName] = slots[slotName] || [];
+                  slots[slotName].push(node);
+                } else {
+                  $template.push(node);
+                }
+              });
+
+              // Check for required slots that were not filled
+              forEach(filledSlots, function(filled, slotName) {
+                if (!filled) {
+                  throw $compileMinErr('reqslot', 'Required transclusion slot `{0}` was not filled.', slotName);
+                }
+              });
+
+              for (var slotName in slots) {
+                if (slots[slotName]) {
+                  // Only define a transclusion function if the slot was filled
+                  slots[slotName] = compilationGenerator(mightHaveMultipleTransclusionError, slots[slotName], transcludeFn);
+                }
+              }
+            }
+
+            $compileNode.empty(); // clear contents
+            childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, undefined,
+                undefined, { needsNewScope: directive.$$isolateScope || directive.$$newScope});
+            childTranscludeFn.$$slots = slots;
+          }
+        }
+
+        if (directive.template) {
+          hasTemplate = true;
+          assertNoDuplicate('template', templateDirective, directive, $compileNode);
+          templateDirective = directive;
+
+          directiveValue = (isFunction(directive.template))
+              ? directive.template($compileNode, templateAttrs)
+              : directive.template;
+
+          directiveValue = denormalizeTemplate(directiveValue);
+
+          if (directive.replace) {
+            replaceDirective = directive;
+            if (jqLiteIsTextNode(directiveValue)) {
+              $template = [];
+            } else {
+              $template = removeComments(wrapTemplate(directive.templateNamespace, trim(directiveValue)));
+            }
+            compileNode = $template[0];
+
+            if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {
+              throw $compileMinErr('tplrt',
+                  'Template for directive \'{0}\' must have exactly one root element. {1}',
+                  directiveName, '');
+            }
+
+            replaceWith(jqCollection, $compileNode, compileNode);
+
+            var newTemplateAttrs = {$attr: {}};
+
+            // combine directives from the original node and from the template:
+            // - take the array of directives for this element
+            // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed)
+            // - collect directives from the template and sort them by priority
+            // - combine directives as: processed + template + unprocessed
+            var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs);
+            var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1));
+
+            if (newIsolateScopeDirective || newScopeDirective) {
+              // The original directive caused the current element to be replaced but this element
+              // also needs to have a new scope, so we need to tell the template directives
+              // that they would need to get their scope from further up, if they require transclusion
+              markDirectiveScope(templateDirectives, newIsolateScopeDirective, newScopeDirective);
+            }
+            directives = directives.concat(templateDirectives).concat(unprocessedDirectives);
+            mergeTemplateAttributes(templateAttrs, newTemplateAttrs);
+
+            ii = directives.length;
+          } else {
+            $compileNode.html(directiveValue);
+          }
+        }
+
+        if (directive.templateUrl) {
+          hasTemplate = true;
+          assertNoDuplicate('template', templateDirective, directive, $compileNode);
+          templateDirective = directive;
+
+          if (directive.replace) {
+            replaceDirective = directive;
+          }
+
+          // eslint-disable-next-line no-func-assign
+          nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
+              templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, {
+                controllerDirectives: controllerDirectives,
+                newScopeDirective: (newScopeDirective !== directive) && newScopeDirective,
+                newIsolateScopeDirective: newIsolateScopeDirective,
+                templateDirective: templateDirective,
+                nonTlbTranscludeDirective: nonTlbTranscludeDirective
+              });
+          ii = directives.length;
+        } else if (directive.compile) {
+          try {
+            linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn);
+            var context = directive.$$originalDirective || directive;
+            if (isFunction(linkFn)) {
+              addLinkFns(null, bind(context, linkFn), attrStart, attrEnd);
+            } else if (linkFn) {
+              addLinkFns(bind(context, linkFn.pre), bind(context, linkFn.post), attrStart, attrEnd);
+            }
+          } catch (e) {
+            $exceptionHandler(e, startingTag($compileNode));
+          }
+        }
+
+        if (directive.terminal) {
+          nodeLinkFn.terminal = true;
+          terminalPriority = Math.max(terminalPriority, directive.priority);
+        }
+
+      }
+
+      nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
+      nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;
+      nodeLinkFn.templateOnThisElement = hasTemplate;
+      nodeLinkFn.transclude = childTranscludeFn;
+
+      previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;
+
+      // might be normal or delayed nodeLinkFn depending on if templateUrl is present
+      return nodeLinkFn;
+
+      ////////////////////
+
+      function addLinkFns(pre, post, attrStart, attrEnd) {
+        if (pre) {
+          if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
+          pre.require = directive.require;
+          pre.directiveName = directiveName;
+          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
+            pre = cloneAndAnnotateFn(pre, {isolateScope: true});
+          }
+          preLinkFns.push(pre);
+        }
+        if (post) {
+          if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
+          post.require = directive.require;
+          post.directiveName = directiveName;
+          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
+            post = cloneAndAnnotateFn(post, {isolateScope: true});
+          }
+          postLinkFns.push(post);
+        }
+      }
+
+      function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
+        var i, ii, linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,
+            attrs, scopeBindingInfo;
+
+        if (compileNode === linkNode) {
+          attrs = templateAttrs;
+          $element = templateAttrs.$$element;
+        } else {
+          $element = jqLite(linkNode);
+          attrs = new Attributes($element, templateAttrs);
+        }
+
+        controllerScope = scope;
+        if (newIsolateScopeDirective) {
+          isolateScope = scope.$new(true);
+        } else if (newScopeDirective) {
+          controllerScope = scope.$parent;
+        }
+
+        if (boundTranscludeFn) {
+          // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`
+          // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`
+          transcludeFn = controllersBoundTransclude;
+          transcludeFn.$$boundTransclude = boundTranscludeFn;
+          // expose the slots on the `$transclude` function
+          transcludeFn.isSlotFilled = function(slotName) {
+            return !!boundTranscludeFn.$$slots[slotName];
+          };
+        }
+
+        if (controllerDirectives) {
+          elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective);
+        }
+
+        if (newIsolateScopeDirective) {
+          // Initialize isolate scope bindings for new isolate scope directive.
+          compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective ||
+              templateDirective === newIsolateScopeDirective.$$originalDirective)));
+          compile.$$addScopeClass($element, true);
+          isolateScope.$$isolateBindings =
+              newIsolateScopeDirective.$$isolateBindings;
+          scopeBindingInfo = initializeDirectiveBindings(scope, attrs, isolateScope,
+                                        isolateScope.$$isolateBindings,
+                                        newIsolateScopeDirective);
+          if (scopeBindingInfo.removeWatches) {
+            isolateScope.$on('$destroy', scopeBindingInfo.removeWatches);
+          }
+        }
+
+        // Initialize bindToController bindings
+        for (var name in elementControllers) {
+          var controllerDirective = controllerDirectives[name];
+          var controller = elementControllers[name];
+          var bindings = controllerDirective.$$bindings.bindToController;
+
+          if (preAssignBindingsEnabled) {
+            if (bindings) {
+              controller.bindingInfo =
+                initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
+            } else {
+              controller.bindingInfo = {};
+            }
+
+            var controllerResult = controller();
+            if (controllerResult !== controller.instance) {
+              // If the controller constructor has a return value, overwrite the instance
+              // from setupControllers
+              controller.instance = controllerResult;
+              $element.data('$' + controllerDirective.name + 'Controller', controllerResult);
+              if (controller.bindingInfo.removeWatches) {
+                controller.bindingInfo.removeWatches();
+              }
+              controller.bindingInfo =
+                initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
+            }
+          } else {
+            controller.instance = controller();
+            $element.data('$' + controllerDirective.name + 'Controller', controller.instance);
+            controller.bindingInfo =
+              initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
+          }
+        }
+
+        // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
+        forEach(controllerDirectives, function(controllerDirective, name) {
+          var require = controllerDirective.require;
+          if (controllerDirective.bindToController && !isArray(require) && isObject(require)) {
+            extend(elementControllers[name].instance, getControllers(name, require, $element, elementControllers));
+          }
+        });
+
+        // Handle the init and destroy lifecycle hooks on all controllers that have them
+        forEach(elementControllers, function(controller) {
+          var controllerInstance = controller.instance;
+          if (isFunction(controllerInstance.$onChanges)) {
+            try {
+              controllerInstance.$onChanges(controller.bindingInfo.initialChanges);
+            } catch (e) {
+              $exceptionHandler(e);
+            }
+          }
+          if (isFunction(controllerInstance.$onInit)) {
+            try {
+              controllerInstance.$onInit();
+            } catch (e) {
+              $exceptionHandler(e);
+            }
+          }
+          if (isFunction(controllerInstance.$doCheck)) {
+            controllerScope.$watch(function() { controllerInstance.$doCheck(); });
+            controllerInstance.$doCheck();
+          }
+          if (isFunction(controllerInstance.$onDestroy)) {
+            controllerScope.$on('$destroy', function callOnDestroyHook() {
+              controllerInstance.$onDestroy();
+            });
+          }
+        });
+
+        // PRELINKING
+        for (i = 0, ii = preLinkFns.length; i < ii; i++) {
+          linkFn = preLinkFns[i];
+          invokeLinkFn(linkFn,
+              linkFn.isolateScope ? isolateScope : scope,
+              $element,
+              attrs,
+              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),
+              transcludeFn
+          );
+        }
+
+        // RECURSION
+        // We only pass the isolate scope, if the isolate directive has a template,
+        // otherwise the child elements do not belong to the isolate directive.
+        var scopeToChild = scope;
+        if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) {
+          scopeToChild = isolateScope;
+        }
+        if (childLinkFn) {
+          childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);
+        }
+
+        // POSTLINKING
+        for (i = postLinkFns.length - 1; i >= 0; i--) {
+          linkFn = postLinkFns[i];
+          invokeLinkFn(linkFn,
+              linkFn.isolateScope ? isolateScope : scope,
+              $element,
+              attrs,
+              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),
+              transcludeFn
+          );
+        }
+
+        // Trigger $postLink lifecycle hooks
+        forEach(elementControllers, function(controller) {
+          var controllerInstance = controller.instance;
+          if (isFunction(controllerInstance.$postLink)) {
+            controllerInstance.$postLink();
+          }
+        });
+
+        // This is the function that is injected as `$transclude`.
+        // Note: all arguments are optional!
+        function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) {
+          var transcludeControllers;
+          // No scope passed in:
+          if (!isScope(scope)) {
+            slotName = futureParentElement;
+            futureParentElement = cloneAttachFn;
+            cloneAttachFn = scope;
+            scope = undefined;
+          }
+
+          if (hasElementTranscludeDirective) {
+            transcludeControllers = elementControllers;
+          }
+          if (!futureParentElement) {
+            futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;
+          }
+          if (slotName) {
+            // slotTranscludeFn can be one of three things:
+            //  * a transclude function - a filled slot
+            //  * `null` - an optional slot that was not filled
+            //  * `undefined` - a slot that was not declared (i.e. invalid)
+            var slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
+            if (slotTranscludeFn) {
+              return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
+            } else if (isUndefined(slotTranscludeFn)) {
+              throw $compileMinErr('noslot',
+               'No parent directive that requires a transclusion with slot name "{0}". ' +
+               'Element: {1}',
+               slotName, startingTag($element));
+            }
+          } else {
+            return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
+          }
+        }
+      }
+    }
+
+    function getControllers(directiveName, require, $element, elementControllers) {
+      var value;
+
+      if (isString(require)) {
+        var match = require.match(REQUIRE_PREFIX_REGEXP);
+        var name = require.substring(match[0].length);
+        var inheritType = match[1] || match[3];
+        var optional = match[2] === '?';
+
+        //If only parents then start at the parent element
+        if (inheritType === '^^') {
+          $element = $element.parent();
+        //Otherwise attempt getting the controller from elementControllers in case
+        //the element is transcluded (and has no data) and to avoid .data if possible
+        } else {
+          value = elementControllers && elementControllers[name];
+          value = value && value.instance;
+        }
+
+        if (!value) {
+          var dataName = '$' + name + 'Controller';
+          value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);
+        }
+
+        if (!value && !optional) {
+          throw $compileMinErr('ctreq',
+              'Controller \'{0}\', required by directive \'{1}\', can\'t be found!',
+              name, directiveName);
+        }
+      } else if (isArray(require)) {
+        value = [];
+        for (var i = 0, ii = require.length; i < ii; i++) {
+          value[i] = getControllers(directiveName, require[i], $element, elementControllers);
+        }
+      } else if (isObject(require)) {
+        value = {};
+        forEach(require, function(controller, property) {
+          value[property] = getControllers(directiveName, controller, $element, elementControllers);
+        });
+      }
+
+      return value || null;
+    }
+
+    function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective) {
+      var elementControllers = createMap();
+      for (var controllerKey in controllerDirectives) {
+        var directive = controllerDirectives[controllerKey];
+        var locals = {
+          $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
+          $element: $element,
+          $attrs: attrs,
+          $transclude: transcludeFn
+        };
+
+        var controller = directive.controller;
+        if (controller === '@') {
+          controller = attrs[directive.name];
+        }
+
+        var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
+
+        // For directives with element transclusion the element is a comment.
+        // In this case .data will not attach any data.
+        // Instead, we save the controllers for the element in a local hash and attach to .data
+        // later, once we have the actual element.
+        elementControllers[directive.name] = controllerInstance;
+        $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
+      }
+      return elementControllers;
+    }
+
+    // Depending upon the context in which a directive finds itself it might need to have a new isolated
+    // or child scope created. For instance:
+    // * if the directive has been pulled into a template because another directive with a higher priority
+    // asked for element transclusion
+    // * if the directive itself asks for transclusion but it is at the root of a template and the original
+    // element was replaced. See https://github.com/angular/angular.js/issues/12936
+    function markDirectiveScope(directives, isolateScope, newScope) {
+      for (var j = 0, jj = directives.length; j < jj; j++) {
+        directives[j] = inherit(directives[j], {$$isolateScope: isolateScope, $$newScope: newScope});
+      }
+    }
+
+    /**
+     * looks up the directive and decorates it with exception handling and proper parameters. We
+     * call this the boundDirective.
+     *
+     * @param {string} name name of the directive to look up.
+     * @param {string} location The directive must be found in specific format.
+     *   String containing any of theses characters:
+     *
+     *   * `E`: element name
+     *   * `A': attribute
+     *   * `C`: class
+     *   * `M`: comment
+     * @returns {boolean} true if directive was added.
+     */
+    function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName,
+                          endAttrName) {
+      if (name === ignoreDirective) return null;
+      var match = null;
+      if (hasDirectives.hasOwnProperty(name)) {
+        for (var directive, directives = $injector.get(name + Suffix),
+            i = 0, ii = directives.length; i < ii; i++) {
+          directive = directives[i];
+          if ((isUndefined(maxPriority) || maxPriority > directive.priority) &&
+               directive.restrict.indexOf(location) !== -1) {
+            if (startAttrName) {
+              directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
+            }
+            if (!directive.$$bindings) {
+              var bindings = directive.$$bindings =
+                  parseDirectiveBindings(directive, directive.name);
+              if (isObject(bindings.isolateScope)) {
+                directive.$$isolateBindings = bindings.isolateScope;
+              }
+            }
+            tDirectives.push(directive);
+            match = directive;
+          }
+        }
+      }
+      return match;
+    }
+
+
+    /**
+     * looks up the directive and returns true if it is a multi-element directive,
+     * and therefore requires DOM nodes between -start and -end markers to be grouped
+     * together.
+     *
+     * @param {string} name name of the directive to look up.
+     * @returns true if directive was registered as multi-element.
+     */
+    function directiveIsMultiElement(name) {
+      if (hasDirectives.hasOwnProperty(name)) {
+        for (var directive, directives = $injector.get(name + Suffix),
+            i = 0, ii = directives.length; i < ii; i++) {
+          directive = directives[i];
+          if (directive.multiElement) {
+            return true;
+          }
+        }
+      }
+      return false;
+    }
+
+    /**
+     * When the element is replaced with HTML template then the new attributes
+     * on the template need to be merged with the existing attributes in the DOM.
+     * The desired effect is to have both of the attributes present.
+     *
+     * @param {object} dst destination attributes (original DOM)
+     * @param {object} src source attributes (from the directive template)
+     */
+    function mergeTemplateAttributes(dst, src) {
+      var srcAttr = src.$attr,
+          dstAttr = dst.$attr;
+
+      // reapply the old attributes to the new element
+      forEach(dst, function(value, key) {
+        if (key.charAt(0) !== '$') {
+          if (src[key] && src[key] !== value) {
+            if (value.length) {
+              value += (key === 'style' ? ';' : ' ') + src[key];
+            } else {
+              value = src[key];
+            }
+          }
+          dst.$set(key, value, true, srcAttr[key]);
+        }
+      });
+
+      // copy the new attributes on the old attrs object
+      forEach(src, function(value, key) {
+        // Check if we already set this attribute in the loop above.
+        // `dst` will never contain hasOwnProperty as DOM parser won't let it.
+        // You will get an "InvalidCharacterError: DOM Exception 5" error if you
+        // have an attribute like "has-own-property" or "data-has-own-property", etc.
+        if (!dst.hasOwnProperty(key) && key.charAt(0) !== '$') {
+          dst[key] = value;
+
+          if (key !== 'class' && key !== 'style') {
+            dstAttr[key] = srcAttr[key];
+          }
+        }
+      });
+    }
+
+
+    function compileTemplateUrl(directives, $compileNode, tAttrs,
+        $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {
+      var linkQueue = [],
+          afterTemplateNodeLinkFn,
+          afterTemplateChildLinkFn,
+          beforeTemplateCompileNode = $compileNode[0],
+          origAsyncDirective = directives.shift(),
+          derivedSyncDirective = inherit(origAsyncDirective, {
+            templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective
+          }),
+          templateUrl = (isFunction(origAsyncDirective.templateUrl))
+              ? origAsyncDirective.templateUrl($compileNode, tAttrs)
+              : origAsyncDirective.templateUrl,
+          templateNamespace = origAsyncDirective.templateNamespace;
+
+      $compileNode.empty();
+
+      $templateRequest(templateUrl)
+        .then(function(content) {
+          var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;
+
+          content = denormalizeTemplate(content);
+
+          if (origAsyncDirective.replace) {
+            if (jqLiteIsTextNode(content)) {
+              $template = [];
+            } else {
+              $template = removeComments(wrapTemplate(templateNamespace, trim(content)));
+            }
+            compileNode = $template[0];
+
+            if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {
+              throw $compileMinErr('tplrt',
+                  'Template for directive \'{0}\' must have exactly one root element. {1}',
+                  origAsyncDirective.name, templateUrl);
+            }
+
+            tempTemplateAttrs = {$attr: {}};
+            replaceWith($rootElement, $compileNode, compileNode);
+            var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs);
+
+            if (isObject(origAsyncDirective.scope)) {
+              // the original directive that caused the template to be loaded async required
+              // an isolate scope
+              markDirectiveScope(templateDirectives, true);
+            }
+            directives = templateDirectives.concat(directives);
+            mergeTemplateAttributes(tAttrs, tempTemplateAttrs);
+          } else {
+            compileNode = beforeTemplateCompileNode;
+            $compileNode.html(content);
+          }
+
+          directives.unshift(derivedSyncDirective);
+
+          afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs,
+              childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns,
+              previousCompileContext);
+          forEach($rootElement, function(node, i) {
+            if (node === compileNode) {
+              $rootElement[i] = $compileNode[0];
+            }
+          });
+          afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
+
+          while (linkQueue.length) {
+            var scope = linkQueue.shift(),
+                beforeTemplateLinkNode = linkQueue.shift(),
+                linkRootElement = linkQueue.shift(),
+                boundTranscludeFn = linkQueue.shift(),
+                linkNode = $compileNode[0];
+
+            if (scope.$$destroyed) continue;
+
+            if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
+              var oldClasses = beforeTemplateLinkNode.className;
+
+              if (!(previousCompileContext.hasElementTranscludeDirective &&
+                  origAsyncDirective.replace)) {
+                // it was cloned therefore we have to clone as well.
+                linkNode = jqLiteClone(compileNode);
+              }
+              replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
+
+              // Copy in CSS classes from original node
+              safeAddClass(jqLite(linkNode), oldClasses);
+            }
+            if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
+              childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
+            } else {
+              childBoundTranscludeFn = boundTranscludeFn;
+            }
+            afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,
+              childBoundTranscludeFn);
+          }
+          linkQueue = null;
+        }).catch(function(error) {
+          if (error instanceof Error) {
+            $exceptionHandler(error);
+          }
+        });
+
+      return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {
+        var childBoundTranscludeFn = boundTranscludeFn;
+        if (scope.$$destroyed) return;
+        if (linkQueue) {
+          linkQueue.push(scope,
+                         node,
+                         rootElement,
+                         childBoundTranscludeFn);
+        } else {
+          if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
+            childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
+          }
+          afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn);
+        }
+      };
+    }
+
+
+    /**
+     * Sorting function for bound directives.
+     */
+    function byPriority(a, b) {
+      var diff = b.priority - a.priority;
+      if (diff !== 0) return diff;
+      if (a.name !== b.name) return (a.name < b.name) ? -1 : 1;
+      return a.index - b.index;
+    }
+
+    function assertNoDuplicate(what, previousDirective, directive, element) {
+
+      function wrapModuleNameIfDefined(moduleName) {
+        return moduleName ?
+          (' (module: ' + moduleName + ')') :
+          '';
+      }
+
+      if (previousDirective) {
+        throw $compileMinErr('multidir', 'Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}',
+            previousDirective.name, wrapModuleNameIfDefined(previousDirective.$$moduleName),
+            directive.name, wrapModuleNameIfDefined(directive.$$moduleName), what, startingTag(element));
+      }
+    }
+
+
+    function addTextInterpolateDirective(directives, text) {
+      var interpolateFn = $interpolate(text, true);
+      if (interpolateFn) {
+        directives.push({
+          priority: 0,
+          compile: function textInterpolateCompileFn(templateNode) {
+            var templateNodeParent = templateNode.parent(),
+                hasCompileParent = !!templateNodeParent.length;
+
+            // When transcluding a template that has bindings in the root
+            // we don't have a parent and thus need to add the class during linking fn.
+            if (hasCompileParent) compile.$$addBindingClass(templateNodeParent);
+
+            return function textInterpolateLinkFn(scope, node) {
+              var parent = node.parent();
+              if (!hasCompileParent) compile.$$addBindingClass(parent);
+              compile.$$addBindingInfo(parent, interpolateFn.expressions);
+              scope.$watch(interpolateFn, function interpolateFnWatchAction(value) {
+                node[0].nodeValue = value;
+              });
+            };
+          }
+        });
+      }
+    }
+
+
+    function wrapTemplate(type, template) {
+      type = lowercase(type || 'html');
+      switch (type) {
+      case 'svg':
+      case 'math':
+        var wrapper = window.document.createElement('div');
+        wrapper.innerHTML = '<' + type + '>' + template + '</' + type + '>';
+        return wrapper.childNodes[0].childNodes;
+      default:
+        return template;
+      }
+    }
+
+
+    function getTrustedContext(node, attrNormalizedName) {
+      if (attrNormalizedName === 'srcdoc') {
+        return $sce.HTML;
+      }
+      var tag = nodeName_(node);
+      // All tags with src attributes require a RESOURCE_URL value, except for
+      // img and various html5 media tags.
+      if (attrNormalizedName === 'src' || attrNormalizedName === 'ngSrc') {
+        if (['img', 'video', 'audio', 'source', 'track'].indexOf(tag) === -1) {
+          return $sce.RESOURCE_URL;
+        }
+      // maction[xlink:href] can source SVG.  It's not limited to <maction>.
+      } else if (attrNormalizedName === 'xlinkHref' ||
+          (tag === 'form' && attrNormalizedName === 'action') ||
+          // links can be stylesheets or imports, which can run script in the current origin
+          (tag === 'link' && attrNormalizedName === 'href')
+      ) {
+        return $sce.RESOURCE_URL;
+      }
+    }
+
+
+    function addAttrInterpolateDirective(node, directives, value, name, isNgAttr) {
+      var trustedContext = getTrustedContext(node, name);
+      var mustHaveExpression = !isNgAttr;
+      var allOrNothing = ALL_OR_NOTHING_ATTRS[name] || isNgAttr;
+
+      var interpolateFn = $interpolate(value, mustHaveExpression, trustedContext, allOrNothing);
+
+      // no interpolation found -> ignore
+      if (!interpolateFn) return;
+
+      if (name === 'multiple' && nodeName_(node) === 'select') {
+        throw $compileMinErr('selmulti',
+            'Binding to the \'multiple\' attribute is not supported. Element: {0}',
+            startingTag(node));
+      }
+
+      if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {
+        throw $compileMinErr('nodomevents',
+            'Interpolations for HTML DOM event attributes are disallowed.  Please use the ' +
+                'ng- versions (such as ng-click instead of onclick) instead.');
+      }
+
+      directives.push({
+        priority: 100,
+        compile: function() {
+            return {
+              pre: function attrInterpolatePreLinkFn(scope, element, attr) {
+                var $$observers = (attr.$$observers || (attr.$$observers = createMap()));
+
+                // If the attribute has changed since last $interpolate()ed
+                var newValue = attr[name];
+                if (newValue !== value) {
+                  // we need to interpolate again since the attribute value has been updated
+                  // (e.g. by another directive's compile function)
+                  // ensure unset/empty values make interpolateFn falsy
+                  interpolateFn = newValue && $interpolate(newValue, true, trustedContext, allOrNothing);
+                  value = newValue;
+                }
+
+                // if attribute was updated so that there is no interpolation going on we don't want to
+                // register any observers
+                if (!interpolateFn) return;
+
+                // initialize attr object so that it's ready in case we need the value for isolate
+                // scope initialization, otherwise the value would not be available from isolate
+                // directive's linking fn during linking phase
+                attr[name] = interpolateFn(scope);
+
+                ($$observers[name] || ($$observers[name] = [])).$$inter = true;
+                (attr.$$observers && attr.$$observers[name].$$scope || scope).
+                  $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {
+                    //special case for class attribute addition + removal
+                    //so that class changes can tap into the animation
+                    //hooks provided by the $animate service. Be sure to
+                    //skip animations when the first digest occurs (when
+                    //both the new and the old values are the same) since
+                    //the CSS classes are the non-interpolated values
+                    if (name === 'class' && newValue !== oldValue) {
+                      attr.$updateClass(newValue, oldValue);
+                    } else {
+                      attr.$set(name, newValue);
+                    }
+                  });
+              }
+            };
+          }
+      });
+    }
+
+
+    /**
+     * This is a special jqLite.replaceWith, which can replace items which
+     * have no parents, provided that the containing jqLite collection is provided.
+     *
+     * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes
+     *                               in the root of the tree.
+     * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep
+     *                                  the shell, but replace its DOM node reference.
+     * @param {Node} newNode The new DOM node.
+     */
+    function replaceWith($rootElement, elementsToRemove, newNode) {
+      var firstElementToRemove = elementsToRemove[0],
+          removeCount = elementsToRemove.length,
+          parent = firstElementToRemove.parentNode,
+          i, ii;
+
+      if ($rootElement) {
+        for (i = 0, ii = $rootElement.length; i < ii; i++) {
+          if ($rootElement[i] === firstElementToRemove) {
+            $rootElement[i++] = newNode;
+            for (var j = i, j2 = j + removeCount - 1,
+                     jj = $rootElement.length;
+                 j < jj; j++, j2++) {
+              if (j2 < jj) {
+                $rootElement[j] = $rootElement[j2];
+              } else {
+                delete $rootElement[j];
+              }
+            }
+            $rootElement.length -= removeCount - 1;
+
+            // If the replaced element is also the jQuery .context then replace it
+            // .context is a deprecated jQuery api, so we should set it only when jQuery set it
+            // http://api.jquery.com/context/
+            if ($rootElement.context === firstElementToRemove) {
+              $rootElement.context = newNode;
+            }
+            break;
+          }
+        }
+      }
+
+      if (parent) {
+        parent.replaceChild(newNode, firstElementToRemove);
+      }
+
+      // Append all the `elementsToRemove` to a fragment. This will...
+      // - remove them from the DOM
+      // - allow them to still be traversed with .nextSibling
+      // - allow a single fragment.qSA to fetch all elements being removed
+      var fragment = window.document.createDocumentFragment();
+      for (i = 0; i < removeCount; i++) {
+        fragment.appendChild(elementsToRemove[i]);
+      }
+
+      if (jqLite.hasData(firstElementToRemove)) {
+        // Copy over user data (that includes Angular's $scope etc.). Don't copy private
+        // data here because there's no public interface in jQuery to do that and copying over
+        // event listeners (which is the main use of private data) wouldn't work anyway.
+        jqLite.data(newNode, jqLite.data(firstElementToRemove));
+
+        // Remove $destroy event listeners from `firstElementToRemove`
+        jqLite(firstElementToRemove).off('$destroy');
+      }
+
+      // Cleanup any data/listeners on the elements and children.
+      // This includes invoking the $destroy event on any elements with listeners.
+      jqLite.cleanData(fragment.querySelectorAll('*'));
+
+      // Update the jqLite collection to only contain the `newNode`
+      for (i = 1; i < removeCount; i++) {
+        delete elementsToRemove[i];
+      }
+      elementsToRemove[0] = newNode;
+      elementsToRemove.length = 1;
+    }
+
+
+    function cloneAndAnnotateFn(fn, annotation) {
+      return extend(function() { return fn.apply(null, arguments); }, fn, annotation);
+    }
+
+
+    function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) {
+      try {
+        linkFn(scope, $element, attrs, controllers, transcludeFn);
+      } catch (e) {
+        $exceptionHandler(e, startingTag($element));
+      }
+    }
+
+
+    // Set up $watches for isolate scope and controller bindings.
+    function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) {
+      var removeWatchCollection = [];
+      var initialChanges = {};
+      var changes;
+      forEach(bindings, function initializeBinding(definition, scopeName) {
+        var attrName = definition.attrName,
+        optional = definition.optional,
+        mode = definition.mode, // @, =, <, or &
+        lastValue,
+        parentGet, parentSet, compare, removeWatch;
+
+        switch (mode) {
+
+          case '@':
+            if (!optional && !hasOwnProperty.call(attrs, attrName)) {
+              destination[scopeName] = attrs[attrName] = undefined;
+            }
+            removeWatch = attrs.$observe(attrName, function(value) {
+              if (isString(value) || isBoolean(value)) {
+                var oldValue = destination[scopeName];
+                recordChanges(scopeName, value, oldValue);
+                destination[scopeName] = value;
+              }
+            });
+            attrs.$$observers[attrName].$$scope = scope;
+            lastValue = attrs[attrName];
+            if (isString(lastValue)) {
+              // If the attribute has been provided then we trigger an interpolation to ensure
+              // the value is there for use in the link fn
+              destination[scopeName] = $interpolate(lastValue)(scope);
+            } else if (isBoolean(lastValue)) {
+              // If the attributes is one of the BOOLEAN_ATTR then Angular will have converted
+              // the value to boolean rather than a string, so we special case this situation
+              destination[scopeName] = lastValue;
+            }
+            initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);
+            removeWatchCollection.push(removeWatch);
+            break;
+
+          case '=':
+            if (!hasOwnProperty.call(attrs, attrName)) {
+              if (optional) break;
+              attrs[attrName] = undefined;
+            }
+            if (optional && !attrs[attrName]) break;
+
+            parentGet = $parse(attrs[attrName]);
+            if (parentGet.literal) {
+              compare = equals;
+            } else {
+              // eslint-disable-next-line no-self-compare
+              compare = function simpleCompare(a, b) { return a === b || (a !== a && b !== b); };
+            }
+            parentSet = parentGet.assign || function() {
+              // reset the change, or we will throw this exception on every $digest
+              lastValue = destination[scopeName] = parentGet(scope);
+              throw $compileMinErr('nonassign',
+                  'Expression \'{0}\' in attribute \'{1}\' used with directive \'{2}\' is non-assignable!',
+                  attrs[attrName], attrName, directive.name);
+            };
+            lastValue = destination[scopeName] = parentGet(scope);
+            var parentValueWatch = function parentValueWatch(parentValue) {
+              if (!compare(parentValue, destination[scopeName])) {
+                // we are out of sync and need to copy
+                if (!compare(parentValue, lastValue)) {
+                  // parent changed and it has precedence
+                  destination[scopeName] = parentValue;
+                } else {
+                  // if the parent can be assigned then do so
+                  parentSet(scope, parentValue = destination[scopeName]);
+                }
+              }
+              lastValue = parentValue;
+              return lastValue;
+            };
+            parentValueWatch.$stateful = true;
+            if (definition.collection) {
+              removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch);
+            } else {
+              removeWatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
+            }
+            removeWatchCollection.push(removeWatch);
+            break;
+
+          case '<':
+            if (!hasOwnProperty.call(attrs, attrName)) {
+              if (optional) break;
+              attrs[attrName] = undefined;
+            }
+            if (optional && !attrs[attrName]) break;
+
+            parentGet = $parse(attrs[attrName]);
+            var deepWatch = parentGet.literal;
+
+            var initialValue = destination[scopeName] = parentGet(scope);
+            initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);
+
+            removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newValue, oldValue) {
+              if (oldValue === newValue) {
+                if (oldValue === initialValue || (deepWatch && equals(oldValue, initialValue))) {
+                  return;
+                }
+                oldValue = initialValue;
+              }
+              recordChanges(scopeName, newValue, oldValue);
+              destination[scopeName] = newValue;
+            }, deepWatch);
+
+            removeWatchCollection.push(removeWatch);
+            break;
+
+          case '&':
+            // Don't assign Object.prototype method to scope
+            parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop;
+
+            // Don't assign noop to destination if expression is not valid
+            if (parentGet === noop && optional) break;
+
+            destination[scopeName] = function(locals) {
+              return parentGet(scope, locals);
+            };
+            break;
+        }
+      });
+
+      function recordChanges(key, currentValue, previousValue) {
+        if (isFunction(destination.$onChanges) && currentValue !== previousValue &&
+            // eslint-disable-next-line no-self-compare
+            (currentValue === currentValue || previousValue === previousValue)) {
+          // If we have not already scheduled the top level onChangesQueue handler then do so now
+          if (!onChangesQueue) {
+            scope.$$postDigest(flushOnChangesQueue);
+            onChangesQueue = [];
+          }
+          // If we have not already queued a trigger of onChanges for this controller then do so now
+          if (!changes) {
+            changes = {};
+            onChangesQueue.push(triggerOnChangesHook);
+          }
+          // If the has been a change on this property already then we need to reuse the previous value
+          if (changes[key]) {
+            previousValue = changes[key].previousValue;
+          }
+          // Store this change
+          changes[key] = new SimpleChange(previousValue, currentValue);
+        }
+      }
+
+      function triggerOnChangesHook() {
+        destination.$onChanges(changes);
+        // Now clear the changes so that we schedule onChanges when more changes arrive
+        changes = undefined;
+      }
+
+      return {
+        initialChanges: initialChanges,
+        removeWatches: removeWatchCollection.length && function removeWatches() {
+          for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) {
+            removeWatchCollection[i]();
+          }
+        }
+      };
+    }
+  }];
+}
+
+function SimpleChange(previous, current) {
+  this.previousValue = previous;
+  this.currentValue = current;
+}
+SimpleChange.prototype.isFirstChange = function() { return this.previousValue === _UNINITIALIZED_VALUE; };
+
+
+var PREFIX_REGEXP = /^((?:x|data)[:\-_])/i;
+var SPECIAL_CHARS_REGEXP = /[:\-_]+(.)/g;
+
+/**
+ * Converts all accepted directives format into proper directive name.
+ * @param name Name to normalize
+ */
+function directiveNormalize(name) {
+  return name
+    .replace(PREFIX_REGEXP, '')
+    .replace(SPECIAL_CHARS_REGEXP, fnCamelCaseReplace);
+}
+
+/**
+ * @ngdoc type
+ * @name $compile.directive.Attributes
+ *
+ * @description
+ * A shared object between directive compile / linking functions which contains normalized DOM
+ * element attributes. The values reflect current binding state `{{ }}`. The normalization is
+ * needed since all of these are treated as equivalent in Angular:
+ *
+ * ```
+ *    <span ng:bind="a" ng-bind="a" data-ng-bind="a" x-ng-bind="a">
+ * ```
+ */
+
+/**
+ * @ngdoc property
+ * @name $compile.directive.Attributes#$attr
+ *
+ * @description
+ * A map of DOM element attribute names to the normalized name. This is
+ * needed to do reverse lookup from normalized name back to actual name.
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $compile.directive.Attributes#$set
+ * @kind function
+ *
+ * @description
+ * Set DOM element attribute value.
+ *
+ *
+ * @param {string} name Normalized element attribute name of the property to modify. The name is
+ *          reverse-translated using the {@link ng.$compile.directive.Attributes#$attr $attr}
+ *          property to the original name.
+ * @param {string} value Value to set the attribute to. The value can be an interpolated string.
+ */
+
+
+
+/**
+ * Closure compiler type information
+ */
+
+function nodesetLinkingFn(
+  /* angular.Scope */ scope,
+  /* NodeList */ nodeList,
+  /* Element */ rootElement,
+  /* function(Function) */ boundTranscludeFn
+) {}
+
+function directiveLinkingFn(
+  /* nodesetLinkingFn */ nodesetLinkingFn,
+  /* angular.Scope */ scope,
+  /* Node */ node,
+  /* Element */ rootElement,
+  /* function(Function) */ boundTranscludeFn
+) {}
+
+function tokenDifference(str1, str2) {
+  var values = '',
+      tokens1 = str1.split(/\s+/),
+      tokens2 = str2.split(/\s+/);
+
+  outer:
+  for (var i = 0; i < tokens1.length; i++) {
+    var token = tokens1[i];
+    for (var j = 0; j < tokens2.length; j++) {
+      if (token === tokens2[j]) continue outer;
+    }
+    values += (values.length > 0 ? ' ' : '') + token;
+  }
+  return values;
+}
+
+function removeComments(jqNodes) {
+  jqNodes = jqLite(jqNodes);
+  var i = jqNodes.length;
+
+  if (i <= 1) {
+    return jqNodes;
+  }
+
+  while (i--) {
+    var node = jqNodes[i];
+    if (node.nodeType === NODE_TYPE_COMMENT ||
+       (node.nodeType === NODE_TYPE_TEXT && node.nodeValue.trim() === '')) {
+         splice.call(jqNodes, i, 1);
+    }
+  }
+  return jqNodes;
+}
+
+var $controllerMinErr = minErr('$controller');
+
+
+var CNTRL_REG = /^(\S+)(\s+as\s+([\w$]+))?$/;
+function identifierForController(controller, ident) {
+  if (ident && isString(ident)) return ident;
+  if (isString(controller)) {
+    var match = CNTRL_REG.exec(controller);
+    if (match) return match[3];
+  }
+}
+
+
+/**
+ * @ngdoc provider
+ * @name $controllerProvider
+ * @this
+ *
+ * @description
+ * The {@link ng.$controller $controller service} is used by Angular to create new
+ * controllers.
+ *
+ * This provider allows controller registration via the
+ * {@link ng.$controllerProvider#register register} method.
+ */
+function $ControllerProvider() {
+  var controllers = {},
+      globals = false;
+
+  /**
+   * @ngdoc method
+   * @name $controllerProvider#has
+   * @param {string} name Controller name to check.
+   */
+  this.has = function(name) {
+    return controllers.hasOwnProperty(name);
+  };
+
+  /**
+   * @ngdoc method
+   * @name $controllerProvider#register
+   * @param {string|Object} name Controller name, or an object map of controllers where the keys are
+   *    the names and the values are the constructors.
+   * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI
+   *    annotations in the array notation).
+   */
+  this.register = function(name, constructor) {
+    assertNotHasOwnProperty(name, 'controller');
+    if (isObject(name)) {
+      extend(controllers, name);
+    } else {
+      controllers[name] = constructor;
+    }
+  };
+
+  /**
+   * @ngdoc method
+   * @name $controllerProvider#allowGlobals
+   * @description If called, allows `$controller` to find controller constructors on `window`
+   *
+   * @deprecated
+   * sinceVersion="v1.3.0"
+   * removeVersion="v1.7.0"
+   * This method of finding controllers has been deprecated.
+   */
+  this.allowGlobals = function() {
+    globals = true;
+  };
+
+
+  this.$get = ['$injector', '$window', function($injector, $window) {
+
+    /**
+     * @ngdoc service
+     * @name $controller
+     * @requires $injector
+     *
+     * @param {Function|string} constructor If called with a function then it's considered to be the
+     *    controller constructor function. Otherwise it's considered to be a string which is used
+     *    to retrieve the controller constructor using the following steps:
+     *
+     *    * check if a controller with given name is registered via `$controllerProvider`
+     *    * check if evaluating the string on the current scope returns a constructor
+     *    * if $controllerProvider#allowGlobals, check `window[constructor]` on the global
+     *      `window` object (deprecated, not recommended)
+     *
+     *    The string can use the `controller as property` syntax, where the controller instance is published
+     *    as the specified property on the `scope`; the `scope` must be injected into `locals` param for this
+     *    to work correctly.
+     *
+     * @param {Object} locals Injection locals for Controller.
+     * @return {Object} Instance of given controller.
+     *
+     * @description
+     * `$controller` service is responsible for instantiating controllers.
+     *
+     * It's just a simple call to {@link auto.$injector $injector}, but extracted into
+     * a service, so that one can override this service with [BC version](https://gist.github.com/1649788).
+     */
+    return function $controller(expression, locals, later, ident) {
+      // PRIVATE API:
+      //   param `later` --- indicates that the controller's constructor is invoked at a later time.
+      //                     If true, $controller will allocate the object with the correct
+      //                     prototype chain, but will not invoke the controller until a returned
+      //                     callback is invoked.
+      //   param `ident` --- An optional label which overrides the label parsed from the controller
+      //                     expression, if any.
+      var instance, match, constructor, identifier;
+      later = later === true;
+      if (ident && isString(ident)) {
+        identifier = ident;
+      }
+
+      if (isString(expression)) {
+        match = expression.match(CNTRL_REG);
+        if (!match) {
+          throw $controllerMinErr('ctrlfmt',
+            'Badly formed controller string \'{0}\'. ' +
+            'Must match `__name__ as __id__` or `__name__`.', expression);
+        }
+        constructor = match[1];
+        identifier = identifier || match[3];
+        expression = controllers.hasOwnProperty(constructor)
+            ? controllers[constructor]
+            : getter(locals.$scope, constructor, true) ||
+                (globals ? getter($window, constructor, true) : undefined);
+
+        if (!expression) {
+          throw $controllerMinErr('ctrlreg',
+            'The controller with the name \'{0}\' is not registered.', constructor);
+        }
+
+        assertArgFn(expression, constructor, true);
+      }
+
+      if (later) {
+        // Instantiate controller later:
+        // This machinery is used to create an instance of the object before calling the
+        // controller's constructor itself.
+        //
+        // This allows properties to be added to the controller before the constructor is
+        // invoked. Primarily, this is used for isolate scope bindings in $compile.
+        //
+        // This feature is not intended for use by applications, and is thus not documented
+        // publicly.
+        // Object creation: http://jsperf.com/create-constructor/2
+        var controllerPrototype = (isArray(expression) ?
+          expression[expression.length - 1] : expression).prototype;
+        instance = Object.create(controllerPrototype || null);
+
+        if (identifier) {
+          addIdentifier(locals, identifier, instance, constructor || expression.name);
+        }
+
+        return extend(function $controllerInit() {
+          var result = $injector.invoke(expression, instance, locals, constructor);
+          if (result !== instance && (isObject(result) || isFunction(result))) {
+            instance = result;
+            if (identifier) {
+              // If result changed, re-assign controllerAs value to scope.
+              addIdentifier(locals, identifier, instance, constructor || expression.name);
+            }
+          }
+          return instance;
+        }, {
+          instance: instance,
+          identifier: identifier
+        });
+      }
+
+      instance = $injector.instantiate(expression, locals, constructor);
+
+      if (identifier) {
+        addIdentifier(locals, identifier, instance, constructor || expression.name);
+      }
+
+      return instance;
+    };
+
+    function addIdentifier(locals, identifier, instance, name) {
+      if (!(locals && isObject(locals.$scope))) {
+        throw minErr('$controller')('noscp',
+          'Cannot export controller \'{0}\' as \'{1}\'! No $scope object provided via `locals`.',
+          name, identifier);
+      }
+
+      locals.$scope[identifier] = instance;
+    }
+  }];
+}
+
+/**
+ * @ngdoc service
+ * @name $document
+ * @requires $window
+ * @this
+ *
+ * @description
+ * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object.
+ *
+ * @example
+   <example module="documentExample" name="document">
+     <file name="index.html">
+       <div ng-controller="ExampleController">
+         <p>$document title: <b ng-bind="title"></b></p>
+         <p>window.document title: <b ng-bind="windowTitle"></b></p>
+       </div>
+     </file>
+     <file name="script.js">
+       angular.module('documentExample', [])
+         .controller('ExampleController', ['$scope', '$document', function($scope, $document) {
+           $scope.title = $document[0].title;
+           $scope.windowTitle = angular.element(window.document)[0].title;
+         }]);
+     </file>
+   </example>
+ */
+function $DocumentProvider() {
+  this.$get = ['$window', function(window) {
+    return jqLite(window.document);
+  }];
+}
+
+
+/**
+ * @private
+ * @this
+ * Listens for document visibility change and makes the current status accessible.
+ */
+function $$IsDocumentHiddenProvider() {
+  this.$get = ['$document', '$rootScope', function($document, $rootScope) {
+    var doc = $document[0];
+    var hidden = doc && doc.hidden;
+
+    $document.on('visibilitychange', changeListener);
+
+    $rootScope.$on('$destroy', function() {
+      $document.off('visibilitychange', changeListener);
+    });
+
+    function changeListener() {
+      hidden = doc.hidden;
+    }
+
+    return function() {
+      return hidden;
+    };
+  }];
+}
+
+/**
+ * @ngdoc service
+ * @name $exceptionHandler
+ * @requires ng.$log
+ * @this
+ *
+ * @description
+ * Any uncaught exception in angular expressions is delegated to this service.
+ * The default implementation simply delegates to `$log.error` which logs it into
+ * the browser console.
+ *
+ * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by
+ * {@link ngMock.$exceptionHandler mock $exceptionHandler} which aids in testing.
+ *
+ * ## Example:
+ *
+ * The example below will overwrite the default `$exceptionHandler` in order to (a) log uncaught
+ * errors to the backend for later inspection by the developers and (b) to use `$log.warn()` instead
+ * of `$log.error()`.
+ *
+ * ```js
+ *   angular.
+ *     module('exceptionOverwrite', []).
+ *     factory('$exceptionHandler', ['$log', 'logErrorsToBackend', function($log, logErrorsToBackend) {
+ *       return function myExceptionHandler(exception, cause) {
+ *         logErrorsToBackend(exception, cause);
+ *         $log.warn(exception, cause);
+ *       };
+ *     }]);
+ * ```
+ *
+ * <hr />
+ * Note, that code executed in event-listeners (even those registered using jqLite's `on`/`bind`
+ * methods) does not delegate exceptions to the {@link ng.$exceptionHandler $exceptionHandler}
+ * (unless executed during a digest).
+ *
+ * If you wish, you can manually delegate exceptions, e.g.
+ * `try { ... } catch(e) { $exceptionHandler(e); }`
+ *
+ * @param {Error} exception Exception associated with the error.
+ * @param {string=} cause Optional information about the context in which
+ *       the error was thrown.
+ *
+ */
+function $ExceptionHandlerProvider() {
+  this.$get = ['$log', function($log) {
+    return function(exception, cause) {
+      $log.error.apply($log, arguments);
+    };
+  }];
+}
+
+var $$ForceReflowProvider = /** @this */ function() {
+  this.$get = ['$document', function($document) {
+    return function(domNode) {
+      //the line below will force the browser to perform a repaint so
+      //that all the animated elements within the animation frame will
+      //be properly updated and drawn on screen. This is required to
+      //ensure that the preparation animation is properly flushed so that
+      //the active state picks up from there. DO NOT REMOVE THIS LINE.
+      //DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
+      //WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
+      //WILL TAKE YEARS AWAY FROM YOUR LIFE.
+      if (domNode) {
+        if (!domNode.nodeType && domNode instanceof jqLite) {
+          domNode = domNode[0];
+        }
+      } else {
+        domNode = $document[0].body;
+      }
+      return domNode.offsetWidth + 1;
+    };
+  }];
+};
+
+var APPLICATION_JSON = 'application/json';
+var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
+var JSON_START = /^\[|^\{(?!\{)/;
+var JSON_ENDS = {
+  '[': /]$/,
+  '{': /}$/
+};
+var JSON_PROTECTION_PREFIX = /^\)]\}',?\n/;
+var $httpMinErr = minErr('$http');
+
+function serializeValue(v) {
+  if (isObject(v)) {
+    return isDate(v) ? v.toISOString() : toJson(v);
+  }
+  return v;
+}
+
+
+/** @this */
+function $HttpParamSerializerProvider() {
+  /**
+   * @ngdoc service
+   * @name $httpParamSerializer
+   * @description
+   *
+   * Default {@link $http `$http`} params serializer that converts objects to strings
+   * according to the following rules:
+   *
+   * * `{'foo': 'bar'}` results in `foo=bar`
+   * * `{'foo': Date.now()}` results in `foo=2015-04-01T09%3A50%3A49.262Z` (`toISOString()` and encoded representation of a Date object)
+   * * `{'foo': ['bar', 'baz']}` results in `foo=bar&foo=baz` (repeated key for each array element)
+   * * `{'foo': {'bar':'baz'}}` results in `foo=%7B%22bar%22%3A%22baz%22%7D` (stringified and encoded representation of an object)
+   *
+   * Note that serializer will sort the request parameters alphabetically.
+   * */
+
+  this.$get = function() {
+    return function ngParamSerializer(params) {
+      if (!params) return '';
+      var parts = [];
+      forEachSorted(params, function(value, key) {
+        if (value === null || isUndefined(value)) return;
+        if (isArray(value)) {
+          forEach(value, function(v) {
+            parts.push(encodeUriQuery(key)  + '=' + encodeUriQuery(serializeValue(v)));
+          });
+        } else {
+          parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value)));
+        }
+      });
+
+      return parts.join('&');
+    };
+  };
+}
+
+/** @this */
+function $HttpParamSerializerJQLikeProvider() {
+  /**
+   * @ngdoc service
+   * @name $httpParamSerializerJQLike
+   *
+   * @description
+   *
+   * Alternative {@link $http `$http`} params serializer that follows
+   * jQuery's [`param()`](http://api.jquery.com/jquery.param/) method logic.
+   * The serializer will also sort the params alphabetically.
+   *
+   * To use it for serializing `$http` request parameters, set it as the `paramSerializer` property:
+   *
+   * ```js
+   * $http({
+   *   url: myUrl,
+   *   method: 'GET',
+   *   params: myParams,
+   *   paramSerializer: '$httpParamSerializerJQLike'
+   * });
+   * ```
+   *
+   * It is also possible to set it as the default `paramSerializer` in the
+   * {@link $httpProvider#defaults `$httpProvider`}.
+   *
+   * Additionally, you can inject the serializer and use it explicitly, for example to serialize
+   * form data for submission:
+   *
+   * ```js
+   * .controller(function($http, $httpParamSerializerJQLike) {
+   *   //...
+   *
+   *   $http({
+   *     url: myUrl,
+   *     method: 'POST',
+   *     data: $httpParamSerializerJQLike(myData),
+   *     headers: {
+   *       'Content-Type': 'application/x-www-form-urlencoded'
+   *     }
+   *   });
+   *
+   * });
+   * ```
+   *
+   * */
+  this.$get = function() {
+    return function jQueryLikeParamSerializer(params) {
+      if (!params) return '';
+      var parts = [];
+      serialize(params, '', true);
+      return parts.join('&');
+
+      function serialize(toSerialize, prefix, topLevel) {
+        if (toSerialize === null || isUndefined(toSerialize)) return;
+        if (isArray(toSerialize)) {
+          forEach(toSerialize, function(value, index) {
+            serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');
+          });
+        } else if (isObject(toSerialize) && !isDate(toSerialize)) {
+          forEachSorted(toSerialize, function(value, key) {
+            serialize(value, prefix +
+                (topLevel ? '' : '[') +
+                key +
+                (topLevel ? '' : ']'));
+          });
+        } else {
+          parts.push(encodeUriQuery(prefix) + '=' + encodeUriQuery(serializeValue(toSerialize)));
+        }
+      }
+    };
+  };
+}
+
+function defaultHttpResponseTransform(data, headers) {
+  if (isString(data)) {
+    // Strip json vulnerability protection prefix and trim whitespace
+    var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim();
+
+    if (tempData) {
+      var contentType = headers('Content-Type');
+      if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {
+        data = fromJson(tempData);
+      }
+    }
+  }
+
+  return data;
+}
+
+function isJsonLike(str) {
+    var jsonStart = str.match(JSON_START);
+    return jsonStart && JSON_ENDS[jsonStart[0]].test(str);
+}
+
+/**
+ * Parse headers into key value object
+ *
+ * @param {string} headers Raw headers as a string
+ * @returns {Object} Parsed headers as key value object
+ */
+function parseHeaders(headers) {
+  var parsed = createMap(), i;
+
+  function fillInParsed(key, val) {
+    if (key) {
+      parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
+    }
+  }
+
+  if (isString(headers)) {
+    forEach(headers.split('\n'), function(line) {
+      i = line.indexOf(':');
+      fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1)));
+    });
+  } else if (isObject(headers)) {
+    forEach(headers, function(headerVal, headerKey) {
+      fillInParsed(lowercase(headerKey), trim(headerVal));
+    });
+  }
+
+  return parsed;
+}
+
+
+/**
+ * Returns a function that provides access to parsed headers.
+ *
+ * Headers are lazy parsed when first requested.
+ * @see parseHeaders
+ *
+ * @param {(string|Object)} headers Headers to provide access to.
+ * @returns {function(string=)} Returns a getter function which if called with:
+ *
+ *   - if called with an argument returns a single header value or null
+ *   - if called with no arguments returns an object containing all headers.
+ */
+function headersGetter(headers) {
+  var headersObj;
+
+  return function(name) {
+    if (!headersObj) headersObj =  parseHeaders(headers);
+
+    if (name) {
+      var value = headersObj[lowercase(name)];
+      if (value === undefined) {
+        value = null;
+      }
+      return value;
+    }
+
+    return headersObj;
+  };
+}
+
+
+/**
+ * Chain all given functions
+ *
+ * This function is used for both request and response transforming
+ *
+ * @param {*} data Data to transform.
+ * @param {function(string=)} headers HTTP headers getter fn.
+ * @param {number} status HTTP status code of the response.
+ * @param {(Function|Array.<Function>)} fns Function or an array of functions.
+ * @returns {*} Transformed data.
+ */
+function transformData(data, headers, status, fns) {
+  if (isFunction(fns)) {
+    return fns(data, headers, status);
+  }
+
+  forEach(fns, function(fn) {
+    data = fn(data, headers, status);
+  });
+
+  return data;
+}
+
+
+function isSuccess(status) {
+  return 200 <= status && status < 300;
+}
+
+
+/**
+ * @ngdoc provider
+ * @name $httpProvider
+ * @this
+ *
+ * @description
+ * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.
+ * */
+function $HttpProvider() {
+  /**
+   * @ngdoc property
+   * @name $httpProvider#defaults
+   * @description
+   *
+   * Object containing default values for all {@link ng.$http $http} requests.
+   *
+   * - **`defaults.cache`** - {boolean|Object} - A boolean value or object created with
+   * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of HTTP responses
+   * by default. See {@link $http#caching $http Caching} for more information.
+   *
+   * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.
+   * Defaults value is `'XSRF-TOKEN'`.
+   *
+   * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the
+   * XSRF token. Defaults value is `'X-XSRF-TOKEN'`.
+   *
+   * - **`defaults.headers`** - {Object} - Default headers for all $http requests.
+   * Refer to {@link ng.$http#setting-http-headers $http} for documentation on
+   * setting default headers.
+   *     - **`defaults.headers.common`**
+   *     - **`defaults.headers.post`**
+   *     - **`defaults.headers.put`**
+   *     - **`defaults.headers.patch`**
+   *
+   *
+   * - **`defaults.paramSerializer`** - `{string|function(Object<string,string>):string}` - A function
+   *  used to the prepare string representation of request parameters (specified as an object).
+   *  If specified as string, it is interpreted as a function registered with the {@link auto.$injector $injector}.
+   *  Defaults to {@link ng.$httpParamSerializer $httpParamSerializer}.
+   *
+   * - **`defaults.jsonpCallbackParam`** - `{string}` - the name of the query parameter that passes the name of the
+   * callback in a JSONP request. The value of this parameter will be replaced with the expression generated by the
+   * {@link $jsonpCallbacks} service. Defaults to `'callback'`.
+   *
+   **/
+  var defaults = this.defaults = {
+    // transform incoming response data
+    transformResponse: [defaultHttpResponseTransform],
+
+    // transform outgoing request data
+    transformRequest: [function(d) {
+      return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d;
+    }],
+
+    // default headers
+    headers: {
+      common: {
+        'Accept': 'application/json, text/plain, */*'
+      },
+      post:   shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
+      put:    shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
+      patch:  shallowCopy(CONTENT_TYPE_APPLICATION_JSON)
+    },
+
+    xsrfCookieName: 'XSRF-TOKEN',
+    xsrfHeaderName: 'X-XSRF-TOKEN',
+
+    paramSerializer: '$httpParamSerializer',
+
+    jsonpCallbackParam: 'callback'
+  };
+
+  var useApplyAsync = false;
+  /**
+   * @ngdoc method
+   * @name $httpProvider#useApplyAsync
+   * @description
+   *
+   * Configure $http service to combine processing of multiple http responses received at around
+   * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in
+   * significant performance improvement for bigger applications that make many HTTP requests
+   * concurrently (common during application bootstrap).
+   *
+   * Defaults to false. If no value is specified, returns the current configured value.
+   *
+   * @param {boolean=} value If true, when requests are loaded, they will schedule a deferred
+   *    "apply" on the next tick, giving time for subsequent requests in a roughly ~10ms window
+   *    to load and share the same digest cycle.
+   *
+   * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.
+   *    otherwise, returns the current configured value.
+   **/
+  this.useApplyAsync = function(value) {
+    if (isDefined(value)) {
+      useApplyAsync = !!value;
+      return this;
+    }
+    return useApplyAsync;
+  };
+
+  /**
+   * @ngdoc property
+   * @name $httpProvider#interceptors
+   * @description
+   *
+   * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http}
+   * pre-processing of request or postprocessing of responses.
+   *
+   * These service factories are ordered by request, i.e. they are applied in the same order as the
+   * array, on request, but reverse order, on response.
+   *
+   * {@link ng.$http#interceptors Interceptors detailed info}
+   **/
+  var interceptorFactories = this.interceptors = [];
+
+  this.$get = ['$browser', '$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector', '$sce',
+      function($browser, $httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector, $sce) {
+
+    var defaultCache = $cacheFactory('$http');
+
+    /**
+     * Make sure that default param serializer is exposed as a function
+     */
+    defaults.paramSerializer = isString(defaults.paramSerializer) ?
+      $injector.get(defaults.paramSerializer) : defaults.paramSerializer;
+
+    /**
+     * Interceptors stored in reverse order. Inner interceptors before outer interceptors.
+     * The reversal is needed so that we can build up the interception chain around the
+     * server request.
+     */
+    var reversedInterceptors = [];
+
+    forEach(interceptorFactories, function(interceptorFactory) {
+      reversedInterceptors.unshift(isString(interceptorFactory)
+          ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));
+    });
+
+    /**
+     * @ngdoc service
+     * @kind function
+     * @name $http
+     * @requires ng.$httpBackend
+     * @requires $cacheFactory
+     * @requires $rootScope
+     * @requires $q
+     * @requires $injector
+     *
+     * @description
+     * The `$http` service is a core Angular service that facilitates communication with the remote
+     * HTTP servers via the browser's [XMLHttpRequest](https://developer.mozilla.org/en/xmlhttprequest)
+     * object or via [JSONP](http://en.wikipedia.org/wiki/JSONP).
+     *
+     * For unit testing applications that use `$http` service, see
+     * {@link ngMock.$httpBackend $httpBackend mock}.
+     *
+     * For a higher level of abstraction, please check out the {@link ngResource.$resource
+     * $resource} service.
+     *
+     * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
+     * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
+     * it is important to familiarize yourself with these APIs and the guarantees they provide.
+     *
+     *
+     * ## General usage
+     * The `$http` service is a function which takes a single argument — a {@link $http#usage configuration object} —
+     * that is used to generate an HTTP request and returns  a {@link ng.$q promise}.
+     *
+     * ```js
+     *   // Simple GET request example:
+     *   $http({
+     *     method: 'GET',
+     *     url: '/someUrl'
+     *   }).then(function successCallback(response) {
+     *       // this callback will be called asynchronously
+     *       // when the response is available
+     *     }, function errorCallback(response) {
+     *       // called asynchronously if an error occurs
+     *       // or server returns response with an error status.
+     *     });
+     * ```
+     *
+     * The response object has these properties:
+     *
+     *   - **data** – `{string|Object}` – The response body transformed with the transform
+     *     functions.
+     *   - **status** – `{number}` – HTTP status code of the response.
+     *   - **headers** – `{function([headerName])}` – Header getter function.
+     *   - **config** – `{Object}` – The configuration object that was used to generate the request.
+     *   - **statusText** – `{string}` – HTTP status text of the response.
+     *
+     * A response status code between 200 and 299 is considered a success status and will result in
+     * the success callback being called. Any response status code outside of that range is
+     * considered an error status and will result in the error callback being called.
+     * Also, status codes less than -1 are normalized to zero. -1 usually means the request was
+     * aborted, e.g. using a `config.timeout`.
+     * Note that if the response is a redirect, XMLHttpRequest will transparently follow it, meaning
+     * that the outcome (success or error) will be determined by the final response status code.
+     *
+     *
+     * ## Shortcut methods
+     *
+     * Shortcut methods are also available. All shortcut methods require passing in the URL, and
+     * request data must be passed in for POST/PUT requests. An optional config can be passed as the
+     * last argument.
+     *
+     * ```js
+     *   $http.get('/someUrl', config).then(successCallback, errorCallback);
+     *   $http.post('/someUrl', data, config).then(successCallback, errorCallback);
+     * ```
+     *
+     * Complete list of shortcut methods:
+     *
+     * - {@link ng.$http#get $http.get}
+     * - {@link ng.$http#head $http.head}
+     * - {@link ng.$http#post $http.post}
+     * - {@link ng.$http#put $http.put}
+     * - {@link ng.$http#delete $http.delete}
+     * - {@link ng.$http#jsonp $http.jsonp}
+     * - {@link ng.$http#patch $http.patch}
+     *
+     *
+     * ## Writing Unit Tests that use $http
+     * When unit testing (using {@link ngMock ngMock}), it is necessary to call
+     * {@link ngMock.$httpBackend#flush $httpBackend.flush()} to flush each pending
+     * request using trained responses.
+     *
+     * ```
+     * $httpBackend.expectGET(...);
+     * $http.get(...);
+     * $httpBackend.flush();
+     * ```
+     *
+     * ## Setting HTTP Headers
+     *
+     * The $http service will automatically add certain HTTP headers to all requests. These defaults
+     * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
+     * object, which currently contains this default configuration:
+     *
+     * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
+     *   - <code>Accept: application/json, text/plain, \*&#65279;/&#65279;\*</code>
+     * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
+     *   - `Content-Type: application/json`
+     * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
+     *   - `Content-Type: application/json`
+     *
+     * To add or overwrite these defaults, simply add or remove a property from these configuration
+     * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
+     * with the lowercased HTTP method name as the key, e.g.
+     * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }`.
+     *
+     * The defaults can also be set at runtime via the `$http.defaults` object in the same
+     * fashion. For example:
+     *
+     * ```
+     * module.run(function($http) {
+     *   $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w';
+     * });
+     * ```
+     *
+     * In addition, you can supply a `headers` property in the config object passed when
+     * calling `$http(config)`, which overrides the defaults without changing them globally.
+     *
+     * To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis,
+     * Use the `headers` property, setting the desired header to `undefined`. For example:
+     *
+     * ```js
+     * var req = {
+     *  method: 'POST',
+     *  url: 'http://example.com',
+     *  headers: {
+     *    'Content-Type': undefined
+     *  },
+     *  data: { test: 'test' }
+     * }
+     *
+     * $http(req).then(function(){...}, function(){...});
+     * ```
+     *
+     * ## Transforming Requests and Responses
+     *
+     * Both requests and responses can be transformed using transformation functions: `transformRequest`
+     * and `transformResponse`. These properties can be a single function that returns
+     * the transformed value (`function(data, headersGetter, status)`) or an array of such transformation functions,
+     * which allows you to `push` or `unshift` a new transformation function into the transformation chain.
+     *
+     * <div class="alert alert-warning">
+     * **Note:** Angular does not make a copy of the `data` parameter before it is passed into the `transformRequest` pipeline.
+     * That means changes to the properties of `data` are not local to the transform function (since Javascript passes objects by reference).
+     * For example, when calling `$http.get(url, $scope.myObject)`, modifications to the object's properties in a transformRequest
+     * function will be reflected on the scope and in any templates where the object is data-bound.
+     * To prevent this, transform functions should have no side-effects.
+     * If you need to modify properties, it is recommended to make a copy of the data, or create new object to return.
+     * </div>
+     *
+     * ### Default Transformations
+     *
+     * The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and
+     * `defaults.transformResponse` properties. If a request does not provide its own transformations
+     * then these will be applied.
+     *
+     * You can augment or replace the default transformations by modifying these properties by adding to or
+     * replacing the array.
+     *
+     * Angular provides the following default transformations:
+     *
+     * Request transformations (`$httpProvider.defaults.transformRequest` and `$http.defaults.transformRequest`):
+     *
+     * - If the `data` property of the request configuration object contains an object, serialize it
+     *   into JSON format.
+     *
+     * Response transformations (`$httpProvider.defaults.transformResponse` and `$http.defaults.transformResponse`):
+     *
+     *  - If XSRF prefix is detected, strip it (see Security Considerations section below).
+     *  - If JSON response is detected, deserialize it using a JSON parser.
+     *
+     *
+     * ### Overriding the Default Transformations Per Request
+     *
+     * If you wish to override the request/response transformations only for a single request then provide
+     * `transformRequest` and/or `transformResponse` properties on the configuration object passed
+     * into `$http`.
+     *
+     * Note that if you provide these properties on the config object the default transformations will be
+     * overwritten. If you wish to augment the default transformations then you must include them in your
+     * local transformation array.
+     *
+     * The following code demonstrates adding a new response transformation to be run after the default response
+     * transformations have been run.
+     *
+     * ```js
+     * function appendTransform(defaults, transform) {
+     *
+     *   // We can't guarantee that the default transformation is an array
+     *   defaults = angular.isArray(defaults) ? defaults : [defaults];
+     *
+     *   // Append the new transformation to the defaults
+     *   return defaults.concat(transform);
+     * }
+     *
+     * $http({
+     *   url: '...',
+     *   method: 'GET',
+     *   transformResponse: appendTransform($http.defaults.transformResponse, function(value) {
+     *     return doTransform(value);
+     *   })
+     * });
+     * ```
+     *
+     *
+     * ## Caching
+     *
+     * {@link ng.$http `$http`} responses are not cached by default. To enable caching, you must
+     * set the config.cache value or the default cache value to TRUE or to a cache object (created
+     * with {@link ng.$cacheFactory `$cacheFactory`}). If defined, the value of config.cache takes
+     * precedence over the default cache value.
+     *
+     * In order to:
+     *   * cache all responses - set the default cache value to TRUE or to a cache object
+     *   * cache a specific response - set config.cache value to TRUE or to a cache object
+     *
+     * If caching is enabled, but neither the default cache nor config.cache are set to a cache object,
+     * then the default `$cacheFactory("$http")` object is used.
+     *
+     * The default cache value can be set by updating the
+     * {@link ng.$http#defaults `$http.defaults.cache`} property or the
+     * {@link $httpProvider#defaults `$httpProvider.defaults.cache`} property.
+     *
+     * When caching is enabled, {@link ng.$http `$http`} stores the response from the server using
+     * the relevant cache object. The next time the same request is made, the response is returned
+     * from the cache without sending a request to the server.
+     *
+     * Take note that:
+     *
+     *   * Only GET and JSONP requests are cached.
+     *   * The cache key is the request URL including search parameters; headers are not considered.
+     *   * Cached responses are returned asynchronously, in the same way as responses from the server.
+     *   * If multiple identical requests are made using the same cache, which is not yet populated,
+     *     one request will be made to the server and remaining requests will return the same response.
+     *   * A cache-control header on the response does not affect if or how responses are cached.
+     *
+     *
+     * ## Interceptors
+     *
+     * Before you start creating interceptors, be sure to understand the
+     * {@link ng.$q $q and deferred/promise APIs}.
+     *
+     * For purposes of global error handling, authentication, or any kind of synchronous or
+     * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be
+     * able to intercept requests before they are handed to the server and
+     * responses before they are handed over to the application code that
+     * initiated these requests. The interceptors leverage the {@link ng.$q
+     * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing.
+     *
+     * The interceptors are service factories that are registered with the `$httpProvider` by
+     * adding them to the `$httpProvider.interceptors` array. The factory is called and
+     * injected with dependencies (if specified) and returns the interceptor.
+     *
+     * There are two kinds of interceptors (and two kinds of rejection interceptors):
+     *
+     *   * `request`: interceptors get called with a http {@link $http#usage config} object. The function is free to
+     *     modify the `config` object or create a new one. The function needs to return the `config`
+     *     object directly, or a promise containing the `config` or a new `config` object.
+     *   * `requestError`: interceptor gets called when a previous interceptor threw an error or
+     *     resolved with a rejection.
+     *   * `response`: interceptors get called with http `response` object. The function is free to
+     *     modify the `response` object or create a new one. The function needs to return the `response`
+     *     object directly, or as a promise containing the `response` or a new `response` object.
+     *   * `responseError`: interceptor gets called when a previous interceptor threw an error or
+     *     resolved with a rejection.
+     *
+     *
+     * ```js
+     *   // register the interceptor as a service
+     *   $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
+     *     return {
+     *       // optional method
+     *       'request': function(config) {
+     *         // do something on success
+     *         return config;
+     *       },
+     *
+     *       // optional method
+     *      'requestError': function(rejection) {
+     *         // do something on error
+     *         if (canRecover(rejection)) {
+     *           return responseOrNewPromise
+     *         }
+     *         return $q.reject(rejection);
+     *       },
+     *
+     *
+     *
+     *       // optional method
+     *       'response': function(response) {
+     *         // do something on success
+     *         return response;
+     *       },
+     *
+     *       // optional method
+     *      'responseError': function(rejection) {
+     *         // do something on error
+     *         if (canRecover(rejection)) {
+     *           return responseOrNewPromise
+     *         }
+     *         return $q.reject(rejection);
+     *       }
+     *     };
+     *   });
+     *
+     *   $httpProvider.interceptors.push('myHttpInterceptor');
+     *
+     *
+     *   // alternatively, register the interceptor via an anonymous factory
+     *   $httpProvider.interceptors.push(function($q, dependency1, dependency2) {
+     *     return {
+     *      'request': function(config) {
+     *          // same as above
+     *       },
+     *
+     *       'response': function(response) {
+     *          // same as above
+     *       }
+     *     };
+     *   });
+     * ```
+     *
+     * ## Security Considerations
+     *
+     * When designing web applications, consider security threats from:
+     *
+     * - [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)
+     * - [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery)
+     *
+     * Both server and the client must cooperate in order to eliminate these threats. Angular comes
+     * pre-configured with strategies that address these issues, but for this to work backend server
+     * cooperation is required.
+     *
+     * ### JSON Vulnerability Protection
+     *
+     * A [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)
+     * allows third party website to turn your JSON resource URL into
+     * [JSONP](http://en.wikipedia.org/wiki/JSONP) request under some conditions. To
+     * counter this your server can prefix all JSON requests with following string `")]}',\n"`.
+     * Angular will automatically strip the prefix before processing it as JSON.
+     *
+     * For example if your server needs to return:
+     * ```js
+     * ['one','two']
+     * ```
+     *
+     * which is vulnerable to attack, your server can return:
+     * ```js
+     * )]}',
+     * ['one','two']
+     * ```
+     *
+     * Angular will strip the prefix, before processing the JSON.
+     *
+     *
+     * ### Cross Site Request Forgery (XSRF) Protection
+     *
+     * [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by
+     * which the attacker can trick an authenticated user into unknowingly executing actions on your
+     * website. Angular provides a mechanism to counter XSRF. When performing XHR requests, the
+     * $http service reads a token from a cookie (by default, `XSRF-TOKEN`) and sets it as an HTTP
+     * header (`X-XSRF-TOKEN`). Since only JavaScript that runs on your domain could read the
+     * cookie, your server can be assured that the XHR came from JavaScript running on your domain.
+     * The header will not be set for cross-domain requests.
+     *
+     * To take advantage of this, your server needs to set a token in a JavaScript readable session
+     * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
+     * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
+     * that only JavaScript running on your domain could have sent the request. The token must be
+     * unique for each user and must be verifiable by the server (to prevent the JavaScript from
+     * making up its own tokens). We recommend that the token is a digest of your site's
+     * authentication cookie with a [salt](https://en.wikipedia.org/wiki/Salt_(cryptography&#41;)
+     * for added security.
+     *
+     * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName
+     * properties of either $httpProvider.defaults at config-time, $http.defaults at run-time,
+     * or the per-request config object.
+     *
+     * In order to prevent collisions in environments where multiple Angular apps share the
+     * same domain or subdomain, we recommend that each application uses unique cookie name.
+     *
+     * @param {object} config Object describing the request to be made and how it should be
+     *    processed. The object has following properties:
+     *
+     *    - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)
+     *    - **url** – `{string|TrustedObject}` – Absolute or relative URL of the resource that is being requested;
+     *      or an object created by a call to `$sce.trustAsResourceUrl(url)`.
+     *    - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be serialized
+     *      with the `paramSerializer` and appended as GET parameters.
+     *    - **data** – `{string|Object}` – Data to be sent as the request message data.
+     *    - **headers** – `{Object}` – Map of strings or functions which return strings representing
+     *      HTTP headers to send to the server. If the return value of a function is null, the
+     *      header will not be sent. Functions accept a config object as an argument.
+     *    - **eventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest object.
+     *      To bind events to the XMLHttpRequest upload object, use `uploadEventHandlers`.
+     *      The handler will be called in the context of a `$apply` block.
+     *    - **uploadEventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest upload
+     *      object. To bind events to the XMLHttpRequest object, use `eventHandlers`.
+     *      The handler will be called in the context of a `$apply` block.
+     *    - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.
+     *    - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.
+     *    - **transformRequest** –
+     *      `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
+     *      transform function or an array of such functions. The transform function takes the http
+     *      request body and headers and returns its transformed (typically serialized) version.
+     *      See {@link ng.$http#overriding-the-default-transformations-per-request
+     *      Overriding the Default Transformations}
+     *    - **transformResponse** –
+     *      `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –
+     *      transform function or an array of such functions. The transform function takes the http
+     *      response body, headers and status and returns its transformed (typically deserialized) version.
+     *      See {@link ng.$http#overriding-the-default-transformations-per-request
+     *      Overriding the Default Transformations}
+     *    - **paramSerializer** - `{string|function(Object<string,string>):string}` - A function used to
+     *      prepare the string representation of request parameters (specified as an object).
+     *      If specified as string, it is interpreted as function registered with the
+     *      {@link $injector $injector}, which means you can create your own serializer
+     *      by registering it as a {@link auto.$provide#service service}.
+     *      The default serializer is the {@link $httpParamSerializer $httpParamSerializer};
+     *      alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike}
+     *    - **cache** – `{boolean|Object}` – A boolean value or object created with
+     *      {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response.
+     *      See {@link $http#caching $http Caching} for more information.
+     *    - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
+     *      that should abort the request when resolved.
+     *    - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the
+     *      XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials)
+     *      for more information.
+     *    - **responseType** - `{string}` - see
+     *      [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype).
+     *
+     * @returns {HttpPromise} Returns a {@link ng.$q `Promise}` that will be resolved to a response object
+     *                        when the request succeeds or fails.
+     *
+     *
+     * @property {Array.<Object>} pendingRequests Array of config objects for currently pending
+     *   requests. This is primarily meant to be used for debugging purposes.
+     *
+     *
+     * @example
+<example module="httpExample" name="http-service">
+<file name="index.html">
+  <div ng-controller="FetchController">
+    <select ng-model="method" aria-label="Request method">
+      <option>GET</option>
+      <option>JSONP</option>
+    </select>
+    <input type="text" ng-model="url" size="80" aria-label="URL" />
+    <button id="fetchbtn" ng-click="fetch()">fetch</button><br>
+    <button id="samplegetbtn" ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
+    <button id="samplejsonpbtn"
+      ng-click="updateModel('JSONP',
+                    'https://angularjs.org/greet.php?name=Super%20Hero')">
+      Sample JSONP
+    </button>
+    <button id="invalidjsonpbtn"
+      ng-click="updateModel('JSONP', 'https://angularjs.org/doesntexist')">
+        Invalid JSONP
+      </button>
+    <pre>http status code: {{status}}</pre>
+    <pre>http response data: {{data}}</pre>
+  </div>
+</file>
+<file name="script.js">
+  angular.module('httpExample', [])
+    .config(['$sceDelegateProvider', function($sceDelegateProvider) {
+      // We must whitelist the JSONP endpoint that we are using to show that we trust it
+      $sceDelegateProvider.resourceUrlWhitelist([
+        'self',
+        'https://angularjs.org/**'
+      ]);
+    }])
+    .controller('FetchController', ['$scope', '$http', '$templateCache',
+      function($scope, $http, $templateCache) {
+        $scope.method = 'GET';
+        $scope.url = 'http-hello.html';
+
+        $scope.fetch = function() {
+          $scope.code = null;
+          $scope.response = null;
+
+          $http({method: $scope.method, url: $scope.url, cache: $templateCache}).
+            then(function(response) {
+              $scope.status = response.status;
+              $scope.data = response.data;
+            }, function(response) {
+              $scope.data = response.data || 'Request failed';
+              $scope.status = response.status;
+          });
+        };
+
+        $scope.updateModel = function(method, url) {
+          $scope.method = method;
+          $scope.url = url;
+        };
+      }]);
+</file>
+<file name="http-hello.html">
+  Hello, $http!
+</file>
+<file name="protractor.js" type="protractor">
+  var status = element(by.binding('status'));
+  var data = element(by.binding('data'));
+  var fetchBtn = element(by.id('fetchbtn'));
+  var sampleGetBtn = element(by.id('samplegetbtn'));
+  var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));
+
+  it('should make an xhr GET request', function() {
+    sampleGetBtn.click();
+    fetchBtn.click();
+    expect(status.getText()).toMatch('200');
+    expect(data.getText()).toMatch(/Hello, \$http!/);
+  });
+
+// Commented out due to flakes. See https://github.com/angular/angular.js/issues/9185
+// it('should make a JSONP request to angularjs.org', function() {
+//   var sampleJsonpBtn = element(by.id('samplejsonpbtn'));
+//   sampleJsonpBtn.click();
+//   fetchBtn.click();
+//   expect(status.getText()).toMatch('200');
+//   expect(data.getText()).toMatch(/Super Hero!/);
+// });
+
+  it('should make JSONP request to invalid URL and invoke the error handler',
+      function() {
+    invalidJsonpBtn.click();
+    fetchBtn.click();
+    expect(status.getText()).toMatch('0');
+    expect(data.getText()).toMatch('Request failed');
+  });
+</file>
+</example>
+     */
+    function $http(requestConfig) {
+
+      if (!isObject(requestConfig)) {
+        throw minErr('$http')('badreq', 'Http request configuration must be an object.  Received: {0}', requestConfig);
+      }
+
+      if (!isString($sce.valueOf(requestConfig.url))) {
+        throw minErr('$http')('badreq', 'Http request configuration url must be a string or a $sce trusted object.  Received: {0}', requestConfig.url);
+      }
+
+      var config = extend({
+        method: 'get',
+        transformRequest: defaults.transformRequest,
+        transformResponse: defaults.transformResponse,
+        paramSerializer: defaults.paramSerializer,
+        jsonpCallbackParam: defaults.jsonpCallbackParam
+      }, requestConfig);
+
+      config.headers = mergeHeaders(requestConfig);
+      config.method = uppercase(config.method);
+      config.paramSerializer = isString(config.paramSerializer) ?
+          $injector.get(config.paramSerializer) : config.paramSerializer;
+
+      $browser.$$incOutstandingRequestCount();
+
+      var requestInterceptors = [];
+      var responseInterceptors = [];
+      var promise = $q.resolve(config);
+
+      // apply interceptors
+      forEach(reversedInterceptors, function(interceptor) {
+        if (interceptor.request || interceptor.requestError) {
+          requestInterceptors.unshift(interceptor.request, interceptor.requestError);
+        }
+        if (interceptor.response || interceptor.responseError) {
+          responseInterceptors.push(interceptor.response, interceptor.responseError);
+        }
+      });
+
+      promise = chainInterceptors(promise, requestInterceptors);
+      promise = promise.then(serverRequest);
+      promise = chainInterceptors(promise, responseInterceptors);
+      promise = promise.finally(completeOutstandingRequest);
+
+      return promise;
+
+
+      function chainInterceptors(promise, interceptors) {
+        for (var i = 0, ii = interceptors.length; i < ii;) {
+          var thenFn = interceptors[i++];
+          var rejectFn = interceptors[i++];
+
+          promise = promise.then(thenFn, rejectFn);
+        }
+
+        interceptors.length = 0;
+
+        return promise;
+      }
+
+      function completeOutstandingRequest() {
+        $browser.$$completeOutstandingRequest(noop);
+      }
+
+      function executeHeaderFns(headers, config) {
+        var headerContent, processedHeaders = {};
+
+        forEach(headers, function(headerFn, header) {
+          if (isFunction(headerFn)) {
+            headerContent = headerFn(config);
+            if (headerContent != null) {
+              processedHeaders[header] = headerContent;
+            }
+          } else {
+            processedHeaders[header] = headerFn;
+          }
+        });
+
+        return processedHeaders;
+      }
+
+      function mergeHeaders(config) {
+        var defHeaders = defaults.headers,
+            reqHeaders = extend({}, config.headers),
+            defHeaderName, lowercaseDefHeaderName, reqHeaderName;
+
+        defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);
+
+        // using for-in instead of forEach to avoid unnecessary iteration after header has been found
+        defaultHeadersIteration:
+        for (defHeaderName in defHeaders) {
+          lowercaseDefHeaderName = lowercase(defHeaderName);
+
+          for (reqHeaderName in reqHeaders) {
+            if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {
+              continue defaultHeadersIteration;
+            }
+          }
+
+          reqHeaders[defHeaderName] = defHeaders[defHeaderName];
+        }
+
+        // execute if header value is a function for merged headers
+        return executeHeaderFns(reqHeaders, shallowCopy(config));
+      }
+
+      function serverRequest(config) {
+        var headers = config.headers;
+        var reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest);
+
+        // strip content-type if data is undefined
+        if (isUndefined(reqData)) {
+          forEach(headers, function(value, header) {
+            if (lowercase(header) === 'content-type') {
+              delete headers[header];
+            }
+          });
+        }
+
+        if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
+          config.withCredentials = defaults.withCredentials;
+        }
+
+        // send request
+        return sendReq(config, reqData).then(transformResponse, transformResponse);
+      }
+
+      function transformResponse(response) {
+        // make a copy since the response must be cacheable
+        var resp = extend({}, response);
+        resp.data = transformData(response.data, response.headers, response.status,
+                                  config.transformResponse);
+        return (isSuccess(response.status))
+          ? resp
+          : $q.reject(resp);
+      }
+    }
+
+    $http.pendingRequests = [];
+
+    /**
+     * @ngdoc method
+     * @name $http#get
+     *
+     * @description
+     * Shortcut method to perform `GET` request.
+     *
+     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;
+     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.
+     * @param {Object=} config Optional configuration object
+     * @returns {HttpPromise} Future object
+     */
+
+    /**
+     * @ngdoc method
+     * @name $http#delete
+     *
+     * @description
+     * Shortcut method to perform `DELETE` request.
+     *
+     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;
+     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.
+     * @param {Object=} config Optional configuration object
+     * @returns {HttpPromise} Future object
+     */
+
+    /**
+     * @ngdoc method
+     * @name $http#head
+     *
+     * @description
+     * Shortcut method to perform `HEAD` request.
+     *
+     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;
+     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.
+     * @param {Object=} config Optional configuration object
+     * @returns {HttpPromise} Future object
+     */
+
+    /**
+     * @ngdoc method
+     * @name $http#jsonp
+     *
+     * @description
+     * Shortcut method to perform `JSONP` request.
+     *
+     * Note that, since JSONP requests are sensitive because the response is given full access to the browser,
+     * the url must be declared, via {@link $sce} as a trusted resource URL.
+     * You can trust a URL by adding it to the whitelist via
+     * {@link $sceDelegateProvider#resourceUrlWhitelist  `$sceDelegateProvider.resourceUrlWhitelist`} or
+     * by explicitly trusting the URL via {@link $sce#trustAsResourceUrl `$sce.trustAsResourceUrl(url)`}.
+     *
+     * JSONP requests must specify a callback to be used in the response from the server. This callback
+     * is passed as a query parameter in the request. You must specify the name of this parameter by
+     * setting the `jsonpCallbackParam` property on the request config object.
+     *
+     * ```
+     * $http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'})
+     * ```
+     *
+     * You can also specify a default callback parameter name in `$http.defaults.jsonpCallbackParam`.
+     * Initially this is set to `'callback'`.
+     *
+     * <div class="alert alert-danger">
+     * You can no longer use the `JSON_CALLBACK` string as a placeholder for specifying where the callback
+     * parameter value should go.
+     * </div>
+     *
+     * If you would like to customise where and how the callbacks are stored then try overriding
+     * or decorating the {@link $jsonpCallbacks} service.
+     *
+     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;
+     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.
+     * @param {Object=} config Optional configuration object
+     * @returns {HttpPromise} Future object
+     */
+    createShortMethods('get', 'delete', 'head', 'jsonp');
+
+    /**
+     * @ngdoc method
+     * @name $http#post
+     *
+     * @description
+     * Shortcut method to perform `POST` request.
+     *
+     * @param {string} url Relative or absolute URL specifying the destination of the request
+     * @param {*} data Request content
+     * @param {Object=} config Optional configuration object
+     * @returns {HttpPromise} Future object
+     */
+
+    /**
+     * @ngdoc method
+     * @name $http#put
+     *
+     * @description
+     * Shortcut method to perform `PUT` request.
+     *
+     * @param {string} url Relative or absolute URL specifying the destination of the request
+     * @param {*} data Request content
+     * @param {Object=} config Optional configuration object
+     * @returns {HttpPromise} Future object
+     */
+
+     /**
+      * @ngdoc method
+      * @name $http#patch
+      *
+      * @description
+      * Shortcut method to perform `PATCH` request.
+      *
+      * @param {string} url Relative or absolute URL specifying the destination of the request
+      * @param {*} data Request content
+      * @param {Object=} config Optional configuration object
+      * @returns {HttpPromise} Future object
+      */
+    createShortMethodsWithData('post', 'put', 'patch');
+
+        /**
+         * @ngdoc property
+         * @name $http#defaults
+         *
+         * @description
+         * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of
+         * default headers, withCredentials as well as request and response transformations.
+         *
+         * See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above.
+         */
+    $http.defaults = defaults;
+
+
+    return $http;
+
+
+    function createShortMethods(names) {
+      forEach(arguments, function(name) {
+        $http[name] = function(url, config) {
+          return $http(extend({}, config || {}, {
+            method: name,
+            url: url
+          }));
+        };
+      });
+    }
+
+
+    function createShortMethodsWithData(name) {
+      forEach(arguments, function(name) {
+        $http[name] = function(url, data, config) {
+          return $http(extend({}, config || {}, {
+            method: name,
+            url: url,
+            data: data
+          }));
+        };
+      });
+    }
+
+
+    /**
+     * Makes the request.
+     *
+     * !!! ACCESSES CLOSURE VARS:
+     * $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests
+     */
+    function sendReq(config, reqData) {
+      var deferred = $q.defer(),
+          promise = deferred.promise,
+          cache,
+          cachedResp,
+          reqHeaders = config.headers,
+          isJsonp = lowercase(config.method) === 'jsonp',
+          url = config.url;
+
+      if (isJsonp) {
+        // JSONP is a pretty sensitive operation where we're allowing a script to have full access to
+        // our DOM and JS space.  So we require that the URL satisfies SCE.RESOURCE_URL.
+        url = $sce.getTrustedResourceUrl(url);
+      } else if (!isString(url)) {
+        // If it is not a string then the URL must be a $sce trusted object
+        url = $sce.valueOf(url);
+      }
+
+      url = buildUrl(url, config.paramSerializer(config.params));
+
+      if (isJsonp) {
+        // Check the url and add the JSONP callback placeholder
+        url = sanitizeJsonpCallbackParam(url, config.jsonpCallbackParam);
+      }
+
+      $http.pendingRequests.push(config);
+      promise.then(removePendingReq, removePendingReq);
+
+      if ((config.cache || defaults.cache) && config.cache !== false &&
+          (config.method === 'GET' || config.method === 'JSONP')) {
+        cache = isObject(config.cache) ? config.cache
+            : isObject(/** @type {?} */ (defaults).cache)
+              ? /** @type {?} */ (defaults).cache
+              : defaultCache;
+      }
+
+      if (cache) {
+        cachedResp = cache.get(url);
+        if (isDefined(cachedResp)) {
+          if (isPromiseLike(cachedResp)) {
+            // cached request has already been sent, but there is no response yet
+            cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult);
+          } else {
+            // serving from cache
+            if (isArray(cachedResp)) {
+              resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3]);
+            } else {
+              resolvePromise(cachedResp, 200, {}, 'OK');
+            }
+          }
+        } else {
+          // put the promise for the non-transformed response into cache as a placeholder
+          cache.put(url, promise);
+        }
+      }
+
+
+      // if we won't have the response in cache, set the xsrf headers and
+      // send the request to the backend
+      if (isUndefined(cachedResp)) {
+        var xsrfValue = urlIsSameOrigin(config.url)
+            ? $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName]
+            : undefined;
+        if (xsrfValue) {
+          reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
+        }
+
+        $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
+            config.withCredentials, config.responseType,
+            createApplyHandlers(config.eventHandlers),
+            createApplyHandlers(config.uploadEventHandlers));
+      }
+
+      return promise;
+
+      function createApplyHandlers(eventHandlers) {
+        if (eventHandlers) {
+          var applyHandlers = {};
+          forEach(eventHandlers, function(eventHandler, key) {
+            applyHandlers[key] = function(event) {
+              if (useApplyAsync) {
+                $rootScope.$applyAsync(callEventHandler);
+              } else if ($rootScope.$$phase) {
+                callEventHandler();
+              } else {
+                $rootScope.$apply(callEventHandler);
+              }
+
+              function callEventHandler() {
+                eventHandler(event);
+              }
+            };
+          });
+          return applyHandlers;
+        }
+      }
+
+
+      /**
+       * Callback registered to $httpBackend():
+       *  - caches the response if desired
+       *  - resolves the raw $http promise
+       *  - calls $apply
+       */
+      function done(status, response, headersString, statusText) {
+        if (cache) {
+          if (isSuccess(status)) {
+            cache.put(url, [status, response, parseHeaders(headersString), statusText]);
+          } else {
+            // remove promise from the cache
+            cache.remove(url);
+          }
+        }
+
+        function resolveHttpPromise() {
+          resolvePromise(response, status, headersString, statusText);
+        }
+
+        if (useApplyAsync) {
+          $rootScope.$applyAsync(resolveHttpPromise);
+        } else {
+          resolveHttpPromise();
+          if (!$rootScope.$$phase) $rootScope.$apply();
+        }
+      }
+
+
+      /**
+       * Resolves the raw $http promise.
+       */
+      function resolvePromise(response, status, headers, statusText) {
+        //status: HTTP response status code, 0, -1 (aborted by timeout / promise)
+        status = status >= -1 ? status : 0;
+
+        (isSuccess(status) ? deferred.resolve : deferred.reject)({
+          data: response,
+          status: status,
+          headers: headersGetter(headers),
+          config: config,
+          statusText: statusText
+        });
+      }
+
+      function resolvePromiseWithResult(result) {
+        resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText);
+      }
+
+      function removePendingReq() {
+        var idx = $http.pendingRequests.indexOf(config);
+        if (idx !== -1) $http.pendingRequests.splice(idx, 1);
+      }
+    }
+
+
+    function buildUrl(url, serializedParams) {
+      if (serializedParams.length > 0) {
+        url += ((url.indexOf('?') === -1) ? '?' : '&') + serializedParams;
+      }
+      return url;
+    }
+
+    function sanitizeJsonpCallbackParam(url, key) {
+      if (/[&?][^=]+=JSON_CALLBACK/.test(url)) {
+        // Throw if the url already contains a reference to JSON_CALLBACK
+        throw $httpMinErr('badjsonp', 'Illegal use of JSON_CALLBACK in url, "{0}"', url);
+      }
+
+      var callbackParamRegex = new RegExp('[&?]' + key + '=');
+      if (callbackParamRegex.test(url)) {
+        // Throw if the callback param was already provided
+        throw $httpMinErr('badjsonp', 'Illegal use of callback param, "{0}", in url, "{1}"', key, url);
+      }
+
+      // Add in the JSON_CALLBACK callback param value
+      url += ((url.indexOf('?') === -1) ? '?' : '&') + key + '=JSON_CALLBACK';
+
+      return url;
+    }
+  }];
+}
+
+/**
+ * @ngdoc service
+ * @name $xhrFactory
+ * @this
+ *
+ * @description
+ * Factory function used to create XMLHttpRequest objects.
+ *
+ * Replace or decorate this service to create your own custom XMLHttpRequest objects.
+ *
+ * ```
+ * angular.module('myApp', [])
+ * .factory('$xhrFactory', function() {
+ *   return function createXhr(method, url) {
+ *     return new window.XMLHttpRequest({mozSystem: true});
+ *   };
+ * });
+ * ```
+ *
+ * @param {string} method HTTP method of the request (GET, POST, PUT, ..)
+ * @param {string} url URL of the request.
+ */
+function $xhrFactoryProvider() {
+  this.$get = function() {
+    return function createXhr() {
+      return new window.XMLHttpRequest();
+    };
+  };
+}
+
+/**
+ * @ngdoc service
+ * @name $httpBackend
+ * @requires $jsonpCallbacks
+ * @requires $document
+ * @requires $xhrFactory
+ * @this
+ *
+ * @description
+ * HTTP backend used by the {@link ng.$http service} that delegates to
+ * XMLHttpRequest object or JSONP and deals with browser incompatibilities.
+ *
+ * You should never need to use this service directly, instead use the higher-level abstractions:
+ * {@link ng.$http $http} or {@link ngResource.$resource $resource}.
+ *
+ * During testing this implementation is swapped with {@link ngMock.$httpBackend mock
+ * $httpBackend} which can be trained with responses.
+ */
+function $HttpBackendProvider() {
+  this.$get = ['$browser', '$jsonpCallbacks', '$document', '$xhrFactory', function($browser, $jsonpCallbacks, $document, $xhrFactory) {
+    return createHttpBackend($browser, $xhrFactory, $browser.defer, $jsonpCallbacks, $document[0]);
+  }];
+}
+
+function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {
+  // TODO(vojta): fix the signature
+  return function(method, url, post, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers) {
+    url = url || $browser.url();
+
+    if (lowercase(method) === 'jsonp') {
+      var callbackPath = callbacks.createCallback(url);
+      var jsonpDone = jsonpReq(url, callbackPath, function(status, text) {
+        // jsonpReq only ever sets status to 200 (OK), 404 (ERROR) or -1 (WAITING)
+        var response = (status === 200) && callbacks.getResponse(callbackPath);
+        completeRequest(callback, status, response, '', text);
+        callbacks.removeCallback(callbackPath);
+      });
+    } else {
+
+      var xhr = createXhr(method, url);
+
+      xhr.open(method, url, true);
+      forEach(headers, function(value, key) {
+        if (isDefined(value)) {
+            xhr.setRequestHeader(key, value);
+        }
+      });
+
+      xhr.onload = function requestLoaded() {
+        var statusText = xhr.statusText || '';
+
+        // responseText is the old-school way of retrieving response (supported by IE9)
+        // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
+        var response = ('response' in xhr) ? xhr.response : xhr.responseText;
+
+        // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
+        var status = xhr.status === 1223 ? 204 : xhr.status;
+
+        // fix status code when it is 0 (0 status is undocumented).
+        // Occurs when accessing file resources or on Android 4.1 stock browser
+        // while retrieving files from application cache.
+        if (status === 0) {
+          status = response ? 200 : urlResolve(url).protocol === 'file' ? 404 : 0;
+        }
+
+        completeRequest(callback,
+            status,
+            response,
+            xhr.getAllResponseHeaders(),
+            statusText);
+      };
+
+      var requestError = function() {
+        // The response is always empty
+        // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error
+        completeRequest(callback, -1, null, null, '');
+      };
+
+      xhr.onerror = requestError;
+      xhr.onabort = requestError;
+      xhr.ontimeout = requestError;
+
+      forEach(eventHandlers, function(value, key) {
+          xhr.addEventListener(key, value);
+      });
+
+      forEach(uploadEventHandlers, function(value, key) {
+        xhr.upload.addEventListener(key, value);
+      });
+
+      if (withCredentials) {
+        xhr.withCredentials = true;
+      }
+
+      if (responseType) {
+        try {
+          xhr.responseType = responseType;
+        } catch (e) {
+          // WebKit added support for the json responseType value on 09/03/2013
+          // https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
+          // known to throw when setting the value "json" as the response type. Other older
+          // browsers implementing the responseType
+          //
+          // The json response type can be ignored if not supported, because JSON payloads are
+          // parsed on the client-side regardless.
+          if (responseType !== 'json') {
+            throw e;
+          }
+        }
+      }
+
+      xhr.send(isUndefined(post) ? null : post);
+    }
+
+    if (timeout > 0) {
+      var timeoutId = $browserDefer(timeoutRequest, timeout);
+    } else if (isPromiseLike(timeout)) {
+      timeout.then(timeoutRequest);
+    }
+
+
+    function timeoutRequest() {
+      if (jsonpDone) {
+        jsonpDone();
+      }
+      if (xhr) {
+        xhr.abort();
+      }
+    }
+
+    function completeRequest(callback, status, response, headersString, statusText) {
+      // cancel timeout and subsequent timeout promise resolution
+      if (isDefined(timeoutId)) {
+        $browserDefer.cancel(timeoutId);
+      }
+      jsonpDone = xhr = null;
+
+      callback(status, response, headersString, statusText);
+    }
+  };
+
+  function jsonpReq(url, callbackPath, done) {
+    url = url.replace('JSON_CALLBACK', callbackPath);
+    // we can't use jQuery/jqLite here because jQuery does crazy stuff with script elements, e.g.:
+    // - fetches local scripts via XHR and evals them
+    // - adds and immediately removes script elements from the document
+    var script = rawDocument.createElement('script'), callback = null;
+    script.type = 'text/javascript';
+    script.src = url;
+    script.async = true;
+
+    callback = function(event) {
+      script.removeEventListener('load', callback);
+      script.removeEventListener('error', callback);
+      rawDocument.body.removeChild(script);
+      script = null;
+      var status = -1;
+      var text = 'unknown';
+
+      if (event) {
+        if (event.type === 'load' && !callbacks.wasCalled(callbackPath)) {
+          event = { type: 'error' };
+        }
+        text = event.type;
+        status = event.type === 'error' ? 404 : 200;
+      }
+
+      if (done) {
+        done(status, text);
+      }
+    };
+
+    script.addEventListener('load', callback);
+    script.addEventListener('error', callback);
+    rawDocument.body.appendChild(script);
+    return callback;
+  }
+}
+
+var $interpolateMinErr = angular.$interpolateMinErr = minErr('$interpolate');
+$interpolateMinErr.throwNoconcat = function(text) {
+  throw $interpolateMinErr('noconcat',
+      'Error while interpolating: {0}\nStrict Contextual Escaping disallows ' +
+      'interpolations that concatenate multiple expressions when a trusted value is ' +
+      'required.  See http://docs.angularjs.org/api/ng.$sce', text);
+};
+
+$interpolateMinErr.interr = function(text, err) {
+  return $interpolateMinErr('interr', 'Can\'t interpolate: {0}\n{1}', text, err.toString());
+};
+
+/**
+ * @ngdoc provider
+ * @name $interpolateProvider
+ * @this
+ *
+ * @description
+ *
+ * Used for configuring the interpolation markup. Defaults to `{{` and `}}`.
+ *
+ * <div class="alert alert-danger">
+ * This feature is sometimes used to mix different markup languages, e.g. to wrap an Angular
+ * template within a Python Jinja template (or any other template language). Mixing templating
+ * languages is **very dangerous**. The embedding template language will not safely escape Angular
+ * expressions, so any user-controlled values in the template will cause Cross Site Scripting (XSS)
+ * security bugs!
+ * </div>
+ *
+ * @example
+<example name="custom-interpolation-markup" module="customInterpolationApp">
+<file name="index.html">
+<script>
+  var customInterpolationApp = angular.module('customInterpolationApp', []);
+
+  customInterpolationApp.config(function($interpolateProvider) {
+    $interpolateProvider.startSymbol('//');
+    $interpolateProvider.endSymbol('//');
+  });
+
+
+  customInterpolationApp.controller('DemoController', function() {
+      this.label = "This binding is brought you by // interpolation symbols.";
+  });
+</script>
+<div ng-controller="DemoController as demo">
+    //demo.label//
+</div>
+</file>
+<file name="protractor.js" type="protractor">
+  it('should interpolate binding with custom symbols', function() {
+    expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.');
+  });
+</file>
+</example>
+ */
+function $InterpolateProvider() {
+  var startSymbol = '{{';
+  var endSymbol = '}}';
+
+  /**
+   * @ngdoc method
+   * @name $interpolateProvider#startSymbol
+   * @description
+   * Symbol to denote start of expression in the interpolated string. Defaults to `{{`.
+   *
+   * @param {string=} value new value to set the starting symbol to.
+   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
+   */
+  this.startSymbol = function(value) {
+    if (value) {
+      startSymbol = value;
+      return this;
+    } else {
+      return startSymbol;
+    }
+  };
+
+  /**
+   * @ngdoc method
+   * @name $interpolateProvider#endSymbol
+   * @description
+   * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
+   *
+   * @param {string=} value new value to set the ending symbol to.
+   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
+   */
+  this.endSymbol = function(value) {
+    if (value) {
+      endSymbol = value;
+      return this;
+    } else {
+      return endSymbol;
+    }
+  };
+
+
+  this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) {
+    var startSymbolLength = startSymbol.length,
+        endSymbolLength = endSymbol.length,
+        escapedStartRegexp = new RegExp(startSymbol.replace(/./g, escape), 'g'),
+        escapedEndRegexp = new RegExp(endSymbol.replace(/./g, escape), 'g');
+
+    function escape(ch) {
+      return '\\\\\\' + ch;
+    }
+
+    function unescapeText(text) {
+      return text.replace(escapedStartRegexp, startSymbol).
+        replace(escapedEndRegexp, endSymbol);
+    }
+
+    // TODO: this is the same as the constantWatchDelegate in parse.js
+    function constantWatchDelegate(scope, listener, objectEquality, constantInterp) {
+      var unwatch = scope.$watch(function constantInterpolateWatch(scope) {
+        unwatch();
+        return constantInterp(scope);
+      }, listener, objectEquality);
+      return unwatch;
+    }
+
+    /**
+     * @ngdoc service
+     * @name $interpolate
+     * @kind function
+     *
+     * @requires $parse
+     * @requires $sce
+     *
+     * @description
+     *
+     * Compiles a string with markup into an interpolation function. This service is used by the
+     * HTML {@link ng.$compile $compile} service for data binding. See
+     * {@link ng.$interpolateProvider $interpolateProvider} for configuring the
+     * interpolation markup.
+     *
+     *
+     * ```js
+     *   var $interpolate = ...; // injected
+     *   var exp = $interpolate('Hello {{name | uppercase}}!');
+     *   expect(exp({name:'Angular'})).toEqual('Hello ANGULAR!');
+     * ```
+     *
+     * `$interpolate` takes an optional fourth argument, `allOrNothing`. If `allOrNothing` is
+     * `true`, the interpolation function will return `undefined` unless all embedded expressions
+     * evaluate to a value other than `undefined`.
+     *
+     * ```js
+     *   var $interpolate = ...; // injected
+     *   var context = {greeting: 'Hello', name: undefined };
+     *
+     *   // default "forgiving" mode
+     *   var exp = $interpolate('{{greeting}} {{name}}!');
+     *   expect(exp(context)).toEqual('Hello !');
+     *
+     *   // "allOrNothing" mode
+     *   exp = $interpolate('{{greeting}} {{name}}!', false, null, true);
+     *   expect(exp(context)).toBeUndefined();
+     *   context.name = 'Angular';
+     *   expect(exp(context)).toEqual('Hello Angular!');
+     * ```
+     *
+     * `allOrNothing` is useful for interpolating URLs. `ngSrc` and `ngSrcset` use this behavior.
+     *
+     * #### Escaped Interpolation
+     * $interpolate provides a mechanism for escaping interpolation markers. Start and end markers
+     * can be escaped by preceding each of their characters with a REVERSE SOLIDUS U+005C (backslash).
+     * It will be rendered as a regular start/end marker, and will not be interpreted as an expression
+     * or binding.
+     *
+     * This enables web-servers to prevent script injection attacks and defacing attacks, to some
+     * degree, while also enabling code examples to work without relying on the
+     * {@link ng.directive:ngNonBindable ngNonBindable} directive.
+     *
+     * **For security purposes, it is strongly encouraged that web servers escape user-supplied data,
+     * replacing angle brackets (&lt;, &gt;) with &amp;lt; and &amp;gt; respectively, and replacing all
+     * interpolation start/end markers with their escaped counterparts.**
+     *
+     * Escaped interpolation markers are only replaced with the actual interpolation markers in rendered
+     * output when the $interpolate service processes the text. So, for HTML elements interpolated
+     * by {@link ng.$compile $compile}, or otherwise interpolated with the `mustHaveExpression` parameter
+     * set to `true`, the interpolated text must contain an unescaped interpolation expression. As such,
+     * this is typically useful only when user-data is used in rendering a template from the server, or
+     * when otherwise untrusted data is used by a directive.
+     *
+     * <example name="interpolation">
+     *  <file name="index.html">
+     *    <div ng-init="username='A user'">
+     *      <p ng-init="apptitle='Escaping demo'">{{apptitle}}: \{\{ username = "defaced value"; \}\}
+     *        </p>
+     *      <p><strong>{{username}}</strong> attempts to inject code which will deface the
+     *        application, but fails to accomplish their task, because the server has correctly
+     *        escaped the interpolation start/end markers with REVERSE SOLIDUS U+005C (backslash)
+     *        characters.</p>
+     *      <p>Instead, the result of the attempted script injection is visible, and can be removed
+     *        from the database by an administrator.</p>
+     *    </div>
+     *  </file>
+     * </example>
+     *
+     * @knownIssue
+     * It is currently not possible for an interpolated expression to contain the interpolation end
+     * symbol. For example, `{{ '}}' }}` will be incorrectly interpreted as `{{ ' }}` + `' }}`, i.e.
+     * an interpolated expression consisting of a single-quote (`'`) and the `' }}` string.
+     *
+     * @knownIssue
+     * All directives and components must use the standard `{{` `}}` interpolation symbols
+     * in their templates. If you change the application interpolation symbols the {@link $compile}
+     * service will attempt to denormalize the standard symbols to the custom symbols.
+     * The denormalization process is not clever enough to know not to replace instances of the standard
+     * symbols where they would not normally be treated as interpolation symbols. For example in the following
+     * code snippet the closing braces of the literal object will get incorrectly denormalized:
+     *
+     * ```
+     * <div data-context='{"context":{"id":3,"type":"page"}}">
+     * ```
+     *
+     * The workaround is to ensure that such instances are separated by whitespace:
+     * ```
+     * <div data-context='{"context":{"id":3,"type":"page"} }">
+     * ```
+     *
+     * See https://github.com/angular/angular.js/pull/14610#issuecomment-219401099 for more information.
+     *
+     * @param {string} text The text with markup to interpolate.
+     * @param {boolean=} mustHaveExpression if set to true then the interpolation string must have
+     *    embedded expression in order to return an interpolation function. Strings with no
+     *    embedded expression will return null for the interpolation function.
+     * @param {string=} trustedContext when provided, the returned function passes the interpolated
+     *    result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult,
+     *    trustedContext)} before returning it.  Refer to the {@link ng.$sce $sce} service that
+     *    provides Strict Contextual Escaping for details.
+     * @param {boolean=} allOrNothing if `true`, then the returned function returns undefined
+     *    unless all embedded expressions evaluate to a value other than `undefined`.
+     * @returns {function(context)} an interpolation function which is used to compute the
+     *    interpolated string. The function has these parameters:
+     *
+     * - `context`: evaluation context for all expressions embedded in the interpolated text
+     */
+    function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {
+      // Provide a quick exit and simplified result function for text with no interpolation
+      if (!text.length || text.indexOf(startSymbol) === -1) {
+        var constantInterp;
+        if (!mustHaveExpression) {
+          var unescapedText = unescapeText(text);
+          constantInterp = valueFn(unescapedText);
+          constantInterp.exp = text;
+          constantInterp.expressions = [];
+          constantInterp.$$watchDelegate = constantWatchDelegate;
+        }
+        return constantInterp;
+      }
+
+      allOrNothing = !!allOrNothing;
+      var startIndex,
+          endIndex,
+          index = 0,
+          expressions = [],
+          parseFns = [],
+          textLength = text.length,
+          exp,
+          concat = [],
+          expressionPositions = [];
+
+      while (index < textLength) {
+        if (((startIndex = text.indexOf(startSymbol, index)) !== -1) &&
+             ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) !== -1)) {
+          if (index !== startIndex) {
+            concat.push(unescapeText(text.substring(index, startIndex)));
+          }
+          exp = text.substring(startIndex + startSymbolLength, endIndex);
+          expressions.push(exp);
+          parseFns.push($parse(exp, parseStringifyInterceptor));
+          index = endIndex + endSymbolLength;
+          expressionPositions.push(concat.length);
+          concat.push('');
+        } else {
+          // we did not find an interpolation, so we have to add the remainder to the separators array
+          if (index !== textLength) {
+            concat.push(unescapeText(text.substring(index)));
+          }
+          break;
+        }
+      }
+
+      // Concatenating expressions makes it hard to reason about whether some combination of
+      // concatenated values are unsafe to use and could easily lead to XSS.  By requiring that a
+      // single expression be used for iframe[src], object[src], etc., we ensure that the value
+      // that's used is assigned or constructed by some JS code somewhere that is more testable or
+      // make it obvious that you bound the value to some user controlled value.  This helps reduce
+      // the load when auditing for XSS issues.
+      if (trustedContext && concat.length > 1) {
+          $interpolateMinErr.throwNoconcat(text);
+      }
+
+      if (!mustHaveExpression || expressions.length) {
+        var compute = function(values) {
+          for (var i = 0, ii = expressions.length; i < ii; i++) {
+            if (allOrNothing && isUndefined(values[i])) return;
+            concat[expressionPositions[i]] = values[i];
+          }
+          return concat.join('');
+        };
+
+        var getValue = function(value) {
+          return trustedContext ?
+            $sce.getTrusted(trustedContext, value) :
+            $sce.valueOf(value);
+        };
+
+        return extend(function interpolationFn(context) {
+            var i = 0;
+            var ii = expressions.length;
+            var values = new Array(ii);
+
+            try {
+              for (; i < ii; i++) {
+                values[i] = parseFns[i](context);
+              }
+
+              return compute(values);
+            } catch (err) {
+              $exceptionHandler($interpolateMinErr.interr(text, err));
+            }
+
+          }, {
+          // all of these properties are undocumented for now
+          exp: text, //just for compatibility with regular watchers created via $watch
+          expressions: expressions,
+          $$watchDelegate: function(scope, listener) {
+            var lastValue;
+            return scope.$watchGroup(parseFns, /** @this */ function interpolateFnWatcher(values, oldValues) {
+              var currValue = compute(values);
+              if (isFunction(listener)) {
+                listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope);
+              }
+              lastValue = currValue;
+            });
+          }
+        });
+      }
+
+      function parseStringifyInterceptor(value) {
+        try {
+          value = getValue(value);
+          return allOrNothing && !isDefined(value) ? value : stringify(value);
+        } catch (err) {
+          $exceptionHandler($interpolateMinErr.interr(text, err));
+        }
+      }
+    }
+
+
+    /**
+     * @ngdoc method
+     * @name $interpolate#startSymbol
+     * @description
+     * Symbol to denote the start of expression in the interpolated string. Defaults to `{{`.
+     *
+     * Use {@link ng.$interpolateProvider#startSymbol `$interpolateProvider.startSymbol`} to change
+     * the symbol.
+     *
+     * @returns {string} start symbol.
+     */
+    $interpolate.startSymbol = function() {
+      return startSymbol;
+    };
+
+
+    /**
+     * @ngdoc method
+     * @name $interpolate#endSymbol
+     * @description
+     * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
+     *
+     * Use {@link ng.$interpolateProvider#endSymbol `$interpolateProvider.endSymbol`} to change
+     * the symbol.
+     *
+     * @returns {string} end symbol.
+     */
+    $interpolate.endSymbol = function() {
+      return endSymbol;
+    };
+
+    return $interpolate;
+  }];
+}
+
+/** @this */
+function $IntervalProvider() {
+  this.$get = ['$rootScope', '$window', '$q', '$$q', '$browser',
+       function($rootScope,   $window,   $q,   $$q,   $browser) {
+    var intervals = {};
+
+
+     /**
+      * @ngdoc service
+      * @name $interval
+      *
+      * @description
+      * Angular's wrapper for `window.setInterval`. The `fn` function is executed every `delay`
+      * milliseconds.
+      *
+      * The return value of registering an interval function is a promise. This promise will be
+      * notified upon each tick of the interval, and will be resolved after `count` iterations, or
+      * run indefinitely if `count` is not defined. The value of the notification will be the
+      * number of iterations that have run.
+      * To cancel an interval, call `$interval.cancel(promise)`.
+      *
+      * In tests you can use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
+      * move forward by `millis` milliseconds and trigger any functions scheduled to run in that
+      * time.
+      *
+      * <div class="alert alert-warning">
+      * **Note**: Intervals created by this service must be explicitly destroyed when you are finished
+      * with them.  In particular they are not automatically destroyed when a controller's scope or a
+      * directive's element are destroyed.
+      * You should take this into consideration and make sure to always cancel the interval at the
+      * appropriate moment.  See the example below for more details on how and when to do this.
+      * </div>
+      *
+      * @param {function()} fn A function that should be called repeatedly. If no additional arguments
+      *   are passed (see below), the function is called with the current iteration count.
+      * @param {number} delay Number of milliseconds between each function call.
+      * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
+      *   indefinitely.
+      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
+      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
+      * @param {...*=} Pass additional parameters to the executed function.
+      * @returns {promise} A promise which will be notified on each iteration.
+      *
+      * @example
+      * <example module="intervalExample" name="interval-service">
+      * <file name="index.html">
+      *   <script>
+      *     angular.module('intervalExample', [])
+      *       .controller('ExampleController', ['$scope', '$interval',
+      *         function($scope, $interval) {
+      *           $scope.format = 'M/d/yy h:mm:ss a';
+      *           $scope.blood_1 = 100;
+      *           $scope.blood_2 = 120;
+      *
+      *           var stop;
+      *           $scope.fight = function() {
+      *             // Don't start a new fight if we are already fighting
+      *             if ( angular.isDefined(stop) ) return;
+      *
+      *             stop = $interval(function() {
+      *               if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
+      *                 $scope.blood_1 = $scope.blood_1 - 3;
+      *                 $scope.blood_2 = $scope.blood_2 - 4;
+      *               } else {
+      *                 $scope.stopFight();
+      *               }
+      *             }, 100);
+      *           };
+      *
+      *           $scope.stopFight = function() {
+      *             if (angular.isDefined(stop)) {
+      *               $interval.cancel(stop);
+      *               stop = undefined;
+      *             }
+      *           };
+      *
+      *           $scope.resetFight = function() {
+      *             $scope.blood_1 = 100;
+      *             $scope.blood_2 = 120;
+      *           };
+      *
+      *           $scope.$on('$destroy', function() {
+      *             // Make sure that the interval is destroyed too
+      *             $scope.stopFight();
+      *           });
+      *         }])
+      *       // Register the 'myCurrentTime' directive factory method.
+      *       // We inject $interval and dateFilter service since the factory method is DI.
+      *       .directive('myCurrentTime', ['$interval', 'dateFilter',
+      *         function($interval, dateFilter) {
+      *           // return the directive link function. (compile function not needed)
+      *           return function(scope, element, attrs) {
+      *             var format,  // date format
+      *                 stopTime; // so that we can cancel the time updates
+      *
+      *             // used to update the UI
+      *             function updateTime() {
+      *               element.text(dateFilter(new Date(), format));
+      *             }
+      *
+      *             // watch the expression, and update the UI on change.
+      *             scope.$watch(attrs.myCurrentTime, function(value) {
+      *               format = value;
+      *               updateTime();
+      *             });
+      *
+      *             stopTime = $interval(updateTime, 1000);
+      *
+      *             // listen on DOM destroy (removal) event, and cancel the next UI update
+      *             // to prevent updating time after the DOM element was removed.
+      *             element.on('$destroy', function() {
+      *               $interval.cancel(stopTime);
+      *             });
+      *           }
+      *         }]);
+      *   </script>
+      *
+      *   <div>
+      *     <div ng-controller="ExampleController">
+      *       <label>Date format: <input ng-model="format"></label> <hr/>
+      *       Current time is: <span my-current-time="format"></span>
+      *       <hr/>
+      *       Blood 1 : <font color='red'>{{blood_1}}</font>
+      *       Blood 2 : <font color='red'>{{blood_2}}</font>
+      *       <button type="button" data-ng-click="fight()">Fight</button>
+      *       <button type="button" data-ng-click="stopFight()">StopFight</button>
+      *       <button type="button" data-ng-click="resetFight()">resetFight</button>
+      *     </div>
+      *   </div>
+      *
+      * </file>
+      * </example>
+      */
+    function interval(fn, delay, count, invokeApply) {
+      var hasParams = arguments.length > 4,
+          args = hasParams ? sliceArgs(arguments, 4) : [],
+          setInterval = $window.setInterval,
+          clearInterval = $window.clearInterval,
+          iteration = 0,
+          skipApply = (isDefined(invokeApply) && !invokeApply),
+          deferred = (skipApply ? $$q : $q).defer(),
+          promise = deferred.promise;
+
+      count = isDefined(count) ? count : 0;
+
+      promise.$$intervalId = setInterval(function tick() {
+        if (skipApply) {
+          $browser.defer(callback);
+        } else {
+          $rootScope.$evalAsync(callback);
+        }
+        deferred.notify(iteration++);
+
+        if (count > 0 && iteration >= count) {
+          deferred.resolve(iteration);
+          clearInterval(promise.$$intervalId);
+          delete intervals[promise.$$intervalId];
+        }
+
+        if (!skipApply) $rootScope.$apply();
+
+      }, delay);
+
+      intervals[promise.$$intervalId] = deferred;
+
+      return promise;
+
+      function callback() {
+        if (!hasParams) {
+          fn(iteration);
+        } else {
+          fn.apply(null, args);
+        }
+      }
+    }
+
+
+     /**
+      * @ngdoc method
+      * @name $interval#cancel
+      *
+      * @description
+      * Cancels a task associated with the `promise`.
+      *
+      * @param {Promise=} promise returned by the `$interval` function.
+      * @returns {boolean} Returns `true` if the task was successfully canceled.
+      */
+    interval.cancel = function(promise) {
+      if (promise && promise.$$intervalId in intervals) {
+        // Interval cancels should not report as unhandled promise.
+        intervals[promise.$$intervalId].promise.catch(noop);
+        intervals[promise.$$intervalId].reject('canceled');
+        $window.clearInterval(promise.$$intervalId);
+        delete intervals[promise.$$intervalId];
+        return true;
+      }
+      return false;
+    };
+
+    return interval;
+  }];
+}
+
+/**
+ * @ngdoc service
+ * @name $jsonpCallbacks
+ * @requires $window
+ * @description
+ * This service handles the lifecycle of callbacks to handle JSONP requests.
+ * Override this service if you wish to customise where the callbacks are stored and
+ * how they vary compared to the requested url.
+ */
+var $jsonpCallbacksProvider = /** @this */ function() {
+  this.$get = function() {
+    var callbacks = angular.callbacks;
+    var callbackMap = {};
+
+    function createCallback(callbackId) {
+      var callback = function(data) {
+        callback.data = data;
+        callback.called = true;
+      };
+      callback.id = callbackId;
+      return callback;
+    }
+
+    return {
+      /**
+       * @ngdoc method
+       * @name $jsonpCallbacks#createCallback
+       * @param {string} url the url of the JSONP request
+       * @returns {string} the callback path to send to the server as part of the JSONP request
+       * @description
+       * {@link $httpBackend} calls this method to create a callback and get hold of the path to the callback
+       * to pass to the server, which will be used to call the callback with its payload in the JSONP response.
+       */
+      createCallback: function(url) {
+        var callbackId = '_' + (callbacks.$$counter++).toString(36);
+        var callbackPath = 'angular.callbacks.' + callbackId;
+        var callback = createCallback(callbackId);
+        callbackMap[callbackPath] = callbacks[callbackId] = callback;
+        return callbackPath;
+      },
+      /**
+       * @ngdoc method
+       * @name $jsonpCallbacks#wasCalled
+       * @param {string} callbackPath the path to the callback that was sent in the JSONP request
+       * @returns {boolean} whether the callback has been called, as a result of the JSONP response
+       * @description
+       * {@link $httpBackend} calls this method to find out whether the JSONP response actually called the
+       * callback that was passed in the request.
+       */
+      wasCalled: function(callbackPath) {
+        return callbackMap[callbackPath].called;
+      },
+      /**
+       * @ngdoc method
+       * @name $jsonpCallbacks#getResponse
+       * @param {string} callbackPath the path to the callback that was sent in the JSONP request
+       * @returns {*} the data received from the response via the registered callback
+       * @description
+       * {@link $httpBackend} calls this method to get hold of the data that was provided to the callback
+       * in the JSONP response.
+       */
+      getResponse: function(callbackPath) {
+        return callbackMap[callbackPath].data;
+      },
+      /**
+       * @ngdoc method
+       * @name $jsonpCallbacks#removeCallback
+       * @param {string} callbackPath the path to the callback that was sent in the JSONP request
+       * @description
+       * {@link $httpBackend} calls this method to remove the callback after the JSONP request has
+       * completed or timed-out.
+       */
+      removeCallback: function(callbackPath) {
+        var callback = callbackMap[callbackPath];
+        delete callbacks[callback.id];
+        delete callbackMap[callbackPath];
+      }
+    };
+  };
+};
+
+/**
+ * @ngdoc service
+ * @name $locale
+ *
+ * @description
+ * $locale service provides localization rules for various Angular components. As of right now the
+ * only public api is:
+ *
+ * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
+ */
+
+var PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/,
+    DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};
+var $locationMinErr = minErr('$location');
+
+
+/**
+ * Encode path using encodeUriSegment, ignoring forward slashes
+ *
+ * @param {string} path Path to encode
+ * @returns {string}
+ */
+function encodePath(path) {
+  var segments = path.split('/'),
+      i = segments.length;
+
+  while (i--) {
+    segments[i] = encodeUriSegment(segments[i]);
+  }
+
+  return segments.join('/');
+}
+
+function parseAbsoluteUrl(absoluteUrl, locationObj) {
+  var parsedUrl = urlResolve(absoluteUrl);
+
+  locationObj.$$protocol = parsedUrl.protocol;
+  locationObj.$$host = parsedUrl.hostname;
+  locationObj.$$port = toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
+}
+
+var DOUBLE_SLASH_REGEX = /^\s*[\\/]{2,}/;
+function parseAppUrl(url, locationObj) {
+
+  if (DOUBLE_SLASH_REGEX.test(url)) {
+    throw $locationMinErr('badpath', 'Invalid url "{0}".', url);
+  }
+
+  var prefixed = (url.charAt(0) !== '/');
+  if (prefixed) {
+    url = '/' + url;
+  }
+  var match = urlResolve(url);
+  locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
+      match.pathname.substring(1) : match.pathname);
+  locationObj.$$search = parseKeyValue(match.search);
+  locationObj.$$hash = decodeURIComponent(match.hash);
+
+  // make sure path starts with '/';
+  if (locationObj.$$path && locationObj.$$path.charAt(0) !== '/') {
+    locationObj.$$path = '/' + locationObj.$$path;
+  }
+}
+
+function startsWith(str, search) {
+  return str.slice(0, search.length) === search;
+}
+
+/**
+ *
+ * @param {string} base
+ * @param {string} url
+ * @returns {string} returns text from `url` after `base` or `undefined` if it does not begin with
+ *                   the expected string.
+ */
+function stripBaseUrl(base, url) {
+  if (startsWith(url, base)) {
+    return url.substr(base.length);
+  }
+}
+
+
+function stripHash(url) {
+  var index = url.indexOf('#');
+  return index === -1 ? url : url.substr(0, index);
+}
+
+function trimEmptyHash(url) {
+  return url.replace(/(#.+)|#$/, '$1');
+}
+
+
+function stripFile(url) {
+  return url.substr(0, stripHash(url).lastIndexOf('/') + 1);
+}
+
+/* return the server only (scheme://host:port) */
+function serverBase(url) {
+  return url.substring(0, url.indexOf('/', url.indexOf('//') + 2));
+}
+
+
+/**
+ * LocationHtml5Url represents a URL
+ * This object is exposed as $location service when HTML5 mode is enabled and supported
+ *
+ * @constructor
+ * @param {string} appBase application base URL
+ * @param {string} appBaseNoFile application base URL stripped of any filename
+ * @param {string} basePrefix URL path prefix
+ */
+function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {
+  this.$$html5 = true;
+  basePrefix = basePrefix || '';
+  parseAbsoluteUrl(appBase, this);
+
+
+  /**
+   * Parse given HTML5 (regular) URL string into properties
+   * @param {string} url HTML5 URL
+   * @private
+   */
+  this.$$parse = function(url) {
+    var pathUrl = stripBaseUrl(appBaseNoFile, url);
+    if (!isString(pathUrl)) {
+      throw $locationMinErr('ipthprfx', 'Invalid url "{0}", missing path prefix "{1}".', url,
+          appBaseNoFile);
+    }
+
+    parseAppUrl(pathUrl, this);
+
+    if (!this.$$path) {
+      this.$$path = '/';
+    }
+
+    this.$$compose();
+  };
+
+  /**
+   * Compose url and update `absUrl` property
+   * @private
+   */
+  this.$$compose = function() {
+    var search = toKeyValue(this.$$search),
+        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
+
+    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
+    this.$$absUrl = appBaseNoFile + this.$$url.substr(1); // first char is always '/'
+
+    this.$$urlUpdatedByLocation = true;
+  };
+
+  this.$$parseLinkUrl = function(url, relHref) {
+    if (relHref && relHref[0] === '#') {
+      // special case for links to hash fragments:
+      // keep the old url and only replace the hash fragment
+      this.hash(relHref.slice(1));
+      return true;
+    }
+    var appUrl, prevAppUrl;
+    var rewrittenUrl;
+
+
+    if (isDefined(appUrl = stripBaseUrl(appBase, url))) {
+      prevAppUrl = appUrl;
+      if (basePrefix && isDefined(appUrl = stripBaseUrl(basePrefix, appUrl))) {
+        rewrittenUrl = appBaseNoFile + (stripBaseUrl('/', appUrl) || appUrl);
+      } else {
+        rewrittenUrl = appBase + prevAppUrl;
+      }
+    } else if (isDefined(appUrl = stripBaseUrl(appBaseNoFile, url))) {
+      rewrittenUrl = appBaseNoFile + appUrl;
+    } else if (appBaseNoFile === url + '/') {
+      rewrittenUrl = appBaseNoFile;
+    }
+    if (rewrittenUrl) {
+      this.$$parse(rewrittenUrl);
+    }
+    return !!rewrittenUrl;
+  };
+}
+
+
+/**
+ * LocationHashbangUrl represents URL
+ * This object is exposed as $location service when developer doesn't opt into html5 mode.
+ * It also serves as the base class for html5 mode fallback on legacy browsers.
+ *
+ * @constructor
+ * @param {string} appBase application base URL
+ * @param {string} appBaseNoFile application base URL stripped of any filename
+ * @param {string} hashPrefix hashbang prefix
+ */
+function LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) {
+
+  parseAbsoluteUrl(appBase, this);
+
+
+  /**
+   * Parse given hashbang URL into properties
+   * @param {string} url Hashbang URL
+   * @private
+   */
+  this.$$parse = function(url) {
+    var withoutBaseUrl = stripBaseUrl(appBase, url) || stripBaseUrl(appBaseNoFile, url);
+    var withoutHashUrl;
+
+    if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === '#') {
+
+      // The rest of the URL starts with a hash so we have
+      // got either a hashbang path or a plain hash fragment
+      withoutHashUrl = stripBaseUrl(hashPrefix, withoutBaseUrl);
+      if (isUndefined(withoutHashUrl)) {
+        // There was no hashbang prefix so we just have a hash fragment
+        withoutHashUrl = withoutBaseUrl;
+      }
+
+    } else {
+      // There was no hashbang path nor hash fragment:
+      // If we are in HTML5 mode we use what is left as the path;
+      // Otherwise we ignore what is left
+      if (this.$$html5) {
+        withoutHashUrl = withoutBaseUrl;
+      } else {
+        withoutHashUrl = '';
+        if (isUndefined(withoutBaseUrl)) {
+          appBase = url;
+          /** @type {?} */ (this).replace();
+        }
+      }
+    }
+
+    parseAppUrl(withoutHashUrl, this);
+
+    this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
+
+    this.$$compose();
+
+    /*
+     * In Windows, on an anchor node on documents loaded from
+     * the filesystem, the browser will return a pathname
+     * prefixed with the drive name ('/C:/path') when a
+     * pathname without a drive is set:
+     *  * a.setAttribute('href', '/foo')
+     *   * a.pathname === '/C:/foo' //true
+     *
+     * Inside of Angular, we're always using pathnames that
+     * do not include drive names for routing.
+     */
+    function removeWindowsDriveName(path, url, base) {
+      /*
+      Matches paths for file protocol on windows,
+      such as /C:/foo/bar, and captures only /foo/bar.
+      */
+      var windowsFilePathExp = /^\/[A-Z]:(\/.*)/;
+
+      var firstPathSegmentMatch;
+
+      //Get the relative path from the input URL.
+      if (startsWith(url, base)) {
+        url = url.replace(base, '');
+      }
+
+      // The input URL intentionally contains a first path segment that ends with a colon.
+      if (windowsFilePathExp.exec(url)) {
+        return path;
+      }
+
+      firstPathSegmentMatch = windowsFilePathExp.exec(path);
+      return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
+    }
+  };
+
+  /**
+   * Compose hashbang URL and update `absUrl` property
+   * @private
+   */
+  this.$$compose = function() {
+    var search = toKeyValue(this.$$search),
+        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
+
+    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
+    this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url : '');
+
+    this.$$urlUpdatedByLocation = true;
+  };
+
+  this.$$parseLinkUrl = function(url, relHref) {
+    if (stripHash(appBase) === stripHash(url)) {
+      this.$$parse(url);
+      return true;
+    }
+    return false;
+  };
+}
+
+
+/**
+ * LocationHashbangUrl represents URL
+ * This object is exposed as $location service when html5 history api is enabled but the browser
+ * does not support it.
+ *
+ * @constructor
+ * @param {string} appBase application base URL
+ * @param {string} appBaseNoFile application base URL stripped of any filename
+ * @param {string} hashPrefix hashbang prefix
+ */
+function LocationHashbangInHtml5Url(appBase, appBaseNoFile, hashPrefix) {
+  this.$$html5 = true;
+  LocationHashbangUrl.apply(this, arguments);
+
+  this.$$parseLinkUrl = function(url, relHref) {
+    if (relHref && relHref[0] === '#') {
+      // special case for links to hash fragments:
+      // keep the old url and only replace the hash fragment
+      this.hash(relHref.slice(1));
+      return true;
+    }
+
+    var rewrittenUrl;
+    var appUrl;
+
+    if (appBase === stripHash(url)) {
+      rewrittenUrl = url;
+    } else if ((appUrl = stripBaseUrl(appBaseNoFile, url))) {
+      rewrittenUrl = appBase + hashPrefix + appUrl;
+    } else if (appBaseNoFile === url + '/') {
+      rewrittenUrl = appBaseNoFile;
+    }
+    if (rewrittenUrl) {
+      this.$$parse(rewrittenUrl);
+    }
+    return !!rewrittenUrl;
+  };
+
+  this.$$compose = function() {
+    var search = toKeyValue(this.$$search),
+        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
+
+    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
+    // include hashPrefix in $$absUrl when $$url is empty so IE9 does not reload page because of removal of '#'
+    this.$$absUrl = appBase + hashPrefix + this.$$url;
+
+    this.$$urlUpdatedByLocation = true;
+  };
+
+}
+
+
+var locationPrototype = {
+
+  /**
+   * Ensure absolute URL is initialized.
+   * @private
+   */
+  $$absUrl:'',
+
+  /**
+   * Are we in html5 mode?
+   * @private
+   */
+  $$html5: false,
+
+  /**
+   * Has any change been replacing?
+   * @private
+   */
+  $$replace: false,
+
+  /**
+   * @ngdoc method
+   * @name $location#absUrl
+   *
+   * @description
+   * This method is getter only.
+   *
+   * Return full URL representation with all segments encoded according to rules specified in
+   * [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).
+   *
+   *
+   * ```js
+   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
+   * var absUrl = $location.absUrl();
+   * // => "http://example.com/#/some/path?foo=bar&baz=xoxo"
+   * ```
+   *
+   * @return {string} full URL
+   */
+  absUrl: locationGetter('$$absUrl'),
+
+  /**
+   * @ngdoc method
+   * @name $location#url
+   *
+   * @description
+   * This method is getter / setter.
+   *
+   * Return URL (e.g. `/path?a=b#hash`) when called without any parameter.
+   *
+   * Change path, search and hash, when called with parameter and return `$location`.
+   *
+   *
+   * ```js
+   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
+   * var url = $location.url();
+   * // => "/some/path?foo=bar&baz=xoxo"
+   * ```
+   *
+   * @param {string=} url New URL without base prefix (e.g. `/path?a=b#hash`)
+   * @return {string} url
+   */
+  url: function(url) {
+    if (isUndefined(url)) {
+      return this.$$url;
+    }
+
+    var match = PATH_MATCH.exec(url);
+    if (match[1] || url === '') this.path(decodeURIComponent(match[1]));
+    if (match[2] || match[1] || url === '') this.search(match[3] || '');
+    this.hash(match[5] || '');
+
+    return this;
+  },
+
+  /**
+   * @ngdoc method
+   * @name $location#protocol
+   *
+   * @description
+   * This method is getter only.
+   *
+   * Return protocol of current URL.
+   *
+   *
+   * ```js
+   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
+   * var protocol = $location.protocol();
+   * // => "http"
+   * ```
+   *
+   * @return {string} protocol of current URL
+   */
+  protocol: locationGetter('$$protocol'),
+
+  /**
+   * @ngdoc method
+   * @name $location#host
+   *
+   * @description
+   * This method is getter only.
+   *
+   * Return host of current URL.
+   *
+   * Note: compared to the non-angular version `location.host` which returns `hostname:port`, this returns the `hostname` portion only.
+   *
+   *
+   * ```js
+   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
+   * var host = $location.host();
+   * // => "example.com"
+   *
+   * // given URL http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo
+   * host = $location.host();
+   * // => "example.com"
+   * host = location.host;
+   * // => "example.com:8080"
+   * ```
+   *
+   * @return {string} host of current URL.
+   */
+  host: locationGetter('$$host'),
+
+  /**
+   * @ngdoc method
+   * @name $location#port
+   *
+   * @description
+   * This method is getter only.
+   *
+   * Return port of current URL.
+   *
+   *
+   * ```js
+   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
+   * var port = $location.port();
+   * // => 80
+   * ```
+   *
+   * @return {Number} port
+   */
+  port: locationGetter('$$port'),
+
+  /**
+   * @ngdoc method
+   * @name $location#path
+   *
+   * @description
+   * This method is getter / setter.
+   *
+   * Return path of current URL when called without any parameter.
+   *
+   * Change path when called with parameter and return `$location`.
+   *
+   * Note: Path should always begin with forward slash (/), this method will add the forward slash
+   * if it is missing.
+   *
+   *
+   * ```js
+   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
+   * var path = $location.path();
+   * // => "/some/path"
+   * ```
+   *
+   * @param {(string|number)=} path New path
+   * @return {(string|object)} path if called with no parameters, or `$location` if called with a parameter
+   */
+  path: locationGetterSetter('$$path', function(path) {
+    path = path !== null ? path.toString() : '';
+    return path.charAt(0) === '/' ? path : '/' + path;
+  }),
+
+  /**
+   * @ngdoc method
+   * @name $location#search
+   *
+   * @description
+   * This method is getter / setter.
+   *
+   * Return search part (as object) of current URL when called without any parameter.
+   *
+   * Change search part when called with parameter and return `$location`.
+   *
+   *
+   * ```js
+   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
+   * var searchObject = $location.search();
+   * // => {foo: 'bar', baz: 'xoxo'}
+   *
+   * // set foo to 'yipee'
+   * $location.search('foo', 'yipee');
+   * // $location.search() => {foo: 'yipee', baz: 'xoxo'}
+   * ```
+   *
+   * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or
+   * hash object.
+   *
+   * When called with a single argument the method acts as a setter, setting the `search` component
+   * of `$location` to the specified value.
+   *
+   * If the argument is a hash object containing an array of values, these values will be encoded
+   * as duplicate search parameters in the URL.
+   *
+   * @param {(string|Number|Array<string>|boolean)=} paramValue If `search` is a string or number, then `paramValue`
+   * will override only a single search property.
+   *
+   * If `paramValue` is an array, it will override the property of the `search` component of
+   * `$location` specified via the first argument.
+   *
+   * If `paramValue` is `null`, the property specified via the first argument will be deleted.
+   *
+   * If `paramValue` is `true`, the property specified via the first argument will be added with no
+   * value nor trailing equal sign.
+   *
+   * @return {Object} If called with no arguments returns the parsed `search` object. If called with
+   * one or more arguments returns `$location` object itself.
+   */
+  search: function(search, paramValue) {
+    switch (arguments.length) {
+      case 0:
+        return this.$$search;
+      case 1:
+        if (isString(search) || isNumber(search)) {
+          search = search.toString();
+          this.$$search = parseKeyValue(search);
+        } else if (isObject(search)) {
+          search = copy(search, {});
+          // remove object undefined or null properties
+          forEach(search, function(value, key) {
+            if (value == null) delete search[key];
+          });
+
+          this.$$search = search;
+        } else {
+          throw $locationMinErr('isrcharg',
+              'The first argument of the `$location#search()` call must be a string or an object.');
+        }
+        break;
+      default:
+        if (isUndefined(paramValue) || paramValue === null) {
+          delete this.$$search[search];
+        } else {
+          this.$$search[search] = paramValue;
+        }
+    }
+
+    this.$$compose();
+    return this;
+  },
+
+  /**
+   * @ngdoc method
+   * @name $location#hash
+   *
+   * @description
+   * This method is getter / setter.
+   *
+   * Returns the hash fragment when called without any parameters.
+   *
+   * Changes the hash fragment when called with a parameter and returns `$location`.
+   *
+   *
+   * ```js
+   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue
+   * var hash = $location.hash();
+   * // => "hashValue"
+   * ```
+   *
+   * @param {(string|number)=} hash New hash fragment
+   * @return {string} hash
+   */
+  hash: locationGetterSetter('$$hash', function(hash) {
+    return hash !== null ? hash.toString() : '';
+  }),
+
+  /**
+   * @ngdoc method
+   * @name $location#replace
+   *
+   * @description
+   * If called, all changes to $location during the current `$digest` will replace the current history
+   * record, instead of adding a new one.
+   */
+  replace: function() {
+    this.$$replace = true;
+    return this;
+  }
+};
+
+forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) {
+  Location.prototype = Object.create(locationPrototype);
+
+  /**
+   * @ngdoc method
+   * @name $location#state
+   *
+   * @description
+   * This method is getter / setter.
+   *
+   * Return the history state object when called without any parameter.
+   *
+   * Change the history state object when called with one parameter and return `$location`.
+   * The state object is later passed to `pushState` or `replaceState`.
+   *
+   * NOTE: This method is supported only in HTML5 mode and only in browsers supporting
+   * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support
+   * older browsers (like IE9 or Android < 4.0), don't use this method.
+   *
+   * @param {object=} state State object for pushState or replaceState
+   * @return {object} state
+   */
+  Location.prototype.state = function(state) {
+    if (!arguments.length) {
+      return this.$$state;
+    }
+
+    if (Location !== LocationHtml5Url || !this.$$html5) {
+      throw $locationMinErr('nostate', 'History API state support is available only ' +
+        'in HTML5 mode and only in browsers supporting HTML5 History API');
+    }
+    // The user might modify `stateObject` after invoking `$location.state(stateObject)`
+    // but we're changing the $$state reference to $browser.state() during the $digest
+    // so the modification window is narrow.
+    this.$$state = isUndefined(state) ? null : state;
+    this.$$urlUpdatedByLocation = true;
+
+    return this;
+  };
+});
+
+
+function locationGetter(property) {
+  return /** @this */ function() {
+    return this[property];
+  };
+}
+
+
+function locationGetterSetter(property, preprocess) {
+  return /** @this */ function(value) {
+    if (isUndefined(value)) {
+      return this[property];
+    }
+
+    this[property] = preprocess(value);
+    this.$$compose();
+
+    return this;
+  };
+}
+
+
+/**
+ * @ngdoc service
+ * @name $location
+ *
+ * @requires $rootElement
+ *
+ * @description
+ * The $location service parses the URL in the browser address bar (based on the
+ * [window.location](https://developer.mozilla.org/en/window.location)) and makes the URL
+ * available to your application. Changes to the URL in the address bar are reflected into
+ * $location service and changes to $location are reflected into the browser address bar.
+ *
+ * **The $location service:**
+ *
+ * - Exposes the current URL in the browser address bar, so you can
+ *   - Watch and observe the URL.
+ *   - Change the URL.
+ * - Synchronizes the URL with the browser when the user
+ *   - Changes the address bar.
+ *   - Clicks the back or forward button (or clicks a History link).
+ *   - Clicks on a link.
+ * - Represents the URL object as a set of methods (protocol, host, port, path, search, hash).
+ *
+ * For more information see {@link guide/$location Developer Guide: Using $location}
+ */
+
+/**
+ * @ngdoc provider
+ * @name $locationProvider
+ * @this
+ *
+ * @description
+ * Use the `$locationProvider` to configure how the application deep linking paths are stored.
+ */
+function $LocationProvider() {
+  var hashPrefix = '!',
+      html5Mode = {
+        enabled: false,
+        requireBase: true,
+        rewriteLinks: true
+      };
+
+  /**
+   * @ngdoc method
+   * @name $locationProvider#hashPrefix
+   * @description
+   * The default value for the prefix is `'!'`.
+   * @param {string=} prefix Prefix for hash part (containing path and search)
+   * @returns {*} current value if used as getter or itself (chaining) if used as setter
+   */
+  this.hashPrefix = function(prefix) {
+    if (isDefined(prefix)) {
+      hashPrefix = prefix;
+      return this;
+    } else {
+      return hashPrefix;
+    }
+  };
+
+  /**
+   * @ngdoc method
+   * @name $locationProvider#html5Mode
+   * @description
+   * @param {(boolean|Object)=} mode If boolean, sets `html5Mode.enabled` to value.
+   *   If object, sets `enabled`, `requireBase` and `rewriteLinks` to respective values. Supported
+   *   properties:
+   *   - **enabled** – `{boolean}` – (default: false) If true, will rely on `history.pushState` to
+   *     change urls where supported. Will fall back to hash-prefixed paths in browsers that do not
+   *     support `pushState`.
+   *   - **requireBase** - `{boolean}` - (default: `true`) When html5Mode is enabled, specifies
+   *     whether or not a <base> tag is required to be present. If `enabled` and `requireBase` are
+   *     true, and a base tag is not present, an error will be thrown when `$location` is injected.
+   *     See the {@link guide/$location $location guide for more information}
+   *   - **rewriteLinks** - `{boolean|string}` - (default: `true`) When html5Mode is enabled,
+   *     enables/disables URL rewriting for relative links. If set to a string, URL rewriting will
+   *     only happen on links with an attribute that matches the given string. For example, if set
+   *     to `'internal-link'`, then the URL will only be rewritten for `<a internal-link>` links.
+   *     Note that [attribute name normalization](guide/directive#normalization) does not apply
+   *     here, so `'internalLink'` will **not** match `'internal-link'`.
+   *
+   * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter
+   */
+  this.html5Mode = function(mode) {
+    if (isBoolean(mode)) {
+      html5Mode.enabled = mode;
+      return this;
+    } else if (isObject(mode)) {
+
+      if (isBoolean(mode.enabled)) {
+        html5Mode.enabled = mode.enabled;
+      }
+
+      if (isBoolean(mode.requireBase)) {
+        html5Mode.requireBase = mode.requireBase;
+      }
+
+      if (isBoolean(mode.rewriteLinks) || isString(mode.rewriteLinks)) {
+        html5Mode.rewriteLinks = mode.rewriteLinks;
+      }
+
+      return this;
+    } else {
+      return html5Mode;
+    }
+  };
+
+  /**
+   * @ngdoc event
+   * @name $location#$locationChangeStart
+   * @eventType broadcast on root scope
+   * @description
+   * Broadcasted before a URL will change.
+   *
+   * This change can be prevented by calling
+   * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more
+   * details about event object. Upon successful change
+   * {@link ng.$location#$locationChangeSuccess $locationChangeSuccess} is fired.
+   *
+   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when
+   * the browser supports the HTML5 History API.
+   *
+   * @param {Object} angularEvent Synthetic event object.
+   * @param {string} newUrl New URL
+   * @param {string=} oldUrl URL that was before it was changed.
+   * @param {string=} newState New history state object
+   * @param {string=} oldState History state object that was before it was changed.
+   */
+
+  /**
+   * @ngdoc event
+   * @name $location#$locationChangeSuccess
+   * @eventType broadcast on root scope
+   * @description
+   * Broadcasted after a URL was changed.
+   *
+   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when
+   * the browser supports the HTML5 History API.
+   *
+   * @param {Object} angularEvent Synthetic event object.
+   * @param {string} newUrl New URL
+   * @param {string=} oldUrl URL that was before it was changed.
+   * @param {string=} newState New history state object
+   * @param {string=} oldState History state object that was before it was changed.
+   */
+
+  this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', '$window',
+      function($rootScope, $browser, $sniffer, $rootElement, $window) {
+    var $location,
+        LocationMode,
+        baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
+        initialUrl = $browser.url(),
+        appBase;
+
+    if (html5Mode.enabled) {
+      if (!baseHref && html5Mode.requireBase) {
+        throw $locationMinErr('nobase',
+          '$location in HTML5 mode requires a <base> tag to be present!');
+      }
+      appBase = serverBase(initialUrl) + (baseHref || '/');
+      LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url;
+    } else {
+      appBase = stripHash(initialUrl);
+      LocationMode = LocationHashbangUrl;
+    }
+    var appBaseNoFile = stripFile(appBase);
+
+    $location = new LocationMode(appBase, appBaseNoFile, '#' + hashPrefix);
+    $location.$$parseLinkUrl(initialUrl, initialUrl);
+
+    $location.$$state = $browser.state();
+
+    var IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
+
+    function setBrowserUrlWithFallback(url, replace, state) {
+      var oldUrl = $location.url();
+      var oldState = $location.$$state;
+      try {
+        $browser.url(url, replace, state);
+
+        // Make sure $location.state() returns referentially identical (not just deeply equal)
+        // state object; this makes possible quick checking if the state changed in the digest
+        // loop. Checking deep equality would be too expensive.
+        $location.$$state = $browser.state();
+      } catch (e) {
+        // Restore old values if pushState fails
+        $location.url(oldUrl);
+        $location.$$state = oldState;
+
+        throw e;
+      }
+    }
+
+    $rootElement.on('click', function(event) {
+      var rewriteLinks = html5Mode.rewriteLinks;
+      // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
+      // currently we open nice url link and redirect then
+
+      if (!rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 || event.button === 2) return;
+
+      var elm = jqLite(event.target);
+
+      // traverse the DOM up to find first A tag
+      while (nodeName_(elm[0]) !== 'a') {
+        // ignore rewriting if no A tag (reached root element, or no parent - removed from document)
+        if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return;
+      }
+
+      if (isString(rewriteLinks) && isUndefined(elm.attr(rewriteLinks))) return;
+
+      var absHref = elm.prop('href');
+      // get the actual href attribute - see
+      // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx
+      var relHref = elm.attr('href') || elm.attr('xlink:href');
+
+      if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {
+        // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during
+        // an animation.
+        absHref = urlResolve(absHref.animVal).href;
+      }
+
+      // Ignore when url is started with javascript: or mailto:
+      if (IGNORE_URI_REGEXP.test(absHref)) return;
+
+      if (absHref && !elm.attr('target') && !event.isDefaultPrevented()) {
+        if ($location.$$parseLinkUrl(absHref, relHref)) {
+          // We do a preventDefault for all urls that are part of the angular application,
+          // in html5mode and also without, so that we are able to abort navigation without
+          // getting double entries in the location history.
+          event.preventDefault();
+          // update location manually
+          if ($location.absUrl() !== $browser.url()) {
+            $rootScope.$apply();
+            // hack to work around FF6 bug 684208 when scenario runner clicks on links
+            $window.angular['ff-684208-preventDefault'] = true;
+          }
+        }
+      }
+    });
+
+
+    // rewrite hashbang url <> html5 url
+    if (trimEmptyHash($location.absUrl()) !== trimEmptyHash(initialUrl)) {
+      $browser.url($location.absUrl(), true);
+    }
+
+    var initializing = true;
+
+    // update $location when $browser url changes
+    $browser.onUrlChange(function(newUrl, newState) {
+
+      if (!startsWith(newUrl, appBaseNoFile)) {
+        // If we are navigating outside of the app then force a reload
+        $window.location.href = newUrl;
+        return;
+      }
+
+      $rootScope.$evalAsync(function() {
+        var oldUrl = $location.absUrl();
+        var oldState = $location.$$state;
+        var defaultPrevented;
+        newUrl = trimEmptyHash(newUrl);
+        $location.$$parse(newUrl);
+        $location.$$state = newState;
+
+        defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
+            newState, oldState).defaultPrevented;
+
+        // if the location was changed by a `$locationChangeStart` handler then stop
+        // processing this location change
+        if ($location.absUrl() !== newUrl) return;
+
+        if (defaultPrevented) {
+          $location.$$parse(oldUrl);
+          $location.$$state = oldState;
+          setBrowserUrlWithFallback(oldUrl, false, oldState);
+        } else {
+          initializing = false;
+          afterLocationChange(oldUrl, oldState);
+        }
+      });
+      if (!$rootScope.$$phase) $rootScope.$digest();
+    });
+
+    // update browser
+    $rootScope.$watch(function $locationWatch() {
+      if (initializing || $location.$$urlUpdatedByLocation) {
+        $location.$$urlUpdatedByLocation = false;
+
+        var oldUrl = trimEmptyHash($browser.url());
+        var newUrl = trimEmptyHash($location.absUrl());
+        var oldState = $browser.state();
+        var currentReplace = $location.$$replace;
+        var urlOrStateChanged = oldUrl !== newUrl ||
+          ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);
+
+        if (initializing || urlOrStateChanged) {
+          initializing = false;
+
+          $rootScope.$evalAsync(function() {
+            var newUrl = $location.absUrl();
+            var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
+                $location.$$state, oldState).defaultPrevented;
+
+            // if the location was changed by a `$locationChangeStart` handler then stop
+            // processing this location change
+            if ($location.absUrl() !== newUrl) return;
+
+            if (defaultPrevented) {
+              $location.$$parse(oldUrl);
+              $location.$$state = oldState;
+            } else {
+              if (urlOrStateChanged) {
+                setBrowserUrlWithFallback(newUrl, currentReplace,
+                                          oldState === $location.$$state ? null : $location.$$state);
+              }
+              afterLocationChange(oldUrl, oldState);
+            }
+          });
+        }
+      }
+
+      $location.$$replace = false;
+
+      // we don't need to return anything because $evalAsync will make the digest loop dirty when
+      // there is a change
+    });
+
+    return $location;
+
+    function afterLocationChange(oldUrl, oldState) {
+      $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl,
+        $location.$$state, oldState);
+    }
+}];
+}
+
+/**
+ * @ngdoc service
+ * @name $log
+ * @requires $window
+ *
+ * @description
+ * Simple service for logging. Default implementation safely writes the message
+ * into the browser's console (if present).
+ *
+ * The main purpose of this service is to simplify debugging and troubleshooting.
+ *
+ * The default is to log `debug` messages. You can use
+ * {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.
+ *
+ * @example
+   <example module="logExample" name="log-service">
+     <file name="script.js">
+       angular.module('logExample', [])
+         .controller('LogController', ['$scope', '$log', function($scope, $log) {
+           $scope.$log = $log;
+           $scope.message = 'Hello World!';
+         }]);
+     </file>
+     <file name="index.html">
+       <div ng-controller="LogController">
+         <p>Reload this page with open console, enter text and hit the log button...</p>
+         <label>Message:
+         <input type="text" ng-model="message" /></label>
+         <button ng-click="$log.log(message)">log</button>
+         <button ng-click="$log.warn(message)">warn</button>
+         <button ng-click="$log.info(message)">info</button>
+         <button ng-click="$log.error(message)">error</button>
+         <button ng-click="$log.debug(message)">debug</button>
+       </div>
+     </file>
+   </example>
+ */
+
+/**
+ * @ngdoc provider
+ * @name $logProvider
+ * @this
+ *
+ * @description
+ * Use the `$logProvider` to configure how the application logs messages
+ */
+function $LogProvider() {
+  var debug = true,
+      self = this;
+
+  /**
+   * @ngdoc method
+   * @name $logProvider#debugEnabled
+   * @description
+   * @param {boolean=} flag enable or disable debug level messages
+   * @returns {*} current value if used as getter or itself (chaining) if used as setter
+   */
+  this.debugEnabled = function(flag) {
+    if (isDefined(flag)) {
+      debug = flag;
+      return this;
+    } else {
+      return debug;
+    }
+  };
+
+  this.$get = ['$window', function($window) {
+    // Support: IE 9-11, Edge 12-14+
+    // IE/Edge display errors in such a way that it requires the user to click in 4 places
+    // to see the stack trace. There is no way to feature-detect it so there's a chance
+    // of the user agent sniffing to go wrong but since it's only about logging, this shouldn't
+    // break apps. Other browsers display errors in a sensible way and some of them map stack
+    // traces along source maps if available so it makes sense to let browsers display it
+    // as they want.
+    var formatStackTrace = msie || /\bEdge\//.test($window.navigator && $window.navigator.userAgent);
+
+    return {
+      /**
+       * @ngdoc method
+       * @name $log#log
+       *
+       * @description
+       * Write a log message
+       */
+      log: consoleLog('log'),
+
+      /**
+       * @ngdoc method
+       * @name $log#info
+       *
+       * @description
+       * Write an information message
+       */
+      info: consoleLog('info'),
+
+      /**
+       * @ngdoc method
+       * @name $log#warn
+       *
+       * @description
+       * Write a warning message
+       */
+      warn: consoleLog('warn'),
+
+      /**
+       * @ngdoc method
+       * @name $log#error
+       *
+       * @description
+       * Write an error message
+       */
+      error: consoleLog('error'),
+
+      /**
+       * @ngdoc method
+       * @name $log#debug
+       *
+       * @description
+       * Write a debug message
+       */
+      debug: (function() {
+        var fn = consoleLog('debug');
+
+        return function() {
+          if (debug) {
+            fn.apply(self, arguments);
+          }
+        };
+      })()
+    };
+
+    function formatError(arg) {
+      if (arg instanceof Error) {
+        if (arg.stack && formatStackTrace) {
+          arg = (arg.message && arg.stack.indexOf(arg.message) === -1)
+              ? 'Error: ' + arg.message + '\n' + arg.stack
+              : arg.stack;
+        } else if (arg.sourceURL) {
+          arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line;
+        }
+      }
+      return arg;
+    }
+
+    function consoleLog(type) {
+      var console = $window.console || {},
+          logFn = console[type] || console.log || noop,
+          hasApply = false;
+
+      // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.
+      // The reason behind this is that console.log has type "object" in IE8...
+      try {
+        hasApply = !!logFn.apply;
+      } catch (e) { /* empty */ }
+
+      if (hasApply) {
+        return function() {
+          var args = [];
+          forEach(arguments, function(arg) {
+            args.push(formatError(arg));
+          });
+          return logFn.apply(console, args);
+        };
+      }
+
+      // we are IE which either doesn't have window.console => this is noop and we do nothing,
+      // or we are IE where console.log doesn't have apply so we log at least first 2 args
+      return function(arg1, arg2) {
+        logFn(arg1, arg2 == null ? '' : arg2);
+      };
+    }
+  }];
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *     Any commits to this file should be reviewed with security in mind.  *
+ *   Changes to this file can potentially create security vulnerabilities. *
+ *          An approval from 2 Core members with history of modifying      *
+ *                         this file is required.                          *
+ *                                                                         *
+ *  Does the change somehow allow for arbitrary javascript to be executed? *
+ *    Or allows for someone to change the prototype of built-in objects?   *
+ *     Or gives undesired access to variables likes document or window?    *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+var $parseMinErr = minErr('$parse');
+
+var objectValueOf = {}.constructor.prototype.valueOf;
+
+// Sandboxing Angular Expressions
+// ------------------------------
+// Angular expressions are no longer sandboxed. So it is now even easier to access arbitrary JS code by
+// various means such as obtaining a reference to native JS functions like the Function constructor.
+//
+// As an example, consider the following Angular expression:
+//
+//   {}.toString.constructor('alert("evil JS code")')
+//
+// It is important to realize that if you create an expression from a string that contains user provided
+// content then it is possible that your application contains a security vulnerability to an XSS style attack.
+//
+// See https://docs.angularjs.org/guide/security
+
+
+function getStringValue(name) {
+  // Property names must be strings. This means that non-string objects cannot be used
+  // as keys in an object. Any non-string object, including a number, is typecasted
+  // into a string via the toString method.
+  // -- MDN, https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors#Property_names
+  //
+  // So, to ensure that we are checking the same `name` that JavaScript would use, we cast it
+  // to a string. It's not always possible. If `name` is an object and its `toString` method is
+  // 'broken' (doesn't return a string, isn't a function, etc.), an error will be thrown:
+  //
+  // TypeError: Cannot convert object to primitive value
+  //
+  // For performance reasons, we don't catch this error here and allow it to propagate up the call
+  // stack. Note that you'll get the same error in JavaScript if you try to access a property using
+  // such a 'broken' object as a key.
+  return name + '';
+}
+
+
+var OPERATORS = createMap();
+forEach('+ - * / % === !== == != < > <= >= && || ! = |'.split(' '), function(operator) { OPERATORS[operator] = true; });
+var ESCAPE = {'n':'\n', 'f':'\f', 'r':'\r', 't':'\t', 'v':'\v', '\'':'\'', '"':'"'};
+
+
+/////////////////////////////////////////
+
+
+/**
+ * @constructor
+ */
+var Lexer = function Lexer(options) {
+  this.options = options;
+};
+
+Lexer.prototype = {
+  constructor: Lexer,
+
+  lex: function(text) {
+    this.text = text;
+    this.index = 0;
+    this.tokens = [];
+
+    while (this.index < this.text.length) {
+      var ch = this.text.charAt(this.index);
+      if (ch === '"' || ch === '\'') {
+        this.readString(ch);
+      } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {
+        this.readNumber();
+      } else if (this.isIdentifierStart(this.peekMultichar())) {
+        this.readIdent();
+      } else if (this.is(ch, '(){}[].,;:?')) {
+        this.tokens.push({index: this.index, text: ch});
+        this.index++;
+      } else if (this.isWhitespace(ch)) {
+        this.index++;
+      } else {
+        var ch2 = ch + this.peek();
+        var ch3 = ch2 + this.peek(2);
+        var op1 = OPERATORS[ch];
+        var op2 = OPERATORS[ch2];
+        var op3 = OPERATORS[ch3];
+        if (op1 || op2 || op3) {
+          var token = op3 ? ch3 : (op2 ? ch2 : ch);
+          this.tokens.push({index: this.index, text: token, operator: true});
+          this.index += token.length;
+        } else {
+          this.throwError('Unexpected next character ', this.index, this.index + 1);
+        }
+      }
+    }
+    return this.tokens;
+  },
+
+  is: function(ch, chars) {
+    return chars.indexOf(ch) !== -1;
+  },
+
+  peek: function(i) {
+    var num = i || 1;
+    return (this.index + num < this.text.length) ? this.text.charAt(this.index + num) : false;
+  },
+
+  isNumber: function(ch) {
+    return ('0' <= ch && ch <= '9') && typeof ch === 'string';
+  },
+
+  isWhitespace: function(ch) {
+    // IE treats non-breaking space as \u00A0
+    return (ch === ' ' || ch === '\r' || ch === '\t' ||
+            ch === '\n' || ch === '\v' || ch === '\u00A0');
+  },
+
+  isIdentifierStart: function(ch) {
+    return this.options.isIdentifierStart ?
+        this.options.isIdentifierStart(ch, this.codePointAt(ch)) :
+        this.isValidIdentifierStart(ch);
+  },
+
+  isValidIdentifierStart: function(ch) {
+    return ('a' <= ch && ch <= 'z' ||
+            'A' <= ch && ch <= 'Z' ||
+            '_' === ch || ch === '$');
+  },
+
+  isIdentifierContinue: function(ch) {
+    return this.options.isIdentifierContinue ?
+        this.options.isIdentifierContinue(ch, this.codePointAt(ch)) :
+        this.isValidIdentifierContinue(ch);
+  },
+
+  isValidIdentifierContinue: function(ch, cp) {
+    return this.isValidIdentifierStart(ch, cp) || this.isNumber(ch);
+  },
+
+  codePointAt: function(ch) {
+    if (ch.length === 1) return ch.charCodeAt(0);
+    // eslint-disable-next-line no-bitwise
+    return (ch.charCodeAt(0) << 10) + ch.charCodeAt(1) - 0x35FDC00;
+  },
+
+  peekMultichar: function() {
+    var ch = this.text.charAt(this.index);
+    var peek = this.peek();
+    if (!peek) {
+      return ch;
+    }
+    var cp1 = ch.charCodeAt(0);
+    var cp2 = peek.charCodeAt(0);
+    if (cp1 >= 0xD800 && cp1 <= 0xDBFF && cp2 >= 0xDC00 && cp2 <= 0xDFFF) {
+      return ch + peek;
+    }
+    return ch;
+  },
+
+  isExpOperator: function(ch) {
+    return (ch === '-' || ch === '+' || this.isNumber(ch));
+  },
+
+  throwError: function(error, start, end) {
+    end = end || this.index;
+    var colStr = (isDefined(start)
+            ? 's ' + start +  '-' + this.index + ' [' + this.text.substring(start, end) + ']'
+            : ' ' + end);
+    throw $parseMinErr('lexerr', 'Lexer Error: {0} at column{1} in expression [{2}].',
+        error, colStr, this.text);
+  },
+
+  readNumber: function() {
+    var number = '';
+    var start = this.index;
+    while (this.index < this.text.length) {
+      var ch = lowercase(this.text.charAt(this.index));
+      if (ch === '.' || this.isNumber(ch)) {
+        number += ch;
+      } else {
+        var peekCh = this.peek();
+        if (ch === 'e' && this.isExpOperator(peekCh)) {
+          number += ch;
+        } else if (this.isExpOperator(ch) &&
+            peekCh && this.isNumber(peekCh) &&
+            number.charAt(number.length - 1) === 'e') {
+          number += ch;
+        } else if (this.isExpOperator(ch) &&
+            (!peekCh || !this.isNumber(peekCh)) &&
+            number.charAt(number.length - 1) === 'e') {
+          this.throwError('Invalid exponent');
+        } else {
+          break;
+        }
+      }
+      this.index++;
+    }
+    this.tokens.push({
+      index: start,
+      text: number,
+      constant: true,
+      value: Number(number)
+    });
+  },
+
+  readIdent: function() {
+    var start = this.index;
+    this.index += this.peekMultichar().length;
+    while (this.index < this.text.length) {
+      var ch = this.peekMultichar();
+      if (!this.isIdentifierContinue(ch)) {
+        break;
+      }
+      this.index += ch.length;
+    }
+    this.tokens.push({
+      index: start,
+      text: this.text.slice(start, this.index),
+      identifier: true
+    });
+  },
+
+  readString: function(quote) {
+    var start = this.index;
+    this.index++;
+    var string = '';
+    var rawString = quote;
+    var escape = false;
+    while (this.index < this.text.length) {
+      var ch = this.text.charAt(this.index);
+      rawString += ch;
+      if (escape) {
+        if (ch === 'u') {
+          var hex = this.text.substring(this.index + 1, this.index + 5);
+          if (!hex.match(/[\da-f]{4}/i)) {
+            this.throwError('Invalid unicode escape [\\u' + hex + ']');
+          }
+          this.index += 4;
+          string += String.fromCharCode(parseInt(hex, 16));
+        } else {
+          var rep = ESCAPE[ch];
+          string = string + (rep || ch);
+        }
+        escape = false;
+      } else if (ch === '\\') {
+        escape = true;
+      } else if (ch === quote) {
+        this.index++;
+        this.tokens.push({
+          index: start,
+          text: rawString,
+          constant: true,
+          value: string
+        });
+        return;
+      } else {
+        string += ch;
+      }
+      this.index++;
+    }
+    this.throwError('Unterminated quote', start);
+  }
+};
+
+var AST = function AST(lexer, options) {
+  this.lexer = lexer;
+  this.options = options;
+};
+
+AST.Program = 'Program';
+AST.ExpressionStatement = 'ExpressionStatement';
+AST.AssignmentExpression = 'AssignmentExpression';
+AST.ConditionalExpression = 'ConditionalExpression';
+AST.LogicalExpression = 'LogicalExpression';
+AST.BinaryExpression = 'BinaryExpression';
+AST.UnaryExpression = 'UnaryExpression';
+AST.CallExpression = 'CallExpression';
+AST.MemberExpression = 'MemberExpression';
+AST.Identifier = 'Identifier';
+AST.Literal = 'Literal';
+AST.ArrayExpression = 'ArrayExpression';
+AST.Property = 'Property';
+AST.ObjectExpression = 'ObjectExpression';
+AST.ThisExpression = 'ThisExpression';
+AST.LocalsExpression = 'LocalsExpression';
+
+// Internal use only
+AST.NGValueParameter = 'NGValueParameter';
+
+AST.prototype = {
+  ast: function(text) {
+    this.text = text;
+    this.tokens = this.lexer.lex(text);
+
+    var value = this.program();
+
+    if (this.tokens.length !== 0) {
+      this.throwError('is an unexpected token', this.tokens[0]);
+    }
+
+    return value;
+  },
+
+  program: function() {
+    var body = [];
+    while (true) {
+      if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']'))
+        body.push(this.expressionStatement());
+      if (!this.expect(';')) {
+        return { type: AST.Program, body: body};
+      }
+    }
+  },
+
+  expressionStatement: function() {
+    return { type: AST.ExpressionStatement, expression: this.filterChain() };
+  },
+
+  filterChain: function() {
+    var left = this.expression();
+    while (this.expect('|')) {
+      left = this.filter(left);
+    }
+    return left;
+  },
+
+  expression: function() {
+    return this.assignment();
+  },
+
+  assignment: function() {
+    var result = this.ternary();
+    if (this.expect('=')) {
+      if (!isAssignable(result)) {
+        throw $parseMinErr('lval', 'Trying to assign a value to a non l-value');
+      }
+
+      result = { type: AST.AssignmentExpression, left: result, right: this.assignment(), operator: '='};
+    }
+    return result;
+  },
+
+  ternary: function() {
+    var test = this.logicalOR();
+    var alternate;
+    var consequent;
+    if (this.expect('?')) {
+      alternate = this.expression();
+      if (this.consume(':')) {
+        consequent = this.expression();
+        return { type: AST.ConditionalExpression, test: test, alternate: alternate, consequent: consequent};
+      }
+    }
+    return test;
+  },
+
+  logicalOR: function() {
+    var left = this.logicalAND();
+    while (this.expect('||')) {
+      left = { type: AST.LogicalExpression, operator: '||', left: left, right: this.logicalAND() };
+    }
+    return left;
+  },
+
+  logicalAND: function() {
+    var left = this.equality();
+    while (this.expect('&&')) {
+      left = { type: AST.LogicalExpression, operator: '&&', left: left, right: this.equality()};
+    }
+    return left;
+  },
+
+  equality: function() {
+    var left = this.relational();
+    var token;
+    while ((token = this.expect('==','!=','===','!=='))) {
+      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.relational() };
+    }
+    return left;
+  },
+
+  relational: function() {
+    var left = this.additive();
+    var token;
+    while ((token = this.expect('<', '>', '<=', '>='))) {
+      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.additive() };
+    }
+    return left;
+  },
+
+  additive: function() {
+    var left = this.multiplicative();
+    var token;
+    while ((token = this.expect('+','-'))) {
+      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.multiplicative() };
+    }
+    return left;
+  },
+
+  multiplicative: function() {
+    var left = this.unary();
+    var token;
+    while ((token = this.expect('*','/','%'))) {
+      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.unary() };
+    }
+    return left;
+  },
+
+  unary: function() {
+    var token;
+    if ((token = this.expect('+', '-', '!'))) {
+      return { type: AST.UnaryExpression, operator: token.text, prefix: true, argument: this.unary() };
+    } else {
+      return this.primary();
+    }
+  },
+
+  primary: function() {
+    var primary;
+    if (this.expect('(')) {
+      primary = this.filterChain();
+      this.consume(')');
+    } else if (this.expect('[')) {
+      primary = this.arrayDeclaration();
+    } else if (this.expect('{')) {
+      primary = this.object();
+    } else if (this.selfReferential.hasOwnProperty(this.peek().text)) {
+      primary = copy(this.selfReferential[this.consume().text]);
+    } else if (this.options.literals.hasOwnProperty(this.peek().text)) {
+      primary = { type: AST.Literal, value: this.options.literals[this.consume().text]};
+    } else if (this.peek().identifier) {
+      primary = this.identifier();
+    } else if (this.peek().constant) {
+      primary = this.constant();
+    } else {
+      this.throwError('not a primary expression', this.peek());
+    }
+
+    var next;
+    while ((next = this.expect('(', '[', '.'))) {
+      if (next.text === '(') {
+        primary = {type: AST.CallExpression, callee: primary, arguments: this.parseArguments() };
+        this.consume(')');
+      } else if (next.text === '[') {
+        primary = { type: AST.MemberExpression, object: primary, property: this.expression(), computed: true };
+        this.consume(']');
+      } else if (next.text === '.') {
+        primary = { type: AST.MemberExpression, object: primary, property: this.identifier(), computed: false };
+      } else {
+        this.throwError('IMPOSSIBLE');
+      }
+    }
+    return primary;
+  },
+
+  filter: function(baseExpression) {
+    var args = [baseExpression];
+    var result = {type: AST.CallExpression, callee: this.identifier(), arguments: args, filter: true};
+
+    while (this.expect(':')) {
+      args.push(this.expression());
+    }
+
+    return result;
+  },
+
+  parseArguments: function() {
+    var args = [];
+    if (this.peekToken().text !== ')') {
+      do {
+        args.push(this.filterChain());
+      } while (this.expect(','));
+    }
+    return args;
+  },
+
+  identifier: function() {
+    var token = this.consume();
+    if (!token.identifier) {
+      this.throwError('is not a valid identifier', token);
+    }
+    return { type: AST.Identifier, name: token.text };
+  },
+
+  constant: function() {
+    // TODO check that it is a constant
+    return { type: AST.Literal, value: this.consume().value };
+  },
+
+  arrayDeclaration: function() {
+    var elements = [];
+    if (this.peekToken().text !== ']') {
+      do {
+        if (this.peek(']')) {
+          // Support trailing commas per ES5.1.
+          break;
+        }
+        elements.push(this.expression());
+      } while (this.expect(','));
+    }
+    this.consume(']');
+
+    return { type: AST.ArrayExpression, elements: elements };
+  },
+
+  object: function() {
+    var properties = [], property;
+    if (this.peekToken().text !== '}') {
+      do {
+        if (this.peek('}')) {
+          // Support trailing commas per ES5.1.
+          break;
+        }
+        property = {type: AST.Property, kind: 'init'};
+        if (this.peek().constant) {
+          property.key = this.constant();
+          property.computed = false;
+          this.consume(':');
+          property.value = this.expression();
+        } else if (this.peek().identifier) {
+          property.key = this.identifier();
+          property.computed = false;
+          if (this.peek(':')) {
+            this.consume(':');
+            property.value = this.expression();
+          } else {
+            property.value = property.key;
+          }
+        } else if (this.peek('[')) {
+          this.consume('[');
+          property.key = this.expression();
+          this.consume(']');
+          property.computed = true;
+          this.consume(':');
+          property.value = this.expression();
+        } else {
+          this.throwError('invalid key', this.peek());
+        }
+        properties.push(property);
+      } while (this.expect(','));
+    }
+    this.consume('}');
+
+    return {type: AST.ObjectExpression, properties: properties };
+  },
+
+  throwError: function(msg, token) {
+    throw $parseMinErr('syntax',
+        'Syntax Error: Token \'{0}\' {1} at column {2} of the expression [{3}] starting at [{4}].',
+          token.text, msg, (token.index + 1), this.text, this.text.substring(token.index));
+  },
+
+  consume: function(e1) {
+    if (this.tokens.length === 0) {
+      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
+    }
+
+    var token = this.expect(e1);
+    if (!token) {
+      this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());
+    }
+    return token;
+  },
+
+  peekToken: function() {
+    if (this.tokens.length === 0) {
+      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
+    }
+    return this.tokens[0];
+  },
+
+  peek: function(e1, e2, e3, e4) {
+    return this.peekAhead(0, e1, e2, e3, e4);
+  },
+
+  peekAhead: function(i, e1, e2, e3, e4) {
+    if (this.tokens.length > i) {
+      var token = this.tokens[i];
+      var t = token.text;
+      if (t === e1 || t === e2 || t === e3 || t === e4 ||
+          (!e1 && !e2 && !e3 && !e4)) {
+        return token;
+      }
+    }
+    return false;
+  },
+
+  expect: function(e1, e2, e3, e4) {
+    var token = this.peek(e1, e2, e3, e4);
+    if (token) {
+      this.tokens.shift();
+      return token;
+    }
+    return false;
+  },
+
+  selfReferential: {
+    'this': {type: AST.ThisExpression },
+    '$locals': {type: AST.LocalsExpression }
+  }
+};
+
+function ifDefined(v, d) {
+  return typeof v !== 'undefined' ? v : d;
+}
+
+function plusFn(l, r) {
+  if (typeof l === 'undefined') return r;
+  if (typeof r === 'undefined') return l;
+  return l + r;
+}
+
+function isStateless($filter, filterName) {
+  var fn = $filter(filterName);
+  return !fn.$stateful;
+}
+
+function findConstantAndWatchExpressions(ast, $filter) {
+  var allConstants;
+  var argsToWatch;
+  var isStatelessFilter;
+  switch (ast.type) {
+  case AST.Program:
+    allConstants = true;
+    forEach(ast.body, function(expr) {
+      findConstantAndWatchExpressions(expr.expression, $filter);
+      allConstants = allConstants && expr.expression.constant;
+    });
+    ast.constant = allConstants;
+    break;
+  case AST.Literal:
+    ast.constant = true;
+    ast.toWatch = [];
+    break;
+  case AST.UnaryExpression:
+    findConstantAndWatchExpressions(ast.argument, $filter);
+    ast.constant = ast.argument.constant;
+    ast.toWatch = ast.argument.toWatch;
+    break;
+  case AST.BinaryExpression:
+    findConstantAndWatchExpressions(ast.left, $filter);
+    findConstantAndWatchExpressions(ast.right, $filter);
+    ast.constant = ast.left.constant && ast.right.constant;
+    ast.toWatch = ast.left.toWatch.concat(ast.right.toWatch);
+    break;
+  case AST.LogicalExpression:
+    findConstantAndWatchExpressions(ast.left, $filter);
+    findConstantAndWatchExpressions(ast.right, $filter);
+    ast.constant = ast.left.constant && ast.right.constant;
+    ast.toWatch = ast.constant ? [] : [ast];
+    break;
+  case AST.ConditionalExpression:
+    findConstantAndWatchExpressions(ast.test, $filter);
+    findConstantAndWatchExpressions(ast.alternate, $filter);
+    findConstantAndWatchExpressions(ast.consequent, $filter);
+    ast.constant = ast.test.constant && ast.alternate.constant && ast.consequent.constant;
+    ast.toWatch = ast.constant ? [] : [ast];
+    break;
+  case AST.Identifier:
+    ast.constant = false;
+    ast.toWatch = [ast];
+    break;
+  case AST.MemberExpression:
+    findConstantAndWatchExpressions(ast.object, $filter);
+    if (ast.computed) {
+      findConstantAndWatchExpressions(ast.property, $filter);
+    }
+    ast.constant = ast.object.constant && (!ast.computed || ast.property.constant);
+    ast.toWatch = [ast];
+    break;
+  case AST.CallExpression:
+    isStatelessFilter = ast.filter ? isStateless($filter, ast.callee.name) : false;
+    allConstants = isStatelessFilter;
+    argsToWatch = [];
+    forEach(ast.arguments, function(expr) {
+      findConstantAndWatchExpressions(expr, $filter);
+      allConstants = allConstants && expr.constant;
+      if (!expr.constant) {
+        argsToWatch.push.apply(argsToWatch, expr.toWatch);
+      }
+    });
+    ast.constant = allConstants;
+    ast.toWatch = isStatelessFilter ? argsToWatch : [ast];
+    break;
+  case AST.AssignmentExpression:
+    findConstantAndWatchExpressions(ast.left, $filter);
+    findConstantAndWatchExpressions(ast.right, $filter);
+    ast.constant = ast.left.constant && ast.right.constant;
+    ast.toWatch = [ast];
+    break;
+  case AST.ArrayExpression:
+    allConstants = true;
+    argsToWatch = [];
+    forEach(ast.elements, function(expr) {
+      findConstantAndWatchExpressions(expr, $filter);
+      allConstants = allConstants && expr.constant;
+      if (!expr.constant) {
+        argsToWatch.push.apply(argsToWatch, expr.toWatch);
+      }
+    });
+    ast.constant = allConstants;
+    ast.toWatch = argsToWatch;
+    break;
+  case AST.ObjectExpression:
+    allConstants = true;
+    argsToWatch = [];
+    forEach(ast.properties, function(property) {
+      findConstantAndWatchExpressions(property.value, $filter);
+      allConstants = allConstants && property.value.constant && !property.computed;
+      if (!property.value.constant) {
+        argsToWatch.push.apply(argsToWatch, property.value.toWatch);
+      }
+      if (property.computed) {
+        findConstantAndWatchExpressions(property.key, $filter);
+        if (!property.key.constant) {
+          argsToWatch.push.apply(argsToWatch, property.key.toWatch);
+        }
+      }
+
+    });
+    ast.constant = allConstants;
+    ast.toWatch = argsToWatch;
+    break;
+  case AST.ThisExpression:
+    ast.constant = false;
+    ast.toWatch = [];
+    break;
+  case AST.LocalsExpression:
+    ast.constant = false;
+    ast.toWatch = [];
+    break;
+  }
+}
+
+function getInputs(body) {
+  if (body.length !== 1) return;
+  var lastExpression = body[0].expression;
+  var candidate = lastExpression.toWatch;
+  if (candidate.length !== 1) return candidate;
+  return candidate[0] !== lastExpression ? candidate : undefined;
+}
+
+function isAssignable(ast) {
+  return ast.type === AST.Identifier || ast.type === AST.MemberExpression;
+}
+
+function assignableAST(ast) {
+  if (ast.body.length === 1 && isAssignable(ast.body[0].expression)) {
+    return {type: AST.AssignmentExpression, left: ast.body[0].expression, right: {type: AST.NGValueParameter}, operator: '='};
+  }
+}
+
+function isLiteral(ast) {
+  return ast.body.length === 0 ||
+      ast.body.length === 1 && (
+      ast.body[0].expression.type === AST.Literal ||
+      ast.body[0].expression.type === AST.ArrayExpression ||
+      ast.body[0].expression.type === AST.ObjectExpression);
+}
+
+function isConstant(ast) {
+  return ast.constant;
+}
+
+function ASTCompiler(astBuilder, $filter) {
+  this.astBuilder = astBuilder;
+  this.$filter = $filter;
+}
+
+ASTCompiler.prototype = {
+  compile: function(expression) {
+    var self = this;
+    var ast = this.astBuilder.ast(expression);
+    this.state = {
+      nextId: 0,
+      filters: {},
+      fn: {vars: [], body: [], own: {}},
+      assign: {vars: [], body: [], own: {}},
+      inputs: []
+    };
+    findConstantAndWatchExpressions(ast, self.$filter);
+    var extra = '';
+    var assignable;
+    this.stage = 'assign';
+    if ((assignable = assignableAST(ast))) {
+      this.state.computing = 'assign';
+      var result = this.nextId();
+      this.recurse(assignable, result);
+      this.return_(result);
+      extra = 'fn.assign=' + this.generateFunction('assign', 's,v,l');
+    }
+    var toWatch = getInputs(ast.body);
+    self.stage = 'inputs';
+    forEach(toWatch, function(watch, key) {
+      var fnKey = 'fn' + key;
+      self.state[fnKey] = {vars: [], body: [], own: {}};
+      self.state.computing = fnKey;
+      var intoId = self.nextId();
+      self.recurse(watch, intoId);
+      self.return_(intoId);
+      self.state.inputs.push(fnKey);
+      watch.watchId = key;
+    });
+    this.state.computing = 'fn';
+    this.stage = 'main';
+    this.recurse(ast);
+    var fnString =
+      // The build and minification steps remove the string "use strict" from the code, but this is done using a regex.
+      // This is a workaround for this until we do a better job at only removing the prefix only when we should.
+      '"' + this.USE + ' ' + this.STRICT + '";\n' +
+      this.filterPrefix() +
+      'var fn=' + this.generateFunction('fn', 's,l,a,i') +
+      extra +
+      this.watchFns() +
+      'return fn;';
+
+    // eslint-disable-next-line no-new-func
+    var fn = (new Function('$filter',
+        'getStringValue',
+        'ifDefined',
+        'plus',
+        fnString))(
+          this.$filter,
+          getStringValue,
+          ifDefined,
+          plusFn);
+    this.state = this.stage = undefined;
+    fn.literal = isLiteral(ast);
+    fn.constant = isConstant(ast);
+    return fn;
+  },
+
+  USE: 'use',
+
+  STRICT: 'strict',
+
+  watchFns: function() {
+    var result = [];
+    var fns = this.state.inputs;
+    var self = this;
+    forEach(fns, function(name) {
+      result.push('var ' + name + '=' + self.generateFunction(name, 's'));
+    });
+    if (fns.length) {
+      result.push('fn.inputs=[' + fns.join(',') + '];');
+    }
+    return result.join('');
+  },
+
+  generateFunction: function(name, params) {
+    return 'function(' + params + '){' +
+        this.varsPrefix(name) +
+        this.body(name) +
+        '};';
+  },
+
+  filterPrefix: function() {
+    var parts = [];
+    var self = this;
+    forEach(this.state.filters, function(id, filter) {
+      parts.push(id + '=$filter(' + self.escape(filter) + ')');
+    });
+    if (parts.length) return 'var ' + parts.join(',') + ';';
+    return '';
+  },
+
+  varsPrefix: function(section) {
+    return this.state[section].vars.length ? 'var ' + this.state[section].vars.join(',') + ';' : '';
+  },
+
+  body: function(section) {
+    return this.state[section].body.join('');
+  },
+
+  recurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {
+    var left, right, self = this, args, expression, computed;
+    recursionFn = recursionFn || noop;
+    if (!skipWatchIdCheck && isDefined(ast.watchId)) {
+      intoId = intoId || this.nextId();
+      this.if_('i',
+        this.lazyAssign(intoId, this.computedMember('i', ast.watchId)),
+        this.lazyRecurse(ast, intoId, nameId, recursionFn, create, true)
+      );
+      return;
+    }
+    switch (ast.type) {
+    case AST.Program:
+      forEach(ast.body, function(expression, pos) {
+        self.recurse(expression.expression, undefined, undefined, function(expr) { right = expr; });
+        if (pos !== ast.body.length - 1) {
+          self.current().body.push(right, ';');
+        } else {
+          self.return_(right);
+        }
+      });
+      break;
+    case AST.Literal:
+      expression = this.escape(ast.value);
+      this.assign(intoId, expression);
+      recursionFn(intoId || expression);
+      break;
+    case AST.UnaryExpression:
+      this.recurse(ast.argument, undefined, undefined, function(expr) { right = expr; });
+      expression = ast.operator + '(' + this.ifDefined(right, 0) + ')';
+      this.assign(intoId, expression);
+      recursionFn(expression);
+      break;
+    case AST.BinaryExpression:
+      this.recurse(ast.left, undefined, undefined, function(expr) { left = expr; });
+      this.recurse(ast.right, undefined, undefined, function(expr) { right = expr; });
+      if (ast.operator === '+') {
+        expression = this.plus(left, right);
+      } else if (ast.operator === '-') {
+        expression = this.ifDefined(left, 0) + ast.operator + this.ifDefined(right, 0);
+      } else {
+        expression = '(' + left + ')' + ast.operator + '(' + right + ')';
+      }
+      this.assign(intoId, expression);
+      recursionFn(expression);
+      break;
+    case AST.LogicalExpression:
+      intoId = intoId || this.nextId();
+      self.recurse(ast.left, intoId);
+      self.if_(ast.operator === '&&' ? intoId : self.not(intoId), self.lazyRecurse(ast.right, intoId));
+      recursionFn(intoId);
+      break;
+    case AST.ConditionalExpression:
+      intoId = intoId || this.nextId();
+      self.recurse(ast.test, intoId);
+      self.if_(intoId, self.lazyRecurse(ast.alternate, intoId), self.lazyRecurse(ast.consequent, intoId));
+      recursionFn(intoId);
+      break;
+    case AST.Identifier:
+      intoId = intoId || this.nextId();
+      if (nameId) {
+        nameId.context = self.stage === 'inputs' ? 's' : this.assign(this.nextId(), this.getHasOwnProperty('l', ast.name) + '?l:s');
+        nameId.computed = false;
+        nameId.name = ast.name;
+      }
+      self.if_(self.stage === 'inputs' || self.not(self.getHasOwnProperty('l', ast.name)),
+        function() {
+          self.if_(self.stage === 'inputs' || 's', function() {
+            if (create && create !== 1) {
+              self.if_(
+                self.isNull(self.nonComputedMember('s', ast.name)),
+                self.lazyAssign(self.nonComputedMember('s', ast.name), '{}'));
+            }
+            self.assign(intoId, self.nonComputedMember('s', ast.name));
+          });
+        }, intoId && self.lazyAssign(intoId, self.nonComputedMember('l', ast.name))
+        );
+      recursionFn(intoId);
+      break;
+    case AST.MemberExpression:
+      left = nameId && (nameId.context = this.nextId()) || this.nextId();
+      intoId = intoId || this.nextId();
+      self.recurse(ast.object, left, undefined, function() {
+        self.if_(self.notNull(left), function() {
+          if (ast.computed) {
+            right = self.nextId();
+            self.recurse(ast.property, right);
+            self.getStringValue(right);
+            if (create && create !== 1) {
+              self.if_(self.not(self.computedMember(left, right)), self.lazyAssign(self.computedMember(left, right), '{}'));
+            }
+            expression = self.computedMember(left, right);
+            self.assign(intoId, expression);
+            if (nameId) {
+              nameId.computed = true;
+              nameId.name = right;
+            }
+          } else {
+            if (create && create !== 1) {
+              self.if_(self.isNull(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), '{}'));
+            }
+            expression = self.nonComputedMember(left, ast.property.name);
+            self.assign(intoId, expression);
+            if (nameId) {
+              nameId.computed = false;
+              nameId.name = ast.property.name;
+            }
+          }
+        }, function() {
+          self.assign(intoId, 'undefined');
+        });
+        recursionFn(intoId);
+      }, !!create);
+      break;
+    case AST.CallExpression:
+      intoId = intoId || this.nextId();
+      if (ast.filter) {
+        right = self.filter(ast.callee.name);
+        args = [];
+        forEach(ast.arguments, function(expr) {
+          var argument = self.nextId();
+          self.recurse(expr, argument);
+          args.push(argument);
+        });
+        expression = right + '(' + args.join(',') + ')';
+        self.assign(intoId, expression);
+        recursionFn(intoId);
+      } else {
+        right = self.nextId();
+        left = {};
+        args = [];
+        self.recurse(ast.callee, right, left, function() {
+          self.if_(self.notNull(right), function() {
+            forEach(ast.arguments, function(expr) {
+              self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) {
+                args.push(argument);
+              });
+            });
+            if (left.name) {
+              expression = self.member(left.context, left.name, left.computed) + '(' + args.join(',') + ')';
+            } else {
+              expression = right + '(' + args.join(',') + ')';
+            }
+            self.assign(intoId, expression);
+          }, function() {
+            self.assign(intoId, 'undefined');
+          });
+          recursionFn(intoId);
+        });
+      }
+      break;
+    case AST.AssignmentExpression:
+      right = this.nextId();
+      left = {};
+      this.recurse(ast.left, undefined, left, function() {
+        self.if_(self.notNull(left.context), function() {
+          self.recurse(ast.right, right);
+          expression = self.member(left.context, left.name, left.computed) + ast.operator + right;
+          self.assign(intoId, expression);
+          recursionFn(intoId || expression);
+        });
+      }, 1);
+      break;
+    case AST.ArrayExpression:
+      args = [];
+      forEach(ast.elements, function(expr) {
+        self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) {
+          args.push(argument);
+        });
+      });
+      expression = '[' + args.join(',') + ']';
+      this.assign(intoId, expression);
+      recursionFn(intoId || expression);
+      break;
+    case AST.ObjectExpression:
+      args = [];
+      computed = false;
+      forEach(ast.properties, function(property) {
+        if (property.computed) {
+          computed = true;
+        }
+      });
+      if (computed) {
+        intoId = intoId || this.nextId();
+        this.assign(intoId, '{}');
+        forEach(ast.properties, function(property) {
+          if (property.computed) {
+            left = self.nextId();
+            self.recurse(property.key, left);
+          } else {
+            left = property.key.type === AST.Identifier ?
+                       property.key.name :
+                       ('' + property.key.value);
+          }
+          right = self.nextId();
+          self.recurse(property.value, right);
+          self.assign(self.member(intoId, left, property.computed), right);
+        });
+      } else {
+        forEach(ast.properties, function(property) {
+          self.recurse(property.value, ast.constant ? undefined : self.nextId(), undefined, function(expr) {
+            args.push(self.escape(
+                property.key.type === AST.Identifier ? property.key.name :
+                  ('' + property.key.value)) +
+                ':' + expr);
+          });
+        });
+        expression = '{' + args.join(',') + '}';
+        this.assign(intoId, expression);
+      }
+      recursionFn(intoId || expression);
+      break;
+    case AST.ThisExpression:
+      this.assign(intoId, 's');
+      recursionFn(intoId || 's');
+      break;
+    case AST.LocalsExpression:
+      this.assign(intoId, 'l');
+      recursionFn(intoId || 'l');
+      break;
+    case AST.NGValueParameter:
+      this.assign(intoId, 'v');
+      recursionFn(intoId || 'v');
+      break;
+    }
+  },
+
+  getHasOwnProperty: function(element, property) {
+    var key = element + '.' + property;
+    var own = this.current().own;
+    if (!own.hasOwnProperty(key)) {
+      own[key] = this.nextId(false, element + '&&(' + this.escape(property) + ' in ' + element + ')');
+    }
+    return own[key];
+  },
+
+  assign: function(id, value) {
+    if (!id) return;
+    this.current().body.push(id, '=', value, ';');
+    return id;
+  },
+
+  filter: function(filterName) {
+    if (!this.state.filters.hasOwnProperty(filterName)) {
+      this.state.filters[filterName] = this.nextId(true);
+    }
+    return this.state.filters[filterName];
+  },
+
+  ifDefined: function(id, defaultValue) {
+    return 'ifDefined(' + id + ',' + this.escape(defaultValue) + ')';
+  },
+
+  plus: function(left, right) {
+    return 'plus(' + left + ',' + right + ')';
+  },
+
+  return_: function(id) {
+    this.current().body.push('return ', id, ';');
+  },
+
+  if_: function(test, alternate, consequent) {
+    if (test === true) {
+      alternate();
+    } else {
+      var body = this.current().body;
+      body.push('if(', test, '){');
+      alternate();
+      body.push('}');
+      if (consequent) {
+        body.push('else{');
+        consequent();
+        body.push('}');
+      }
+    }
+  },
+
+  not: function(expression) {
+    return '!(' + expression + ')';
+  },
+
+  isNull: function(expression) {
+    return expression + '==null';
+  },
+
+  notNull: function(expression) {
+    return expression + '!=null';
+  },
+
+  nonComputedMember: function(left, right) {
+    var SAFE_IDENTIFIER = /^[$_a-zA-Z][$_a-zA-Z0-9]*$/;
+    var UNSAFE_CHARACTERS = /[^$_a-zA-Z0-9]/g;
+    if (SAFE_IDENTIFIER.test(right)) {
+      return left + '.' + right;
+    } else {
+      return left  + '["' + right.replace(UNSAFE_CHARACTERS, this.stringEscapeFn) + '"]';
+    }
+  },
+
+  computedMember: function(left, right) {
+    return left + '[' + right + ']';
+  },
+
+  member: function(left, right, computed) {
+    if (computed) return this.computedMember(left, right);
+    return this.nonComputedMember(left, right);
+  },
+
+  getStringValue: function(item) {
+    this.assign(item, 'getStringValue(' + item + ')');
+  },
+
+  lazyRecurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {
+    var self = this;
+    return function() {
+      self.recurse(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck);
+    };
+  },
+
+  lazyAssign: function(id, value) {
+    var self = this;
+    return function() {
+      self.assign(id, value);
+    };
+  },
+
+  stringEscapeRegex: /[^ a-zA-Z0-9]/g,
+
+  stringEscapeFn: function(c) {
+    return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4);
+  },
+
+  escape: function(value) {
+    if (isString(value)) return '\'' + value.replace(this.stringEscapeRegex, this.stringEscapeFn) + '\'';
+    if (isNumber(value)) return value.toString();
+    if (value === true) return 'true';
+    if (value === false) return 'false';
+    if (value === null) return 'null';
+    if (typeof value === 'undefined') return 'undefined';
+
+    throw $parseMinErr('esc', 'IMPOSSIBLE');
+  },
+
+  nextId: function(skip, init) {
+    var id = 'v' + (this.state.nextId++);
+    if (!skip) {
+      this.current().vars.push(id + (init ? '=' + init : ''));
+    }
+    return id;
+  },
+
+  current: function() {
+    return this.state[this.state.computing];
+  }
+};
+
+
+function ASTInterpreter(astBuilder, $filter) {
+  this.astBuilder = astBuilder;
+  this.$filter = $filter;
+}
+
+ASTInterpreter.prototype = {
+  compile: function(expression) {
+    var self = this;
+    var ast = this.astBuilder.ast(expression);
+    findConstantAndWatchExpressions(ast, self.$filter);
+    var assignable;
+    var assign;
+    if ((assignable = assignableAST(ast))) {
+      assign = this.recurse(assignable);
+    }
+    var toWatch = getInputs(ast.body);
+    var inputs;
+    if (toWatch) {
+      inputs = [];
+      forEach(toWatch, function(watch, key) {
+        var input = self.recurse(watch);
+        watch.input = input;
+        inputs.push(input);
+        watch.watchId = key;
+      });
+    }
+    var expressions = [];
+    forEach(ast.body, function(expression) {
+      expressions.push(self.recurse(expression.expression));
+    });
+    var fn = ast.body.length === 0 ? noop :
+             ast.body.length === 1 ? expressions[0] :
+             function(scope, locals) {
+               var lastValue;
+               forEach(expressions, function(exp) {
+                 lastValue = exp(scope, locals);
+               });
+               return lastValue;
+             };
+    if (assign) {
+      fn.assign = function(scope, value, locals) {
+        return assign(scope, locals, value);
+      };
+    }
+    if (inputs) {
+      fn.inputs = inputs;
+    }
+    fn.literal = isLiteral(ast);
+    fn.constant = isConstant(ast);
+    return fn;
+  },
+
+  recurse: function(ast, context, create) {
+    var left, right, self = this, args;
+    if (ast.input) {
+      return this.inputs(ast.input, ast.watchId);
+    }
+    switch (ast.type) {
+    case AST.Literal:
+      return this.value(ast.value, context);
+    case AST.UnaryExpression:
+      right = this.recurse(ast.argument);
+      return this['unary' + ast.operator](right, context);
+    case AST.BinaryExpression:
+      left = this.recurse(ast.left);
+      right = this.recurse(ast.right);
+      return this['binary' + ast.operator](left, right, context);
+    case AST.LogicalExpression:
+      left = this.recurse(ast.left);
+      right = this.recurse(ast.right);
+      return this['binary' + ast.operator](left, right, context);
+    case AST.ConditionalExpression:
+      return this['ternary?:'](
+        this.recurse(ast.test),
+        this.recurse(ast.alternate),
+        this.recurse(ast.consequent),
+        context
+      );
+    case AST.Identifier:
+      return self.identifier(ast.name, context, create);
+    case AST.MemberExpression:
+      left = this.recurse(ast.object, false, !!create);
+      if (!ast.computed) {
+        right = ast.property.name;
+      }
+      if (ast.computed) right = this.recurse(ast.property);
+      return ast.computed ?
+        this.computedMember(left, right, context, create) :
+        this.nonComputedMember(left, right, context, create);
+    case AST.CallExpression:
+      args = [];
+      forEach(ast.arguments, function(expr) {
+        args.push(self.recurse(expr));
+      });
+      if (ast.filter) right = this.$filter(ast.callee.name);
+      if (!ast.filter) right = this.recurse(ast.callee, true);
+      return ast.filter ?
+        function(scope, locals, assign, inputs) {
+          var values = [];
+          for (var i = 0; i < args.length; ++i) {
+            values.push(args[i](scope, locals, assign, inputs));
+          }
+          var value = right.apply(undefined, values, inputs);
+          return context ? {context: undefined, name: undefined, value: value} : value;
+        } :
+        function(scope, locals, assign, inputs) {
+          var rhs = right(scope, locals, assign, inputs);
+          var value;
+          if (rhs.value != null) {
+            var values = [];
+            for (var i = 0; i < args.length; ++i) {
+              values.push(args[i](scope, locals, assign, inputs));
+            }
+            value = rhs.value.apply(rhs.context, values);
+          }
+          return context ? {value: value} : value;
+        };
+    case AST.AssignmentExpression:
+      left = this.recurse(ast.left, true, 1);
+      right = this.recurse(ast.right);
+      return function(scope, locals, assign, inputs) {
+        var lhs = left(scope, locals, assign, inputs);
+        var rhs = right(scope, locals, assign, inputs);
+        lhs.context[lhs.name] = rhs;
+        return context ? {value: rhs} : rhs;
+      };
+    case AST.ArrayExpression:
+      args = [];
+      forEach(ast.elements, function(expr) {
+        args.push(self.recurse(expr));
+      });
+      return function(scope, locals, assign, inputs) {
+        var value = [];
+        for (var i = 0; i < args.length; ++i) {
+          value.push(args[i](scope, locals, assign, inputs));
+        }
+        return context ? {value: value} : value;
+      };
+    case AST.ObjectExpression:
+      args = [];
+      forEach(ast.properties, function(property) {
+        if (property.computed) {
+          args.push({key: self.recurse(property.key),
+                     computed: true,
+                     value: self.recurse(property.value)
+          });
+        } else {
+          args.push({key: property.key.type === AST.Identifier ?
+                          property.key.name :
+                          ('' + property.key.value),
+                     computed: false,
+                     value: self.recurse(property.value)
+          });
+        }
+      });
+      return function(scope, locals, assign, inputs) {
+        var value = {};
+        for (var i = 0; i < args.length; ++i) {
+          if (args[i].computed) {
+            value[args[i].key(scope, locals, assign, inputs)] = args[i].value(scope, locals, assign, inputs);
+          } else {
+            value[args[i].key] = args[i].value(scope, locals, assign, inputs);
+          }
+        }
+        return context ? {value: value} : value;
+      };
+    case AST.ThisExpression:
+      return function(scope) {
+        return context ? {value: scope} : scope;
+      };
+    case AST.LocalsExpression:
+      return function(scope, locals) {
+        return context ? {value: locals} : locals;
+      };
+    case AST.NGValueParameter:
+      return function(scope, locals, assign) {
+        return context ? {value: assign} : assign;
+      };
+    }
+  },
+
+  'unary+': function(argument, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = argument(scope, locals, assign, inputs);
+      if (isDefined(arg)) {
+        arg = +arg;
+      } else {
+        arg = 0;
+      }
+      return context ? {value: arg} : arg;
+    };
+  },
+  'unary-': function(argument, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = argument(scope, locals, assign, inputs);
+      if (isDefined(arg)) {
+        arg = -arg;
+      } else {
+        arg = -0;
+      }
+      return context ? {value: arg} : arg;
+    };
+  },
+  'unary!': function(argument, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = !argument(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary+': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var lhs = left(scope, locals, assign, inputs);
+      var rhs = right(scope, locals, assign, inputs);
+      var arg = plusFn(lhs, rhs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary-': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var lhs = left(scope, locals, assign, inputs);
+      var rhs = right(scope, locals, assign, inputs);
+      var arg = (isDefined(lhs) ? lhs : 0) - (isDefined(rhs) ? rhs : 0);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary*': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) * right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary/': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) / right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary%': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) % right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary===': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) === right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary!==': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) !== right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary==': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      // eslint-disable-next-line eqeqeq
+      var arg = left(scope, locals, assign, inputs) == right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary!=': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      // eslint-disable-next-line eqeqeq
+      var arg = left(scope, locals, assign, inputs) != right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary<': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) < right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary>': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) > right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary<=': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) <= right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary>=': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) >= right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary&&': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) && right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'binary||': function(left, right, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = left(scope, locals, assign, inputs) || right(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  'ternary?:': function(test, alternate, consequent, context) {
+    return function(scope, locals, assign, inputs) {
+      var arg = test(scope, locals, assign, inputs) ? alternate(scope, locals, assign, inputs) : consequent(scope, locals, assign, inputs);
+      return context ? {value: arg} : arg;
+    };
+  },
+  value: function(value, context) {
+    return function() { return context ? {context: undefined, name: undefined, value: value} : value; };
+  },
+  identifier: function(name, context, create) {
+    return function(scope, locals, assign, inputs) {
+      var base = locals && (name in locals) ? locals : scope;
+      if (create && create !== 1 && base && base[name] == null) {
+        base[name] = {};
+      }
+      var value = base ? base[name] : undefined;
+      if (context) {
+        return {context: base, name: name, value: value};
+      } else {
+        return value;
+      }
+    };
+  },
+  computedMember: function(left, right, context, create) {
+    return function(scope, locals, assign, inputs) {
+      var lhs = left(scope, locals, assign, inputs);
+      var rhs;
+      var value;
+      if (lhs != null) {
+        rhs = right(scope, locals, assign, inputs);
+        rhs = getStringValue(rhs);
+        if (create && create !== 1) {
+          if (lhs && !(lhs[rhs])) {
+            lhs[rhs] = {};
+          }
+        }
+        value = lhs[rhs];
+      }
+      if (context) {
+        return {context: lhs, name: rhs, value: value};
+      } else {
+        return value;
+      }
+    };
+  },
+  nonComputedMember: function(left, right, context, create) {
+    return function(scope, locals, assign, inputs) {
+      var lhs = left(scope, locals, assign, inputs);
+      if (create && create !== 1) {
+        if (lhs && lhs[right] == null) {
+          lhs[right] = {};
+        }
+      }
+      var value = lhs != null ? lhs[right] : undefined;
+      if (context) {
+        return {context: lhs, name: right, value: value};
+      } else {
+        return value;
+      }
+    };
+  },
+  inputs: function(input, watchId) {
+    return function(scope, value, locals, inputs) {
+      if (inputs) return inputs[watchId];
+      return input(scope, value, locals);
+    };
+  }
+};
+
+/**
+ * @constructor
+ */
+var Parser = function Parser(lexer, $filter, options) {
+  this.lexer = lexer;
+  this.$filter = $filter;
+  this.options = options;
+  this.ast = new AST(lexer, options);
+  this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) :
+                                   new ASTCompiler(this.ast, $filter);
+};
+
+Parser.prototype = {
+  constructor: Parser,
+
+  parse: function(text) {
+    return this.astCompiler.compile(text);
+  }
+};
+
+function getValueOf(value) {
+  return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value);
+}
+
+///////////////////////////////////
+
+/**
+ * @ngdoc service
+ * @name $parse
+ * @kind function
+ *
+ * @description
+ *
+ * Converts Angular {@link guide/expression expression} into a function.
+ *
+ * ```js
+ *   var getter = $parse('user.name');
+ *   var setter = getter.assign;
+ *   var context = {user:{name:'angular'}};
+ *   var locals = {user:{name:'local'}};
+ *
+ *   expect(getter(context)).toEqual('angular');
+ *   setter(context, 'newValue');
+ *   expect(context.user.name).toEqual('newValue');
+ *   expect(getter(context, locals)).toEqual('local');
+ * ```
+ *
+ *
+ * @param {string} expression String expression to compile.
+ * @returns {function(context, locals)} a function which represents the compiled expression:
+ *
+ *    * `context` – `{object}` – an object against which any expressions embedded in the strings
+ *      are evaluated against (typically a scope object).
+ *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
+ *      `context`.
+ *
+ *    The returned function also has the following properties:
+ *      * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript
+ *        literal.
+ *      * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript
+ *        constant literals.
+ *      * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be
+ *        set to a function to change its value on the given context.
+ *
+ */
+
+
+/**
+ * @ngdoc provider
+ * @name $parseProvider
+ * @this
+ *
+ * @description
+ * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse}
+ *  service.
+ */
+function $ParseProvider() {
+  var cache = createMap();
+  var literals = {
+    'true': true,
+    'false': false,
+    'null': null,
+    'undefined': undefined
+  };
+  var identStart, identContinue;
+
+  /**
+   * @ngdoc method
+   * @name $parseProvider#addLiteral
+   * @description
+   *
+   * Configure $parse service to add literal values that will be present as literal at expressions.
+   *
+   * @param {string} literalName Token for the literal value. The literal name value must be a valid literal name.
+   * @param {*} literalValue Value for this literal. All literal values must be primitives or `undefined`.
+   *
+   **/
+  this.addLiteral = function(literalName, literalValue) {
+    literals[literalName] = literalValue;
+  };
+
+ /**
+  * @ngdoc method
+  * @name $parseProvider#setIdentifierFns
+  *
+  * @description
+  *
+  * Allows defining the set of characters that are allowed in Angular expressions. The function
+  * `identifierStart` will get called to know if a given character is a valid character to be the
+  * first character for an identifier. The function `identifierContinue` will get called to know if
+  * a given character is a valid character to be a follow-up identifier character. The functions
+  * `identifierStart` and `identifierContinue` will receive as arguments the single character to be
+  * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in
+  * mind that the `string` parameter can be two characters long depending on the character
+  * representation. It is expected for the function to return `true` or `false`, whether that
+  * character is allowed or not.
+  *
+  * Since this function will be called extensively, keep the implementation of these functions fast,
+  * as the performance of these functions have a direct impact on the expressions parsing speed.
+  *
+  * @param {function=} identifierStart The function that will decide whether the given character is
+  *   a valid identifier start character.
+  * @param {function=} identifierContinue The function that will decide whether the given character is
+  *   a valid identifier continue character.
+  */
+  this.setIdentifierFns = function(identifierStart, identifierContinue) {
+    identStart = identifierStart;
+    identContinue = identifierContinue;
+    return this;
+  };
+
+  this.$get = ['$filter', function($filter) {
+    var noUnsafeEval = csp().noUnsafeEval;
+    var $parseOptions = {
+          csp: noUnsafeEval,
+          literals: copy(literals),
+          isIdentifierStart: isFunction(identStart) && identStart,
+          isIdentifierContinue: isFunction(identContinue) && identContinue
+        };
+    return $parse;
+
+    function $parse(exp, interceptorFn) {
+      var parsedExpression, oneTime, cacheKey;
+
+      switch (typeof exp) {
+        case 'string':
+          exp = exp.trim();
+          cacheKey = exp;
+
+          parsedExpression = cache[cacheKey];
+
+          if (!parsedExpression) {
+            if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
+              oneTime = true;
+              exp = exp.substring(2);
+            }
+            var lexer = new Lexer($parseOptions);
+            var parser = new Parser(lexer, $filter, $parseOptions);
+            parsedExpression = parser.parse(exp);
+            if (parsedExpression.constant) {
+              parsedExpression.$$watchDelegate = constantWatchDelegate;
+            } else if (oneTime) {
+              parsedExpression.$$watchDelegate = parsedExpression.literal ?
+                  oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;
+            } else if (parsedExpression.inputs) {
+              parsedExpression.$$watchDelegate = inputsWatchDelegate;
+            }
+            cache[cacheKey] = parsedExpression;
+          }
+          return addInterceptor(parsedExpression, interceptorFn);
+
+        case 'function':
+          return addInterceptor(exp, interceptorFn);
+
+        default:
+          return addInterceptor(noop, interceptorFn);
+      }
+    }
+
+    function expressionInputDirtyCheck(newValue, oldValueOfValue, compareObjectIdentity) {
+
+      if (newValue == null || oldValueOfValue == null) { // null/undefined
+        return newValue === oldValueOfValue;
+      }
+
+      if (typeof newValue === 'object' && !compareObjectIdentity) {
+
+        // attempt to convert the value to a primitive type
+        // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can
+        //             be cheaply dirty-checked
+        newValue = getValueOf(newValue);
+
+        if (typeof newValue === 'object') {
+          // objects/arrays are not supported - deep-watching them would be too expensive
+          return false;
+        }
+
+        // fall-through to the primitive equality check
+      }
+
+      //Primitive or NaN
+      // eslint-disable-next-line no-self-compare
+      return newValue === oldValueOfValue || (newValue !== newValue && oldValueOfValue !== oldValueOfValue);
+    }
+
+    function inputsWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {
+      var inputExpressions = parsedExpression.inputs;
+      var lastResult;
+
+      if (inputExpressions.length === 1) {
+        var oldInputValueOf = expressionInputDirtyCheck; // init to something unique so that equals check fails
+        inputExpressions = inputExpressions[0];
+        return scope.$watch(function expressionInputWatch(scope) {
+          var newInputValue = inputExpressions(scope);
+          if (!expressionInputDirtyCheck(newInputValue, oldInputValueOf, parsedExpression.literal)) {
+            lastResult = parsedExpression(scope, undefined, undefined, [newInputValue]);
+            oldInputValueOf = newInputValue && getValueOf(newInputValue);
+          }
+          return lastResult;
+        }, listener, objectEquality, prettyPrintExpression);
+      }
+
+      var oldInputValueOfValues = [];
+      var oldInputValues = [];
+      for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
+        oldInputValueOfValues[i] = expressionInputDirtyCheck; // init to something unique so that equals check fails
+        oldInputValues[i] = null;
+      }
+
+      return scope.$watch(function expressionInputsWatch(scope) {
+        var changed = false;
+
+        for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
+          var newInputValue = inputExpressions[i](scope);
+          if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i], parsedExpression.literal))) {
+            oldInputValues[i] = newInputValue;
+            oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue);
+          }
+        }
+
+        if (changed) {
+          lastResult = parsedExpression(scope, undefined, undefined, oldInputValues);
+        }
+
+        return lastResult;
+      }, listener, objectEquality, prettyPrintExpression);
+    }
+
+    function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {
+      var unwatch, lastValue;
+      if (parsedExpression.inputs) {
+        unwatch = inputsWatchDelegate(scope, oneTimeListener, objectEquality, parsedExpression, prettyPrintExpression);
+      } else {
+        unwatch = scope.$watch(oneTimeWatch, oneTimeListener, objectEquality);
+      }
+      return unwatch;
+
+      function oneTimeWatch(scope) {
+        return parsedExpression(scope);
+      }
+      function oneTimeListener(value, old, scope) {
+        lastValue = value;
+        if (isFunction(listener)) {
+          listener(value, old, scope);
+        }
+        if (isDefined(value)) {
+          scope.$$postDigest(function() {
+            if (isDefined(lastValue)) {
+              unwatch();
+            }
+          });
+        }
+      }
+    }
+
+    function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) {
+      var unwatch, lastValue;
+      unwatch = scope.$watch(function oneTimeWatch(scope) {
+        return parsedExpression(scope);
+      }, function oneTimeListener(value, old, scope) {
+        lastValue = value;
+        if (isFunction(listener)) {
+          listener(value, old, scope);
+        }
+        if (isAllDefined(value)) {
+          scope.$$postDigest(function() {
+            if (isAllDefined(lastValue)) unwatch();
+          });
+        }
+      }, objectEquality);
+
+      return unwatch;
+
+      function isAllDefined(value) {
+        var allDefined = true;
+        forEach(value, function(val) {
+          if (!isDefined(val)) allDefined = false;
+        });
+        return allDefined;
+      }
+    }
+
+    function constantWatchDelegate(scope, listener, objectEquality, parsedExpression) {
+      var unwatch = scope.$watch(function constantWatch(scope) {
+        unwatch();
+        return parsedExpression(scope);
+      }, listener, objectEquality);
+      return unwatch;
+    }
+
+    function addInterceptor(parsedExpression, interceptorFn) {
+      if (!interceptorFn) return parsedExpression;
+      var watchDelegate = parsedExpression.$$watchDelegate;
+      var useInputs = false;
+
+      var regularWatch =
+          watchDelegate !== oneTimeLiteralWatchDelegate &&
+          watchDelegate !== oneTimeWatchDelegate;
+
+      var fn = regularWatch ? function regularInterceptedExpression(scope, locals, assign, inputs) {
+        var value = useInputs && inputs ? inputs[0] : parsedExpression(scope, locals, assign, inputs);
+        return interceptorFn(value, scope, locals);
+      } : function oneTimeInterceptedExpression(scope, locals, assign, inputs) {
+        var value = parsedExpression(scope, locals, assign, inputs);
+        var result = interceptorFn(value, scope, locals);
+        // we only return the interceptor's result if the
+        // initial value is defined (for bind-once)
+        return isDefined(value) ? result : value;
+      };
+
+      // Propagate $$watchDelegates other then inputsWatchDelegate
+      useInputs = !parsedExpression.inputs;
+      if (parsedExpression.$$watchDelegate &&
+          parsedExpression.$$watchDelegate !== inputsWatchDelegate) {
+        fn.$$watchDelegate = parsedExpression.$$watchDelegate;
+        fn.inputs = parsedExpression.inputs;
+      } else if (!interceptorFn.$stateful) {
+        // If there is an interceptor, but no watchDelegate then treat the interceptor like
+        // we treat filters - it is assumed to be a pure function unless flagged with $stateful
+        fn.$$watchDelegate = inputsWatchDelegate;
+        fn.inputs = parsedExpression.inputs ? parsedExpression.inputs : [parsedExpression];
+      }
+
+      return fn;
+    }
+  }];
+}
+
+/**
+ * @ngdoc service
+ * @name $q
+ * @requires $rootScope
+ *
+ * @description
+ * A service that helps you run functions asynchronously, and use their return values (or exceptions)
+ * when they are done processing.
+ *
+ * This is a [Promises/A+](https://promisesaplus.com/)-compliant implementation of promises/deferred
+ * objects inspired by [Kris Kowal's Q](https://github.com/kriskowal/q).
+ *
+ * $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred
+ * implementations, and the other which resembles ES6 (ES2015) promises to some degree.
+ *
+ * # $q constructor
+ *
+ * The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver`
+ * function as the first argument. This is similar to the native Promise implementation from ES6,
+ * see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
+ *
+ * While the constructor-style use is supported, not all of the supporting methods from ES6 promises are
+ * available yet.
+ *
+ * It can be used like so:
+ *
+ * ```js
+ *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`
+ *   // are available in the current lexical scope (they could have been injected or passed in).
+ *
+ *   function asyncGreet(name) {
+ *     // perform some asynchronous operation, resolve or reject the promise when appropriate.
+ *     return $q(function(resolve, reject) {
+ *       setTimeout(function() {
+ *         if (okToGreet(name)) {
+ *           resolve('Hello, ' + name + '!');
+ *         } else {
+ *           reject('Greeting ' + name + ' is not allowed.');
+ *         }
+ *       }, 1000);
+ *     });
+ *   }
+ *
+ *   var promise = asyncGreet('Robin Hood');
+ *   promise.then(function(greeting) {
+ *     alert('Success: ' + greeting);
+ *   }, function(reason) {
+ *     alert('Failed: ' + reason);
+ *   });
+ * ```
+ *
+ * Note: progress/notify callbacks are not currently supported via the ES6-style interface.
+ *
+ * Note: unlike ES6 behavior, an exception thrown in the constructor function will NOT implicitly reject the promise.
+ *
+ * However, the more traditional CommonJS-style usage is still available, and documented below.
+ *
+ * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an
+ * interface for interacting with an object that represents the result of an action that is
+ * performed asynchronously, and may or may not be finished at any given point in time.
+ *
+ * From the perspective of dealing with error handling, deferred and promise APIs are to
+ * asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.
+ *
+ * ```js
+ *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`
+ *   // are available in the current lexical scope (they could have been injected or passed in).
+ *
+ *   function asyncGreet(name) {
+ *     var deferred = $q.defer();
+ *
+ *     setTimeout(function() {
+ *       deferred.notify('About to greet ' + name + '.');
+ *
+ *       if (okToGreet(name)) {
+ *         deferred.resolve('Hello, ' + name + '!');
+ *       } else {
+ *         deferred.reject('Greeting ' + name + ' is not allowed.');
+ *       }
+ *     }, 1000);
+ *
+ *     return deferred.promise;
+ *   }
+ *
+ *   var promise = asyncGreet('Robin Hood');
+ *   promise.then(function(greeting) {
+ *     alert('Success: ' + greeting);
+ *   }, function(reason) {
+ *     alert('Failed: ' + reason);
+ *   }, function(update) {
+ *     alert('Got notification: ' + update);
+ *   });
+ * ```
+ *
+ * At first it might not be obvious why this extra complexity is worth the trouble. The payoff
+ * comes in the way of guarantees that promise and deferred APIs make, see
+ * https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md.
+ *
+ * Additionally the promise api allows for composition that is very hard to do with the
+ * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach.
+ * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the
+ * section on serial or parallel joining of promises.
+ *
+ * # The Deferred API
+ *
+ * A new instance of deferred is constructed by calling `$q.defer()`.
+ *
+ * The purpose of the deferred object is to expose the associated Promise instance as well as APIs
+ * that can be used for signaling the successful or unsuccessful completion, as well as the status
+ * of the task.
+ *
+ * **Methods**
+ *
+ * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection
+ *   constructed via `$q.reject`, the promise will be rejected instead.
+ * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
+ *   resolving it with a rejection constructed via `$q.reject`.
+ * - `notify(value)` - provides updates on the status of the promise's execution. This may be called
+ *   multiple times before the promise is either resolved or rejected.
+ *
+ * **Properties**
+ *
+ * - promise – `{Promise}` – promise object associated with this deferred.
+ *
+ *
+ * # The Promise API
+ *
+ * A new promise instance is created when a deferred instance is created and can be retrieved by
+ * calling `deferred.promise`.
+ *
+ * The purpose of the promise object is to allow for interested parties to get access to the result
+ * of the deferred task when it completes.
+ *
+ * **Methods**
+ *
+ * - `then(successCallback, [errorCallback], [notifyCallback])` – regardless of when the promise was or
+ *   will be resolved or rejected, `then` calls one of the success or error callbacks asynchronously
+ *   as soon as the result is available. The callbacks are called with a single argument: the result
+ *   or rejection reason. Additionally, the notify callback may be called zero or more times to
+ *   provide a progress indication, before the promise is resolved or rejected.
+ *
+ *   This method *returns a new promise* which is resolved or rejected via the return value of the
+ *   `successCallback`, `errorCallback` (unless that value is a promise, in which case it is resolved
+ *   with the value which is resolved in that promise using
+ *   [promise chaining](http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promises-queues)).
+ *   It also notifies via the return value of the `notifyCallback` method. The promise cannot be
+ *   resolved or rejected from the notifyCallback method. The errorCallback and notifyCallback
+ *   arguments are optional.
+ *
+ * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`
+ *
+ * - `finally(callback, notifyCallback)` – allows you to observe either the fulfillment or rejection of a promise,
+ *   but to do so without modifying the final value. This is useful to release resources or do some
+ *   clean-up that needs to be done whether the promise was rejected or resolved. See the [full
+ *   specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefinallycallback) for
+ *   more information.
+ *
+ * # Chaining promises
+ *
+ * Because calling the `then` method of a promise returns a new derived promise, it is easily
+ * possible to create a chain of promises:
+ *
+ * ```js
+ *   promiseB = promiseA.then(function(result) {
+ *     return result + 1;
+ *   });
+ *
+ *   // promiseB will be resolved immediately after promiseA is resolved and its value
+ *   // will be the result of promiseA incremented by 1
+ * ```
+ *
+ * It is possible to create chains of any length and since a promise can be resolved with another
+ * promise (which will defer its resolution further), it is possible to pause/defer resolution of
+ * the promises at any point in the chain. This makes it possible to implement powerful APIs like
+ * $http's response interceptors.
+ *
+ *
+ * # Differences between Kris Kowal's Q and $q
+ *
+ *  There are two main differences:
+ *
+ * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation
+ *   mechanism in angular, which means faster propagation of resolution or rejection into your
+ *   models and avoiding unnecessary browser repaints, which would result in flickering UI.
+ * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
+ *   all the important functionality needed for common async tasks.
+ *
+ * # Testing
+ *
+ *  ```js
+ *    it('should simulate promise', inject(function($q, $rootScope) {
+ *      var deferred = $q.defer();
+ *      var promise = deferred.promise;
+ *      var resolvedValue;
+ *
+ *      promise.then(function(value) { resolvedValue = value; });
+ *      expect(resolvedValue).toBeUndefined();
+ *
+ *      // Simulate resolving of promise
+ *      deferred.resolve(123);
+ *      // Note that the 'then' function does not get called synchronously.
+ *      // This is because we want the promise API to always be async, whether or not
+ *      // it got called synchronously or asynchronously.
+ *      expect(resolvedValue).toBeUndefined();
+ *
+ *      // Propagate promise resolution to 'then' functions using $apply().
+ *      $rootScope.$apply();
+ *      expect(resolvedValue).toEqual(123);
+ *    }));
+ *  ```
+ *
+ * @param {function(function, function)} resolver Function which is responsible for resolving or
+ *   rejecting the newly created promise. The first parameter is a function which resolves the
+ *   promise, the second parameter is a function which rejects the promise.
+ *
+ * @returns {Promise} The newly created promise.
+ */
+/**
+ * @ngdoc provider
+ * @name $qProvider
+ * @this
+ *
+ * @description
+ */
+function $QProvider() {
+  var errorOnUnhandledRejections = true;
+  this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) {
+    return qFactory(function(callback) {
+      $rootScope.$evalAsync(callback);
+    }, $exceptionHandler, errorOnUnhandledRejections);
+  }];
+
+  /**
+   * @ngdoc method
+   * @name $qProvider#errorOnUnhandledRejections
+   * @kind function
+   *
+   * @description
+   * Retrieves or overrides whether to generate an error when a rejected promise is not handled.
+   * This feature is enabled by default.
+   *
+   * @param {boolean=} value Whether to generate an error when a rejected promise is not handled.
+   * @returns {boolean|ng.$qProvider} Current value when called without a new value or self for
+   *    chaining otherwise.
+   */
+  this.errorOnUnhandledRejections = function(value) {
+    if (isDefined(value)) {
+      errorOnUnhandledRejections = value;
+      return this;
+    } else {
+      return errorOnUnhandledRejections;
+    }
+  };
+}
+
+/** @this */
+function $$QProvider() {
+  var errorOnUnhandledRejections = true;
+  this.$get = ['$browser', '$exceptionHandler', function($browser, $exceptionHandler) {
+    return qFactory(function(callback) {
+      $browser.defer(callback);
+    }, $exceptionHandler, errorOnUnhandledRejections);
+  }];
+
+  this.errorOnUnhandledRejections = function(value) {
+    if (isDefined(value)) {
+      errorOnUnhandledRejections = value;
+      return this;
+    } else {
+      return errorOnUnhandledRejections;
+    }
+  };
+}
+
+/**
+ * Constructs a promise manager.
+ *
+ * @param {function(function)} nextTick Function for executing functions in the next turn.
+ * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for
+ *     debugging purposes.
+ @ param {=boolean} errorOnUnhandledRejections Whether an error should be generated on unhandled
+ *     promises rejections.
+ * @returns {object} Promise manager.
+ */
+function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
+  var $qMinErr = minErr('$q', TypeError);
+  var queueSize = 0;
+  var checkQueue = [];
+
+  /**
+   * @ngdoc method
+   * @name ng.$q#defer
+   * @kind function
+   *
+   * @description
+   * Creates a `Deferred` object which represents a task which will finish in the future.
+   *
+   * @returns {Deferred} Returns a new instance of deferred.
+   */
+  function defer() {
+    return new Deferred();
+  }
+
+  function Deferred() {
+    var promise = this.promise = new Promise();
+    //Non prototype methods necessary to support unbound execution :/
+    this.resolve = function(val) { resolvePromise(promise, val); };
+    this.reject = function(reason) { rejectPromise(promise, reason); };
+    this.notify = function(progress) { notifyPromise(promise, progress); };
+  }
+
+
+  function Promise() {
+    this.$$state = { status: 0 };
+  }
+
+  extend(Promise.prototype, {
+    then: function(onFulfilled, onRejected, progressBack) {
+      if (isUndefined(onFulfilled) && isUndefined(onRejected) && isUndefined(progressBack)) {
+        return this;
+      }
+      var result = new Promise();
+
+      this.$$state.pending = this.$$state.pending || [];
+      this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);
+      if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);
+
+      return result;
+    },
+
+    'catch': function(callback) {
+      return this.then(null, callback);
+    },
+
+    'finally': function(callback, progressBack) {
+      return this.then(function(value) {
+        return handleCallback(value, resolve, callback);
+      }, function(error) {
+        return handleCallback(error, reject, callback);
+      }, progressBack);
+    }
+  });
+
+  function processQueue(state) {
+    var fn, promise, pending;
+
+    pending = state.pending;
+    state.processScheduled = false;
+    state.pending = undefined;
+    try {
+      for (var i = 0, ii = pending.length; i < ii; ++i) {
+        state.pur = true;
+        promise = pending[i][0];
+        fn = pending[i][state.status];
+        try {
+          if (isFunction(fn)) {
+            resolvePromise(promise, fn(state.value));
+          } else if (state.status === 1) {
+            resolvePromise(promise, state.value);
+          } else {
+            rejectPromise(promise, state.value);
+          }
+        } catch (e) {
+          rejectPromise(promise, e);
+        }
+      }
+    } finally {
+      --queueSize;
+      if (errorOnUnhandledRejections && queueSize === 0) {
+        nextTick(processChecks);
+      }
+    }
+  }
+
+  function processChecks() {
+    // eslint-disable-next-line no-unmodified-loop-condition
+    while (!queueSize && checkQueue.length) {
+      var toCheck = checkQueue.shift();
+      if (!toCheck.pur) {
+        toCheck.pur = true;
+        var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value);
+        if (toCheck.value instanceof Error) {
+          exceptionHandler(toCheck.value, errorMessage);
+        } else {
+          exceptionHandler(errorMessage);
+        }
+      }
+    }
+  }
+
+  function scheduleProcessQueue(state) {
+    if (errorOnUnhandledRejections && !state.pending && state.status === 2 && !state.pur) {
+      if (queueSize === 0 && checkQueue.length === 0) {
+        nextTick(processChecks);
+      }
+      checkQueue.push(state);
+    }
+    if (state.processScheduled || !state.pending) return;
+    state.processScheduled = true;
+    ++queueSize;
+    nextTick(function() { processQueue(state); });
+  }
+
+  function resolvePromise(promise, val) {
+    if (promise.$$state.status) return;
+    if (val === promise) {
+      $$reject(promise, $qMinErr(
+        'qcycle',
+        'Expected promise to be resolved with value other than itself \'{0}\'',
+        val));
+    } else {
+      $$resolve(promise, val);
+    }
+
+  }
+
+  function $$resolve(promise, val) {
+    var then;
+    var done = false;
+    try {
+      if (isObject(val) || isFunction(val)) then = val.then;
+      if (isFunction(then)) {
+        promise.$$state.status = -1;
+        then.call(val, doResolve, doReject, doNotify);
+      } else {
+        promise.$$state.value = val;
+        promise.$$state.status = 1;
+        scheduleProcessQueue(promise.$$state);
+      }
+    } catch (e) {
+      doReject(e);
+    }
+
+    function doResolve(val) {
+      if (done) return;
+      done = true;
+      $$resolve(promise, val);
+    }
+    function doReject(val) {
+      if (done) return;
+      done = true;
+      $$reject(promise, val);
+    }
+    function doNotify(progress) {
+      notifyPromise(promise, progress);
+    }
+  }
+
+  function rejectPromise(promise, reason) {
+    if (promise.$$state.status) return;
+    $$reject(promise, reason);
+  }
+
+  function $$reject(promise, reason) {
+    promise.$$state.value = reason;
+    promise.$$state.status = 2;
+    scheduleProcessQueue(promise.$$state);
+  }
+
+  function notifyPromise(promise, progress) {
+    var callbacks = promise.$$state.pending;
+
+    if ((promise.$$state.status <= 0) && callbacks && callbacks.length) {
+      nextTick(function() {
+        var callback, result;
+        for (var i = 0, ii = callbacks.length; i < ii; i++) {
+          result = callbacks[i][0];
+          callback = callbacks[i][3];
+          try {
+            notifyPromise(result, isFunction(callback) ? callback(progress) : progress);
+          } catch (e) {
+            exceptionHandler(e);
+          }
+        }
+      });
+    }
+  }
+
+  /**
+   * @ngdoc method
+   * @name $q#reject
+   * @kind function
+   *
+   * @description
+   * Creates a promise that is resolved as rejected with the specified `reason`. This api should be
+   * used to forward rejection in a chain of promises. If you are dealing with the last promise in
+   * a promise chain, you don't need to worry about it.
+   *
+   * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of
+   * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via
+   * a promise error callback and you want to forward the error to the promise derived from the
+   * current promise, you have to "rethrow" the error by returning a rejection constructed via
+   * `reject`.
+   *
+   * ```js
+   *   promiseB = promiseA.then(function(result) {
+   *     // success: do something and resolve promiseB
+   *     //          with the old or a new result
+   *     return result;
+   *   }, function(reason) {
+   *     // error: handle the error if possible and
+   *     //        resolve promiseB with newPromiseOrValue,
+   *     //        otherwise forward the rejection to promiseB
+   *     if (canHandle(reason)) {
+   *      // handle the error and recover
+   *      return newPromiseOrValue;
+   *     }
+   *     return $q.reject(reason);
+   *   });
+   * ```
+   *
+   * @param {*} reason Constant, message, exception or an object representing the rejection reason.
+   * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
+   */
+  function reject(reason) {
+    var result = new Promise();
+    rejectPromise(result, reason);
+    return result;
+  }
+
+  function handleCallback(value, resolver, callback) {
+    var callbackOutput = null;
+    try {
+      if (isFunction(callback)) callbackOutput = callback();
+    } catch (e) {
+      return reject(e);
+    }
+    if (isPromiseLike(callbackOutput)) {
+      return callbackOutput.then(function() {
+        return resolver(value);
+      }, reject);
+    } else {
+      return resolver(value);
+    }
+  }
+
+  /**
+   * @ngdoc method
+   * @name $q#when
+   * @kind function
+   *
+   * @description
+   * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
+   * This is useful when you are dealing with an object that might or might not be a promise, or if
+   * the promise comes from a source that can't be trusted.
+   *
+   * @param {*} value Value or a promise
+   * @param {Function=} successCallback
+   * @param {Function=} errorCallback
+   * @param {Function=} progressCallback
+   * @returns {Promise} Returns a promise of the passed value or promise
+   */
+
+
+  function when(value, callback, errback, progressBack) {
+    var result = new Promise();
+    resolvePromise(result, value);
+    return result.then(callback, errback, progressBack);
+  }
+
+  /**
+   * @ngdoc method
+   * @name $q#resolve
+   * @kind function
+   *
+   * @description
+   * Alias of {@link ng.$q#when when} to maintain naming consistency with ES6.
+   *
+   * @param {*} value Value or a promise
+   * @param {Function=} successCallback
+   * @param {Function=} errorCallback
+   * @param {Function=} progressCallback
+   * @returns {Promise} Returns a promise of the passed value or promise
+   */
+  var resolve = when;
+
+  /**
+   * @ngdoc method
+   * @name $q#all
+   * @kind function
+   *
+   * @description
+   * Combines multiple promises into a single promise that is resolved when all of the input
+   * promises are resolved.
+   *
+   * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.
+   * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values,
+   *   each value corresponding to the promise at the same index/key in the `promises` array/hash.
+   *   If any of the promises is resolved with a rejection, this resulting promise will be rejected
+   *   with the same rejection value.
+   */
+
+  function all(promises) {
+    var result = new Promise(),
+        counter = 0,
+        results = isArray(promises) ? [] : {};
+
+    forEach(promises, function(promise, key) {
+      counter++;
+      when(promise).then(function(value) {
+        results[key] = value;
+        if (!(--counter)) resolvePromise(result, results);
+      }, function(reason) {
+        rejectPromise(result, reason);
+      });
+    });
+
+    if (counter === 0) {
+      resolvePromise(result, results);
+    }
+
+    return result;
+  }
+
+  /**
+   * @ngdoc method
+   * @name $q#race
+   * @kind function
+   *
+   * @description
+   * Returns a promise that resolves or rejects as soon as one of those promises
+   * resolves or rejects, with the value or reason from that promise.
+   *
+   * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.
+   * @returns {Promise} a promise that resolves or rejects as soon as one of the `promises`
+   * resolves or rejects, with the value or reason from that promise.
+   */
+
+  function race(promises) {
+    var deferred = defer();
+
+    forEach(promises, function(promise) {
+      when(promise).then(deferred.resolve, deferred.reject);
+    });
+
+    return deferred.promise;
+  }
+
+  function $Q(resolver) {
+    if (!isFunction(resolver)) {
+      throw $qMinErr('norslvr', 'Expected resolverFn, got \'{0}\'', resolver);
+    }
+
+    var promise = new Promise();
+
+    function resolveFn(value) {
+      resolvePromise(promise, value);
+    }
+
+    function rejectFn(reason) {
+      rejectPromise(promise, reason);
+    }
+
+    resolver(resolveFn, rejectFn);
+
+    return promise;
+  }
+
+  // Let's make the instanceof operator work for promises, so that
+  // `new $q(fn) instanceof $q` would evaluate to true.
+  $Q.prototype = Promise.prototype;
+
+  $Q.defer = defer;
+  $Q.reject = reject;
+  $Q.when = when;
+  $Q.resolve = resolve;
+  $Q.all = all;
+  $Q.race = race;
+
+  return $Q;
+}
+
+/** @this */
+function $$RAFProvider() { //rAF
+  this.$get = ['$window', '$timeout', function($window, $timeout) {
+    var requestAnimationFrame = $window.requestAnimationFrame ||
+                                $window.webkitRequestAnimationFrame;
+
+    var cancelAnimationFrame = $window.cancelAnimationFrame ||
+                               $window.webkitCancelAnimationFrame ||
+                               $window.webkitCancelRequestAnimationFrame;
+
+    var rafSupported = !!requestAnimationFrame;
+    var raf = rafSupported
+      ? function(fn) {
+          var id = requestAnimationFrame(fn);
+          return function() {
+            cancelAnimationFrame(id);
+          };
+        }
+      : function(fn) {
+          var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666
+          return function() {
+            $timeout.cancel(timer);
+          };
+        };
+
+    raf.supported = rafSupported;
+
+    return raf;
+  }];
+}
+
+/**
+ * DESIGN NOTES
+ *
+ * The design decisions behind the scope are heavily favored for speed and memory consumption.
+ *
+ * The typical use of scope is to watch the expressions, which most of the time return the same
+ * value as last time so we optimize the operation.
+ *
+ * Closures construction is expensive in terms of speed as well as memory:
+ *   - No closures, instead use prototypical inheritance for API
+ *   - Internal state needs to be stored on scope directly, which means that private state is
+ *     exposed as $$____ properties
+ *
+ * Loop operations are optimized by using while(count--) { ... }
+ *   - This means that in order to keep the same order of execution as addition we have to add
+ *     items to the array at the beginning (unshift) instead of at the end (push)
+ *
+ * Child scopes are created and removed often
+ *   - Using an array would be slow since inserts in the middle are expensive; so we use linked lists
+ *
+ * There are fewer watches than observers. This is why you don't want the observer to be implemented
+ * in the same way as watch. Watch requires return of the initialization function which is expensive
+ * to construct.
+ */
+
+
+/**
+ * @ngdoc provider
+ * @name $rootScopeProvider
+ * @description
+ *
+ * Provider for the $rootScope service.
+ */
+
+/**
+ * @ngdoc method
+ * @name $rootScopeProvider#digestTtl
+ * @description
+ *
+ * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and
+ * assuming that the model is unstable.
+ *
+ * The current default is 10 iterations.
+ *
+ * In complex applications it's possible that the dependencies between `$watch`s will result in
+ * several digest iterations. However if an application needs more than the default 10 digest
+ * iterations for its model to stabilize then you should investigate what is causing the model to
+ * continuously change during the digest.
+ *
+ * Increasing the TTL could have performance implications, so you should not change it without
+ * proper justification.
+ *
+ * @param {number} limit The number of digest iterations.
+ */
+
+
+/**
+ * @ngdoc service
+ * @name $rootScope
+ * @this
+ *
+ * @description
+ *
+ * Every application has a single root {@link ng.$rootScope.Scope scope}.
+ * All other scopes are descendant scopes of the root scope. Scopes provide separation
+ * between the model and the view, via a mechanism for watching the model for changes.
+ * They also provide event emission/broadcast and subscription facility. See the
+ * {@link guide/scope developer guide on scopes}.
+ */
+function $RootScopeProvider() {
+  var TTL = 10;
+  var $rootScopeMinErr = minErr('$rootScope');
+  var lastDirtyWatch = null;
+  var applyAsyncId = null;
+
+  this.digestTtl = function(value) {
+    if (arguments.length) {
+      TTL = value;
+    }
+    return TTL;
+  };
+
+  function createChildScopeClass(parent) {
+    function ChildScope() {
+      this.$$watchers = this.$$nextSibling =
+          this.$$childHead = this.$$childTail = null;
+      this.$$listeners = {};
+      this.$$listenerCount = {};
+      this.$$watchersCount = 0;
+      this.$id = nextUid();
+      this.$$ChildScope = null;
+    }
+    ChildScope.prototype = parent;
+    return ChildScope;
+  }
+
+  this.$get = ['$exceptionHandler', '$parse', '$browser',
+      function($exceptionHandler, $parse, $browser) {
+
+    function destroyChildScope($event) {
+        $event.currentScope.$$destroyed = true;
+    }
+
+    function cleanUpScope($scope) {
+
+      // Support: IE 9 only
+      if (msie === 9) {
+        // There is a memory leak in IE9 if all child scopes are not disconnected
+        // completely when a scope is destroyed. So this code will recurse up through
+        // all this scopes children
+        //
+        // See issue https://github.com/angular/angular.js/issues/10706
+        if ($scope.$$childHead) {
+          cleanUpScope($scope.$$childHead);
+        }
+        if ($scope.$$nextSibling) {
+          cleanUpScope($scope.$$nextSibling);
+        }
+      }
+
+      // The code below works around IE9 and V8's memory leaks
+      //
+      // See:
+      // - https://code.google.com/p/v8/issues/detail?id=2073#c26
+      // - https://github.com/angular/angular.js/issues/6794#issuecomment-38648909
+      // - https://github.com/angular/angular.js/issues/1313#issuecomment-10378451
+
+      $scope.$parent = $scope.$$nextSibling = $scope.$$prevSibling = $scope.$$childHead =
+          $scope.$$childTail = $scope.$root = $scope.$$watchers = null;
+    }
+
+    /**
+     * @ngdoc type
+     * @name $rootScope.Scope
+     *
+     * @description
+     * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the
+     * {@link auto.$injector $injector}. Child scopes are created using the
+     * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when
+     * compiled HTML template is executed.) See also the {@link guide/scope Scopes guide} for
+     * an in-depth introduction and usage examples.
+     *
+     *
+     * # Inheritance
+     * A scope can inherit from a parent scope, as in this example:
+     * ```js
+         var parent = $rootScope;
+         var child = parent.$new();
+
+         parent.salutation = "Hello";
+         expect(child.salutation).toEqual('Hello');
+
+         child.salutation = "Welcome";
+         expect(child.salutation).toEqual('Welcome');
+         expect(parent.salutation).toEqual('Hello');
+     * ```
+     *
+     * When interacting with `Scope` in tests, additional helper methods are available on the
+     * instances of `Scope` type. See {@link ngMock.$rootScope.Scope ngMock Scope} for additional
+     * details.
+     *
+     *
+     * @param {Object.<string, function()>=} providers Map of service factory which need to be
+     *                                       provided for the current scope. Defaults to {@link ng}.
+     * @param {Object.<string, *>=} instanceCache Provides pre-instantiated services which should
+     *                              append/override services provided by `providers`. This is handy
+     *                              when unit-testing and having the need to override a default
+     *                              service.
+     * @returns {Object} Newly created scope.
+     *
+     */
+    function Scope() {
+      this.$id = nextUid();
+      this.$$phase = this.$parent = this.$$watchers =
+                     this.$$nextSibling = this.$$prevSibling =
+                     this.$$childHead = this.$$childTail = null;
+      this.$root = this;
+      this.$$destroyed = false;
+      this.$$listeners = {};
+      this.$$listenerCount = {};
+      this.$$watchersCount = 0;
+      this.$$isolateBindings = null;
+    }
+
+    /**
+     * @ngdoc property
+     * @name $rootScope.Scope#$id
+     *
+     * @description
+     * Unique scope ID (monotonically increasing) useful for debugging.
+     */
+
+     /**
+      * @ngdoc property
+      * @name $rootScope.Scope#$parent
+      *
+      * @description
+      * Reference to the parent scope.
+      */
+
+      /**
+       * @ngdoc property
+       * @name $rootScope.Scope#$root
+       *
+       * @description
+       * Reference to the root scope.
+       */
+
+    Scope.prototype = {
+      constructor: Scope,
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$new
+       * @kind function
+       *
+       * @description
+       * Creates a new child {@link ng.$rootScope.Scope scope}.
+       *
+       * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} event.
+       * The scope can be removed from the scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}.
+       *
+       * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is
+       * desired for the scope and its child scopes to be permanently detached from the parent and
+       * thus stop participating in model change detection and listener notification by invoking.
+       *
+       * @param {boolean} isolate If true, then the scope does not prototypically inherit from the
+       *         parent scope. The scope is isolated, as it can not see parent scope properties.
+       *         When creating widgets, it is useful for the widget to not accidentally read parent
+       *         state.
+       *
+       * @param {Scope} [parent=this] The {@link ng.$rootScope.Scope `Scope`} that will be the `$parent`
+       *                              of the newly created scope. Defaults to `this` scope if not provided.
+       *                              This is used when creating a transclude scope to correctly place it
+       *                              in the scope hierarchy while maintaining the correct prototypical
+       *                              inheritance.
+       *
+       * @returns {Object} The newly created child scope.
+       *
+       */
+      $new: function(isolate, parent) {
+        var child;
+
+        parent = parent || this;
+
+        if (isolate) {
+          child = new Scope();
+          child.$root = this.$root;
+        } else {
+          // Only create a child scope class if somebody asks for one,
+          // but cache it to allow the VM to optimize lookups.
+          if (!this.$$ChildScope) {
+            this.$$ChildScope = createChildScopeClass(this);
+          }
+          child = new this.$$ChildScope();
+        }
+        child.$parent = parent;
+        child.$$prevSibling = parent.$$childTail;
+        if (parent.$$childHead) {
+          parent.$$childTail.$$nextSibling = child;
+          parent.$$childTail = child;
+        } else {
+          parent.$$childHead = parent.$$childTail = child;
+        }
+
+        // When the new scope is not isolated or we inherit from `this`, and
+        // the parent scope is destroyed, the property `$$destroyed` is inherited
+        // prototypically. In all other cases, this property needs to be set
+        // when the parent scope is destroyed.
+        // The listener needs to be added after the parent is set
+        if (isolate || parent !== this) child.$on('$destroy', destroyChildScope);
+
+        return child;
+      },
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$watch
+       * @kind function
+       *
+       * @description
+       * Registers a `listener` callback to be executed whenever the `watchExpression` changes.
+       *
+       * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest
+       *   $digest()} and should return the value that will be watched. (`watchExpression` should not change
+       *   its value when executed multiple times with the same input because it may be executed multiple
+       *   times by {@link ng.$rootScope.Scope#$digest $digest()}. That is, `watchExpression` should be
+       *   [idempotent](http://en.wikipedia.org/wiki/Idempotence).)
+       * - The `listener` is called only when the value from the current `watchExpression` and the
+       *   previous call to `watchExpression` are not equal (with the exception of the initial run,
+       *   see below). Inequality is determined according to reference inequality,
+       *   [strict comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)
+       *    via the `!==` Javascript operator, unless `objectEquality == true`
+       *   (see next point)
+       * - When `objectEquality == true`, inequality of the `watchExpression` is determined
+       *   according to the {@link angular.equals} function. To save the value of the object for
+       *   later comparison, the {@link angular.copy} function is used. This therefore means that
+       *   watching complex objects will have adverse memory and performance implications.
+       * - This should not be used to watch for changes in objects that are
+       *   or contain [File](https://developer.mozilla.org/docs/Web/API/File) objects due to limitations with {@link angular.copy `angular.copy`}.
+       * - The watch `listener` may change the model, which may trigger other `listener`s to fire.
+       *   This is achieved by rerunning the watchers until no changes are detected. The rerun
+       *   iteration limit is 10 to prevent an infinite loop deadlock.
+       *
+       *
+       * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called,
+       * you can register a `watchExpression` function with no `listener`. (Be prepared for
+       * multiple calls to your `watchExpression` because it will execute multiple times in a
+       * single {@link ng.$rootScope.Scope#$digest $digest} cycle if a change is detected.)
+       *
+       * After a watcher is registered with the scope, the `listener` fn is called asynchronously
+       * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the
+       * watcher. In rare cases, this is undesirable because the listener is called when the result
+       * of `watchExpression` didn't change. To detect this scenario within the `listener` fn, you
+       * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the
+       * listener was called due to initialization.
+       *
+       *
+       *
+       * # Example
+       * ```js
+           // let's assume that scope was dependency injected as the $rootScope
+           var scope = $rootScope;
+           scope.name = 'misko';
+           scope.counter = 0;
+
+           expect(scope.counter).toEqual(0);
+           scope.$watch('name', function(newValue, oldValue) {
+             scope.counter = scope.counter + 1;
+           });
+           expect(scope.counter).toEqual(0);
+
+           scope.$digest();
+           // the listener is always called during the first $digest loop after it was registered
+           expect(scope.counter).toEqual(1);
+
+           scope.$digest();
+           // but now it will not be called unless the value changes
+           expect(scope.counter).toEqual(1);
+
+           scope.name = 'adam';
+           scope.$digest();
+           expect(scope.counter).toEqual(2);
+
+
+
+           // Using a function as a watchExpression
+           var food;
+           scope.foodCounter = 0;
+           expect(scope.foodCounter).toEqual(0);
+           scope.$watch(
+             // This function returns the value being watched. It is called for each turn of the $digest loop
+             function() { return food; },
+             // This is the change listener, called when the value returned from the above function changes
+             function(newValue, oldValue) {
+               if ( newValue !== oldValue ) {
+                 // Only increment the counter if the value changed
+                 scope.foodCounter = scope.foodCounter + 1;
+               }
+             }
+           );
+           // No digest has been run so the counter will be zero
+           expect(scope.foodCounter).toEqual(0);
+
+           // Run the digest but since food has not changed count will still be zero
+           scope.$digest();
+           expect(scope.foodCounter).toEqual(0);
+
+           // Update food and run digest.  Now the counter will increment
+           food = 'cheeseburger';
+           scope.$digest();
+           expect(scope.foodCounter).toEqual(1);
+
+       * ```
+       *
+       *
+       *
+       * @param {(function()|string)} watchExpression Expression that is evaluated on each
+       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers
+       *    a call to the `listener`.
+       *
+       *    - `string`: Evaluated as {@link guide/expression expression}
+       *    - `function(scope)`: called with current `scope` as a parameter.
+       * @param {function(newVal, oldVal, scope)} listener Callback called whenever the value
+       *    of `watchExpression` changes.
+       *
+       *    - `newVal` contains the current value of the `watchExpression`
+       *    - `oldVal` contains the previous value of the `watchExpression`
+       *    - `scope` refers to the current scope
+       * @param {boolean=} [objectEquality=false] Compare for object equality using {@link angular.equals} instead of
+       *     comparing for reference equality.
+       * @returns {function()} Returns a deregistration function for this listener.
+       */
+      $watch: function(watchExp, listener, objectEquality, prettyPrintExpression) {
+        var get = $parse(watchExp);
+
+        if (get.$$watchDelegate) {
+          return get.$$watchDelegate(this, listener, objectEquality, get, watchExp);
+        }
+        var scope = this,
+            array = scope.$$watchers,
+            watcher = {
+              fn: listener,
+              last: initWatchVal,
+              get: get,
+              exp: prettyPrintExpression || watchExp,
+              eq: !!objectEquality
+            };
+
+        lastDirtyWatch = null;
+
+        if (!isFunction(listener)) {
+          watcher.fn = noop;
+        }
+
+        if (!array) {
+          array = scope.$$watchers = [];
+          array.$$digestWatchIndex = -1;
+        }
+        // we use unshift since we use a while loop in $digest for speed.
+        // the while loop reads in reverse order.
+        array.unshift(watcher);
+        array.$$digestWatchIndex++;
+        incrementWatchersCount(this, 1);
+
+        return function deregisterWatch() {
+          var index = arrayRemove(array, watcher);
+          if (index >= 0) {
+            incrementWatchersCount(scope, -1);
+            if (index < array.$$digestWatchIndex) {
+              array.$$digestWatchIndex--;
+            }
+          }
+          lastDirtyWatch = null;
+        };
+      },
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$watchGroup
+       * @kind function
+       *
+       * @description
+       * A variant of {@link ng.$rootScope.Scope#$watch $watch()} where it watches an array of `watchExpressions`.
+       * If any one expression in the collection changes the `listener` is executed.
+       *
+       * - The items in the `watchExpressions` array are observed via the standard `$watch` operation. Their return
+       *   values are examined for changes on every call to `$digest`.
+       * - The `listener` is called whenever any expression in the `watchExpressions` array changes.
+       *
+       * @param {Array.<string|Function(scope)>} watchExpressions Array of expressions that will be individually
+       * watched using {@link ng.$rootScope.Scope#$watch $watch()}
+       *
+       * @param {function(newValues, oldValues, scope)} listener Callback called whenever the return value of any
+       *    expression in `watchExpressions` changes
+       *    The `newValues` array contains the current values of the `watchExpressions`, with the indexes matching
+       *    those of `watchExpression`
+       *    and the `oldValues` array contains the previous values of the `watchExpressions`, with the indexes matching
+       *    those of `watchExpression`
+       *    The `scope` refers to the current scope.
+       * @returns {function()} Returns a de-registration function for all listeners.
+       */
+      $watchGroup: function(watchExpressions, listener) {
+        var oldValues = new Array(watchExpressions.length);
+        var newValues = new Array(watchExpressions.length);
+        var deregisterFns = [];
+        var self = this;
+        var changeReactionScheduled = false;
+        var firstRun = true;
+
+        if (!watchExpressions.length) {
+          // No expressions means we call the listener ASAP
+          var shouldCall = true;
+          self.$evalAsync(function() {
+            if (shouldCall) listener(newValues, newValues, self);
+          });
+          return function deregisterWatchGroup() {
+            shouldCall = false;
+          };
+        }
+
+        if (watchExpressions.length === 1) {
+          // Special case size of one
+          return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) {
+            newValues[0] = value;
+            oldValues[0] = oldValue;
+            listener(newValues, (value === oldValue) ? newValues : oldValues, scope);
+          });
+        }
+
+        forEach(watchExpressions, function(expr, i) {
+          var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) {
+            newValues[i] = value;
+            oldValues[i] = oldValue;
+            if (!changeReactionScheduled) {
+              changeReactionScheduled = true;
+              self.$evalAsync(watchGroupAction);
+            }
+          });
+          deregisterFns.push(unwatchFn);
+        });
+
+        function watchGroupAction() {
+          changeReactionScheduled = false;
+
+          if (firstRun) {
+            firstRun = false;
+            listener(newValues, newValues, self);
+          } else {
+            listener(newValues, oldValues, self);
+          }
+        }
+
+        return function deregisterWatchGroup() {
+          while (deregisterFns.length) {
+            deregisterFns.shift()();
+          }
+        };
+      },
+
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$watchCollection
+       * @kind function
+       *
+       * @description
+       * Shallow watches the properties of an object and fires whenever any of the properties change
+       * (for arrays, this implies watching the array items; for object maps, this implies watching
+       * the properties). If a change is detected, the `listener` callback is fired.
+       *
+       * - The `obj` collection is observed via standard $watch operation and is examined on every
+       *   call to $digest() to see if any items have been added, removed, or moved.
+       * - The `listener` is called whenever anything within the `obj` has changed. Examples include
+       *   adding, removing, and moving items belonging to an object or array.
+       *
+       *
+       * # Example
+       * ```js
+          $scope.names = ['igor', 'matias', 'misko', 'james'];
+          $scope.dataCount = 4;
+
+          $scope.$watchCollection('names', function(newNames, oldNames) {
+            $scope.dataCount = newNames.length;
+          });
+
+          expect($scope.dataCount).toEqual(4);
+          $scope.$digest();
+
+          //still at 4 ... no changes
+          expect($scope.dataCount).toEqual(4);
+
+          $scope.names.pop();
+          $scope.$digest();
+
+          //now there's been a change
+          expect($scope.dataCount).toEqual(3);
+       * ```
+       *
+       *
+       * @param {string|function(scope)} obj Evaluated as {@link guide/expression expression}. The
+       *    expression value should evaluate to an object or an array which is observed on each
+       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the
+       *    collection will trigger a call to the `listener`.
+       *
+       * @param {function(newCollection, oldCollection, scope)} listener a callback function called
+       *    when a change is detected.
+       *    - The `newCollection` object is the newly modified data obtained from the `obj` expression
+       *    - The `oldCollection` object is a copy of the former collection data.
+       *      Due to performance considerations, the`oldCollection` value is computed only if the
+       *      `listener` function declares two or more arguments.
+       *    - The `scope` argument refers to the current scope.
+       *
+       * @returns {function()} Returns a de-registration function for this listener. When the
+       *    de-registration function is executed, the internal watch operation is terminated.
+       */
+      $watchCollection: function(obj, listener) {
+        $watchCollectionInterceptor.$stateful = true;
+
+        var self = this;
+        // the current value, updated on each dirty-check run
+        var newValue;
+        // a shallow copy of the newValue from the last dirty-check run,
+        // updated to match newValue during dirty-check run
+        var oldValue;
+        // a shallow copy of the newValue from when the last change happened
+        var veryOldValue;
+        // only track veryOldValue if the listener is asking for it
+        var trackVeryOldValue = (listener.length > 1);
+        var changeDetected = 0;
+        var changeDetector = $parse(obj, $watchCollectionInterceptor);
+        var internalArray = [];
+        var internalObject = {};
+        var initRun = true;
+        var oldLength = 0;
+
+        function $watchCollectionInterceptor(_value) {
+          newValue = _value;
+          var newLength, key, bothNaN, newItem, oldItem;
+
+          // If the new value is undefined, then return undefined as the watch may be a one-time watch
+          if (isUndefined(newValue)) return;
+
+          if (!isObject(newValue)) { // if primitive
+            if (oldValue !== newValue) {
+              oldValue = newValue;
+              changeDetected++;
+            }
+          } else if (isArrayLike(newValue)) {
+            if (oldValue !== internalArray) {
+              // we are transitioning from something which was not an array into array.
+              oldValue = internalArray;
+              oldLength = oldValue.length = 0;
+              changeDetected++;
+            }
+
+            newLength = newValue.length;
+
+            if (oldLength !== newLength) {
+              // if lengths do not match we need to trigger change notification
+              changeDetected++;
+              oldValue.length = oldLength = newLength;
+            }
+            // copy the items to oldValue and look for changes.
+            for (var i = 0; i < newLength; i++) {
+              oldItem = oldValue[i];
+              newItem = newValue[i];
+
+              // eslint-disable-next-line no-self-compare
+              bothNaN = (oldItem !== oldItem) && (newItem !== newItem);
+              if (!bothNaN && (oldItem !== newItem)) {
+                changeDetected++;
+                oldValue[i] = newItem;
+              }
+            }
+          } else {
+            if (oldValue !== internalObject) {
+              // we are transitioning from something which was not an object into object.
+              oldValue = internalObject = {};
+              oldLength = 0;
+              changeDetected++;
+            }
+            // copy the items to oldValue and look for changes.
+            newLength = 0;
+            for (key in newValue) {
+              if (hasOwnProperty.call(newValue, key)) {
+                newLength++;
+                newItem = newValue[key];
+                oldItem = oldValue[key];
+
+                if (key in oldValue) {
+                  // eslint-disable-next-line no-self-compare
+                  bothNaN = (oldItem !== oldItem) && (newItem !== newItem);
+                  if (!bothNaN && (oldItem !== newItem)) {
+                    changeDetected++;
+                    oldValue[key] = newItem;
+                  }
+                } else {
+                  oldLength++;
+                  oldValue[key] = newItem;
+                  changeDetected++;
+                }
+              }
+            }
+            if (oldLength > newLength) {
+              // we used to have more keys, need to find them and destroy them.
+              changeDetected++;
+              for (key in oldValue) {
+                if (!hasOwnProperty.call(newValue, key)) {
+                  oldLength--;
+                  delete oldValue[key];
+                }
+              }
+            }
+          }
+          return changeDetected;
+        }
+
+        function $watchCollectionAction() {
+          if (initRun) {
+            initRun = false;
+            listener(newValue, newValue, self);
+          } else {
+            listener(newValue, veryOldValue, self);
+          }
+
+          // make a copy for the next time a collection is changed
+          if (trackVeryOldValue) {
+            if (!isObject(newValue)) {
+              //primitive
+              veryOldValue = newValue;
+            } else if (isArrayLike(newValue)) {
+              veryOldValue = new Array(newValue.length);
+              for (var i = 0; i < newValue.length; i++) {
+                veryOldValue[i] = newValue[i];
+              }
+            } else { // if object
+              veryOldValue = {};
+              for (var key in newValue) {
+                if (hasOwnProperty.call(newValue, key)) {
+                  veryOldValue[key] = newValue[key];
+                }
+              }
+            }
+          }
+        }
+
+        return this.$watch(changeDetector, $watchCollectionAction);
+      },
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$digest
+       * @kind function
+       *
+       * @description
+       * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and
+       * its children. Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change
+       * the model, the `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers}
+       * until no more listeners are firing. This means that it is possible to get into an infinite
+       * loop. This function will throw `'Maximum iteration limit exceeded.'` if the number of
+       * iterations exceeds 10.
+       *
+       * Usually, you don't call `$digest()` directly in
+       * {@link ng.directive:ngController controllers} or in
+       * {@link ng.$compileProvider#directive directives}.
+       * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within
+       * a {@link ng.$compileProvider#directive directive}), which will force a `$digest()`.
+       *
+       * If you want to be notified whenever `$digest()` is called,
+       * you can register a `watchExpression` function with
+       * {@link ng.$rootScope.Scope#$watch $watch()} with no `listener`.
+       *
+       * In unit tests, you may need to call `$digest()` to simulate the scope life cycle.
+       *
+       * # Example
+       * ```js
+           var scope = ...;
+           scope.name = 'misko';
+           scope.counter = 0;
+
+           expect(scope.counter).toEqual(0);
+           scope.$watch('name', function(newValue, oldValue) {
+             scope.counter = scope.counter + 1;
+           });
+           expect(scope.counter).toEqual(0);
+
+           scope.$digest();
+           // the listener is always called during the first $digest loop after it was registered
+           expect(scope.counter).toEqual(1);
+
+           scope.$digest();
+           // but now it will not be called unless the value changes
+           expect(scope.counter).toEqual(1);
+
+           scope.name = 'adam';
+           scope.$digest();
+           expect(scope.counter).toEqual(2);
+       * ```
+       *
+       */
+      $digest: function() {
+        var watch, value, last, fn, get,
+            watchers,
+            dirty, ttl = TTL,
+            next, current, target = this,
+            watchLog = [],
+            logIdx, asyncTask;
+
+        beginPhase('$digest');
+        // Check for changes to browser url that happened in sync before the call to $digest
+        $browser.$$checkUrlChange();
+
+        if (this === $rootScope && applyAsyncId !== null) {
+          // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then
+          // cancel the scheduled $apply and flush the queue of expressions to be evaluated.
+          $browser.defer.cancel(applyAsyncId);
+          flushApplyAsync();
+        }
+
+        lastDirtyWatch = null;
+
+        do { // "while dirty" loop
+          dirty = false;
+          current = target;
+
+          // It's safe for asyncQueuePosition to be a local variable here because this loop can't
+          // be reentered recursively. Calling $digest from a function passed to $evalAsync would
+          // lead to a '$digest already in progress' error.
+          for (var asyncQueuePosition = 0; asyncQueuePosition < asyncQueue.length; asyncQueuePosition++) {
+            try {
+              asyncTask = asyncQueue[asyncQueuePosition];
+              fn = asyncTask.fn;
+              fn(asyncTask.scope, asyncTask.locals);
+            } catch (e) {
+              $exceptionHandler(e);
+            }
+            lastDirtyWatch = null;
+          }
+          asyncQueue.length = 0;
+
+          traverseScopesLoop:
+          do { // "traverse the scopes" loop
+            if ((watchers = current.$$watchers)) {
+              // process our watches
+              watchers.$$digestWatchIndex = watchers.length;
+              while (watchers.$$digestWatchIndex--) {
+                try {
+                  watch = watchers[watchers.$$digestWatchIndex];
+                  // Most common watches are on primitives, in which case we can short
+                  // circuit it with === operator, only when === fails do we use .equals
+                  if (watch) {
+                    get = watch.get;
+                    if ((value = get(current)) !== (last = watch.last) &&
+                        !(watch.eq
+                            ? equals(value, last)
+                            : (isNumberNaN(value) && isNumberNaN(last)))) {
+                      dirty = true;
+                      lastDirtyWatch = watch;
+                      watch.last = watch.eq ? copy(value, null) : value;
+                      fn = watch.fn;
+                      fn(value, ((last === initWatchVal) ? value : last), current);
+                      if (ttl < 5) {
+                        logIdx = 4 - ttl;
+                        if (!watchLog[logIdx]) watchLog[logIdx] = [];
+                        watchLog[logIdx].push({
+                          msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp,
+                          newVal: value,
+                          oldVal: last
+                        });
+                      }
+                    } else if (watch === lastDirtyWatch) {
+                      // If the most recently dirty watcher is now clean, short circuit since the remaining watchers
+                      // have already been tested.
+                      dirty = false;
+                      break traverseScopesLoop;
+                    }
+                  }
+                } catch (e) {
+                  $exceptionHandler(e);
+                }
+              }
+            }
+
+            // Insanity Warning: scope depth-first traversal
+            // yes, this code is a bit crazy, but it works and we have tests to prove it!
+            // this piece should be kept in sync with the traversal in $broadcast
+            if (!(next = ((current.$$watchersCount && current.$$childHead) ||
+                (current !== target && current.$$nextSibling)))) {
+              while (current !== target && !(next = current.$$nextSibling)) {
+                current = current.$parent;
+              }
+            }
+          } while ((current = next));
+
+          // `break traverseScopesLoop;` takes us to here
+
+          if ((dirty || asyncQueue.length) && !(ttl--)) {
+            clearPhase();
+            throw $rootScopeMinErr('infdig',
+                '{0} $digest() iterations reached. Aborting!\n' +
+                'Watchers fired in the last 5 iterations: {1}',
+                TTL, watchLog);
+          }
+
+        } while (dirty || asyncQueue.length);
+
+        clearPhase();
+
+        // postDigestQueuePosition isn't local here because this loop can be reentered recursively.
+        while (postDigestQueuePosition < postDigestQueue.length) {
+          try {
+            postDigestQueue[postDigestQueuePosition++]();
+          } catch (e) {
+            $exceptionHandler(e);
+          }
+        }
+        postDigestQueue.length = postDigestQueuePosition = 0;
+
+        // Check for changes to browser url that happened during the $digest
+        // (for which no event is fired; e.g. via `history.pushState()`)
+        $browser.$$checkUrlChange();
+      },
+
+
+      /**
+       * @ngdoc event
+       * @name $rootScope.Scope#$destroy
+       * @eventType broadcast on scope being destroyed
+       *
+       * @description
+       * Broadcasted when a scope and its children are being destroyed.
+       *
+       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
+       * clean up DOM bindings before an element is removed from the DOM.
+       */
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$destroy
+       * @kind function
+       *
+       * @description
+       * Removes the current scope (and all of its children) from the parent scope. Removal implies
+       * that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer
+       * propagate to the current scope and its children. Removal also implies that the current
+       * scope is eligible for garbage collection.
+       *
+       * The `$destroy()` is usually used by directives such as
+       * {@link ng.directive:ngRepeat ngRepeat} for managing the
+       * unrolling of the loop.
+       *
+       * Just before a scope is destroyed, a `$destroy` event is broadcasted on this scope.
+       * Application code can register a `$destroy` event handler that will give it a chance to
+       * perform any necessary cleanup.
+       *
+       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
+       * clean up DOM bindings before an element is removed from the DOM.
+       */
+      $destroy: function() {
+        // We can't destroy a scope that has been already destroyed.
+        if (this.$$destroyed) return;
+        var parent = this.$parent;
+
+        this.$broadcast('$destroy');
+        this.$$destroyed = true;
+
+        if (this === $rootScope) {
+          //Remove handlers attached to window when $rootScope is removed
+          $browser.$$applicationDestroyed();
+        }
+
+        incrementWatchersCount(this, -this.$$watchersCount);
+        for (var eventName in this.$$listenerCount) {
+          decrementListenerCount(this, this.$$listenerCount[eventName], eventName);
+        }
+
+        // sever all the references to parent scopes (after this cleanup, the current scope should
+        // not be retained by any of our references and should be eligible for garbage collection)
+        if (parent && parent.$$childHead === this) parent.$$childHead = this.$$nextSibling;
+        if (parent && parent.$$childTail === this) parent.$$childTail = this.$$prevSibling;
+        if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
+        if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;
+
+        // Disable listeners, watchers and apply/digest methods
+        this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop;
+        this.$on = this.$watch = this.$watchGroup = function() { return noop; };
+        this.$$listeners = {};
+
+        // Disconnect the next sibling to prevent `cleanUpScope` destroying those too
+        this.$$nextSibling = null;
+        cleanUpScope(this);
+      },
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$eval
+       * @kind function
+       *
+       * @description
+       * Executes the `expression` on the current scope and returns the result. Any exceptions in
+       * the expression are propagated (uncaught). This is useful when evaluating Angular
+       * expressions.
+       *
+       * # Example
+       * ```js
+           var scope = ng.$rootScope.Scope();
+           scope.a = 1;
+           scope.b = 2;
+
+           expect(scope.$eval('a+b')).toEqual(3);
+           expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3);
+       * ```
+       *
+       * @param {(string|function())=} expression An angular expression to be executed.
+       *
+       *    - `string`: execute using the rules as defined in  {@link guide/expression expression}.
+       *    - `function(scope)`: execute the function with the current `scope` parameter.
+       *
+       * @param {(object)=} locals Local variables object, useful for overriding values in scope.
+       * @returns {*} The result of evaluating the expression.
+       */
+      $eval: function(expr, locals) {
+        return $parse(expr)(this, locals);
+      },
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$evalAsync
+       * @kind function
+       *
+       * @description
+       * Executes the expression on the current scope at a later point in time.
+       *
+       * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only
+       * that:
+       *
+       *   - it will execute after the function that scheduled the evaluation (preferably before DOM
+       *     rendering).
+       *   - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after
+       *     `expression` execution.
+       *
+       * Any exceptions from the execution of the expression are forwarded to the
+       * {@link ng.$exceptionHandler $exceptionHandler} service.
+       *
+       * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle
+       * will be scheduled. However, it is encouraged to always call code that changes the model
+       * from within an `$apply` call. That includes code evaluated via `$evalAsync`.
+       *
+       * @param {(string|function())=} expression An angular expression to be executed.
+       *
+       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.
+       *    - `function(scope)`: execute the function with the current `scope` parameter.
+       *
+       * @param {(object)=} locals Local variables object, useful for overriding values in scope.
+       */
+      $evalAsync: function(expr, locals) {
+        // if we are outside of an $digest loop and this is the first time we are scheduling async
+        // task also schedule async auto-flush
+        if (!$rootScope.$$phase && !asyncQueue.length) {
+          $browser.defer(function() {
+            if (asyncQueue.length) {
+              $rootScope.$digest();
+            }
+          });
+        }
+
+        asyncQueue.push({scope: this, fn: $parse(expr), locals: locals});
+      },
+
+      $$postDigest: function(fn) {
+        postDigestQueue.push(fn);
+      },
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$apply
+       * @kind function
+       *
+       * @description
+       * `$apply()` is used to execute an expression in angular from outside of the angular
+       * framework. (For example from browser DOM events, setTimeout, XHR or third party libraries).
+       * Because we are calling into the angular framework we need to perform proper scope life
+       * cycle of {@link ng.$exceptionHandler exception handling},
+       * {@link ng.$rootScope.Scope#$digest executing watches}.
+       *
+       * ## Life cycle
+       *
+       * # Pseudo-Code of `$apply()`
+       * ```js
+           function $apply(expr) {
+             try {
+               return $eval(expr);
+             } catch (e) {
+               $exceptionHandler(e);
+             } finally {
+               $root.$digest();
+             }
+           }
+       * ```
+       *
+       *
+       * Scope's `$apply()` method transitions through the following stages:
+       *
+       * 1. The {@link guide/expression expression} is executed using the
+       *    {@link ng.$rootScope.Scope#$eval $eval()} method.
+       * 2. Any exceptions from the execution of the expression are forwarded to the
+       *    {@link ng.$exceptionHandler $exceptionHandler} service.
+       * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the
+       *    expression was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method.
+       *
+       *
+       * @param {(string|function())=} exp An angular expression to be executed.
+       *
+       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.
+       *    - `function(scope)`: execute the function with current `scope` parameter.
+       *
+       * @returns {*} The result of evaluating the expression.
+       */
+      $apply: function(expr) {
+        try {
+          beginPhase('$apply');
+          try {
+            return this.$eval(expr);
+          } finally {
+            clearPhase();
+          }
+        } catch (e) {
+          $exceptionHandler(e);
+        } finally {
+          try {
+            $rootScope.$digest();
+          } catch (e) {
+            $exceptionHandler(e);
+            // eslint-disable-next-line no-unsafe-finally
+            throw e;
+          }
+        }
+      },
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$applyAsync
+       * @kind function
+       *
+       * @description
+       * Schedule the invocation of $apply to occur at a later time. The actual time difference
+       * varies across browsers, but is typically around ~10 milliseconds.
+       *
+       * This can be used to queue up multiple expressions which need to be evaluated in the same
+       * digest.
+       *
+       * @param {(string|function())=} exp An angular expression to be executed.
+       *
+       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.
+       *    - `function(scope)`: execute the function with current `scope` parameter.
+       */
+      $applyAsync: function(expr) {
+        var scope = this;
+        if (expr) {
+          applyAsyncQueue.push($applyAsyncExpression);
+        }
+        expr = $parse(expr);
+        scheduleApplyAsync();
+
+        function $applyAsyncExpression() {
+          scope.$eval(expr);
+        }
+      },
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$on
+       * @kind function
+       *
+       * @description
+       * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for
+       * discussion of event life cycle.
+       *
+       * The event listener function format is: `function(event, args...)`. The `event` object
+       * passed into the listener has the following attributes:
+       *
+       *   - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or
+       *     `$broadcast`-ed.
+       *   - `currentScope` - `{Scope}`: the scope that is currently handling the event. Once the
+       *     event propagates through the scope hierarchy, this property is set to null.
+       *   - `name` - `{string}`: name of the event.
+       *   - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel
+       *     further event propagation (available only for events that were `$emit`-ed).
+       *   - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag
+       *     to true.
+       *   - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.
+       *
+       * @param {string} name Event name to listen on.
+       * @param {function(event, ...args)} listener Function to call when the event is emitted.
+       * @returns {function()} Returns a deregistration function for this listener.
+       */
+      $on: function(name, listener) {
+        var namedListeners = this.$$listeners[name];
+        if (!namedListeners) {
+          this.$$listeners[name] = namedListeners = [];
+        }
+        namedListeners.push(listener);
+
+        var current = this;
+        do {
+          if (!current.$$listenerCount[name]) {
+            current.$$listenerCount[name] = 0;
+          }
+          current.$$listenerCount[name]++;
+        } while ((current = current.$parent));
+
+        var self = this;
+        return function() {
+          var indexOfListener = namedListeners.indexOf(listener);
+          if (indexOfListener !== -1) {
+            namedListeners[indexOfListener] = null;
+            decrementListenerCount(self, 1, name);
+          }
+        };
+      },
+
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$emit
+       * @kind function
+       *
+       * @description
+       * Dispatches an event `name` upwards through the scope hierarchy notifying the
+       * registered {@link ng.$rootScope.Scope#$on} listeners.
+       *
+       * The event life cycle starts at the scope on which `$emit` was called. All
+       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get
+       * notified. Afterwards, the event traverses upwards toward the root scope and calls all
+       * registered listeners along the way. The event will stop propagating if one of the listeners
+       * cancels it.
+       *
+       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
+       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
+       *
+       * @param {string} name Event name to emit.
+       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
+       * @return {Object} Event object (see {@link ng.$rootScope.Scope#$on}).
+       */
+      $emit: function(name, args) {
+        var empty = [],
+            namedListeners,
+            scope = this,
+            stopPropagation = false,
+            event = {
+              name: name,
+              targetScope: scope,
+              stopPropagation: function() {stopPropagation = true;},
+              preventDefault: function() {
+                event.defaultPrevented = true;
+              },
+              defaultPrevented: false
+            },
+            listenerArgs = concat([event], arguments, 1),
+            i, length;
+
+        do {
+          namedListeners = scope.$$listeners[name] || empty;
+          event.currentScope = scope;
+          for (i = 0, length = namedListeners.length; i < length; i++) {
+
+            // if listeners were deregistered, defragment the array
+            if (!namedListeners[i]) {
+              namedListeners.splice(i, 1);
+              i--;
+              length--;
+              continue;
+            }
+            try {
+              //allow all listeners attached to the current scope to run
+              namedListeners[i].apply(null, listenerArgs);
+            } catch (e) {
+              $exceptionHandler(e);
+            }
+          }
+          //if any listener on the current scope stops propagation, prevent bubbling
+          if (stopPropagation) {
+            event.currentScope = null;
+            return event;
+          }
+          //traverse upwards
+          scope = scope.$parent;
+        } while (scope);
+
+        event.currentScope = null;
+
+        return event;
+      },
+
+
+      /**
+       * @ngdoc method
+       * @name $rootScope.Scope#$broadcast
+       * @kind function
+       *
+       * @description
+       * Dispatches an event `name` downwards to all child scopes (and their children) notifying the
+       * registered {@link ng.$rootScope.Scope#$on} listeners.
+       *
+       * The event life cycle starts at the scope on which `$broadcast` was called. All
+       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get
+       * notified. Afterwards, the event propagates to all direct and indirect scopes of the current
+       * scope and calls all registered listeners along the way. The event cannot be canceled.
+       *
+       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
+       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
+       *
+       * @param {string} name Event name to broadcast.
+       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
+       * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}
+       */
+      $broadcast: function(name, args) {
+        var target = this,
+            current = target,
+            next = target,
+            event = {
+              name: name,
+              targetScope: target,
+              preventDefault: function() {
+                event.defaultPrevented = true;
+              },
+              defaultPrevented: false
+            };
+
+        if (!target.$$listenerCount[name]) return event;
+
+        var listenerArgs = concat([event], arguments, 1),
+            listeners, i, length;
+
+        //down while you can, then up and next sibling or up and next sibling until back at root
+        while ((current = next)) {
+          event.currentScope = current;
+          listeners = current.$$listeners[name] || [];
+          for (i = 0, length = listeners.length; i < length; i++) {
+            // if listeners were deregistered, defragment the array
+            if (!listeners[i]) {
+              listeners.splice(i, 1);
+              i--;
+              length--;
+              continue;
+            }
+
+            try {
+              listeners[i].apply(null, listenerArgs);
+            } catch (e) {
+              $exceptionHandler(e);
+            }
+          }
+
+          // Insanity Warning: scope depth-first traversal
+          // yes, this code is a bit crazy, but it works and we have tests to prove it!
+          // this piece should be kept in sync with the traversal in $digest
+          // (though it differs due to having the extra check for $$listenerCount)
+          if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
+              (current !== target && current.$$nextSibling)))) {
+            while (current !== target && !(next = current.$$nextSibling)) {
+              current = current.$parent;
+            }
+          }
+        }
+
+        event.currentScope = null;
+        return event;
+      }
+    };
+
+    var $rootScope = new Scope();
+
+    //The internal queues. Expose them on the $rootScope for debugging/testing purposes.
+    var asyncQueue = $rootScope.$$asyncQueue = [];
+    var postDigestQueue = $rootScope.$$postDigestQueue = [];
+    var applyAsyncQueue = $rootScope.$$applyAsyncQueue = [];
+
+    var postDigestQueuePosition = 0;
+
+    return $rootScope;
+
+
+    function beginPhase(phase) {
+      if ($rootScope.$$phase) {
+        throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase);
+      }
+
+      $rootScope.$$phase = phase;
+    }
+
+    function clearPhase() {
+      $rootScope.$$phase = null;
+    }
+
+    function incrementWatchersCount(current, count) {
+      do {
+        current.$$watchersCount += count;
+      } while ((current = current.$parent));
+    }
+
+    function decrementListenerCount(current, count, name) {
+      do {
+        current.$$listenerCount[name] -= count;
+
+        if (current.$$listenerCount[name] === 0) {
+          delete current.$$listenerCount[name];
+        }
+      } while ((current = current.$parent));
+    }
+
+    /**
+     * function used as an initial value for watchers.
+     * because it's unique we can easily tell it apart from other values
+     */
+    function initWatchVal() {}
+
+    function flushApplyAsync() {
+      while (applyAsyncQueue.length) {
+        try {
+          applyAsyncQueue.shift()();
+        } catch (e) {
+          $exceptionHandler(e);
+        }
+      }
+      applyAsyncId = null;
+    }
+
+    function scheduleApplyAsync() {
+      if (applyAsyncId === null) {
+        applyAsyncId = $browser.defer(function() {
+          $rootScope.$apply(flushApplyAsync);
+        });
+      }
+    }
+  }];
+}
+
+/**
+ * @ngdoc service
+ * @name $rootElement
+ *
+ * @description
+ * The root element of Angular application. This is either the element where {@link
+ * ng.directive:ngApp ngApp} was declared or the element passed into
+ * {@link angular.bootstrap}. The element represents the root element of application. It is also the
+ * location where the application's {@link auto.$injector $injector} service gets
+ * published, and can be retrieved using `$rootElement.injector()`.
+ */
+
+
+// the implementation is in angular.bootstrap
+
+/**
+ * @this
+ * @description
+ * Private service to sanitize uris for links and images. Used by $compile and $sanitize.
+ */
+function $$SanitizeUriProvider() {
+  var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
+    imgSrcSanitizationWhitelist = /^\s*((https?|ftp|file|blob):|data:image\/)/;
+
+  /**
+   * @description
+   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
+   * urls during a[href] sanitization.
+   *
+   * The sanitization is a security measure aimed at prevent XSS attacks via html links.
+   *
+   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
+   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
+   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
+   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
+   *
+   * @param {RegExp=} regexp New regexp to whitelist urls with.
+   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
+   *    chaining otherwise.
+   */
+  this.aHrefSanitizationWhitelist = function(regexp) {
+    if (isDefined(regexp)) {
+      aHrefSanitizationWhitelist = regexp;
+      return this;
+    }
+    return aHrefSanitizationWhitelist;
+  };
+
+
+  /**
+   * @description
+   * Retrieves or overrides the default regular expression that is used for whitelisting of safe
+   * urls during img[src] sanitization.
+   *
+   * The sanitization is a security measure aimed at prevent XSS attacks via html links.
+   *
+   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into
+   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
+   * regular expression. If a match is found, the original url is written into the dom. Otherwise,
+   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
+   *
+   * @param {RegExp=} regexp New regexp to whitelist urls with.
+   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
+   *    chaining otherwise.
+   */
+  this.imgSrcSanitizationWhitelist = function(regexp) {
+    if (isDefined(regexp)) {
+      imgSrcSanitizationWhitelist = regexp;
+      return this;
+    }
+    return imgSrcSanitizationWhitelist;
+  };
+
+  this.$get = function() {
+    return function sanitizeUri(uri, isImage) {
+      var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
+      var normalizedVal;
+      normalizedVal = urlResolve(uri).href;
+      if (normalizedVal !== '' && !normalizedVal.match(regex)) {
+        return 'unsafe:' + normalizedVal;
+      }
+      return uri;
+    };
+  };
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *     Any commits to this file should be reviewed with security in mind.  *
+ *   Changes to this file can potentially create security vulnerabilities. *
+ *          An approval from 2 Core members with history of modifying      *
+ *                         this file is required.                          *
+ *                                                                         *
+ *  Does the change somehow allow for arbitrary javascript to be executed? *
+ *    Or allows for someone to change the prototype of built-in objects?   *
+ *     Or gives undesired access to variables likes document or window?    *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* exported $SceProvider, $SceDelegateProvider */
+
+var $sceMinErr = minErr('$sce');
+
+var SCE_CONTEXTS = {
+  HTML: 'html',
+  CSS: 'css',
+  URL: 'url',
+  // RESOURCE_URL is a subtype of URL used in contexts where a privileged resource is sourced from a
+  // url.  (e.g. ng-include, script src, templateUrl)
+  RESOURCE_URL: 'resourceUrl',
+  JS: 'js'
+};
+
+// Helper functions follow.
+
+var UNDERSCORE_LOWERCASE_REGEXP = /_([a-z])/g;
+
+function snakeToCamel(name) {
+  return name
+    .replace(UNDERSCORE_LOWERCASE_REGEXP, fnCamelCaseReplace);
+}
+
+function adjustMatcher(matcher) {
+  if (matcher === 'self') {
+    return matcher;
+  } else if (isString(matcher)) {
+    // Strings match exactly except for 2 wildcards - '*' and '**'.
+    // '*' matches any character except those from the set ':/.?&'.
+    // '**' matches any character (like .* in a RegExp).
+    // More than 2 *'s raises an error as it's ill defined.
+    if (matcher.indexOf('***') > -1) {
+      throw $sceMinErr('iwcard',
+          'Illegal sequence *** in string matcher.  String: {0}', matcher);
+    }
+    matcher = escapeForRegexp(matcher).
+                  replace(/\\\*\\\*/g, '.*').
+                  replace(/\\\*/g, '[^:/.?&;]*');
+    return new RegExp('^' + matcher + '$');
+  } else if (isRegExp(matcher)) {
+    // The only other type of matcher allowed is a Regexp.
+    // Match entire URL / disallow partial matches.
+    // Flags are reset (i.e. no global, ignoreCase or multiline)
+    return new RegExp('^' + matcher.source + '$');
+  } else {
+    throw $sceMinErr('imatcher',
+        'Matchers may only be "self", string patterns or RegExp objects');
+  }
+}
+
+
+function adjustMatchers(matchers) {
+  var adjustedMatchers = [];
+  if (isDefined(matchers)) {
+    forEach(matchers, function(matcher) {
+      adjustedMatchers.push(adjustMatcher(matcher));
+    });
+  }
+  return adjustedMatchers;
+}
+
+
+/**
+ * @ngdoc service
+ * @name $sceDelegate
+ * @kind function
+ *
+ * @description
+ *
+ * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict
+ * Contextual Escaping (SCE)} services to AngularJS.
+ *
+ * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of
+ * the `$sce` service to customize the way Strict Contextual Escaping works in AngularJS.  This is
+ * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to
+ * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things
+ * work because `$sce` delegates to `$sceDelegate` for these operations.
+ *
+ * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service.
+ *
+ * The default instance of `$sceDelegate` should work out of the box with little pain.  While you
+ * can override it completely to change the behavior of `$sce`, the common case would
+ * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting
+ * your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as
+ * templates.  Refer {@link ng.$sceDelegateProvider#resourceUrlWhitelist
+ * $sceDelegateProvider.resourceUrlWhitelist} and {@link
+ * ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}
+ */
+
+/**
+ * @ngdoc provider
+ * @name $sceDelegateProvider
+ * @this
+ *
+ * @description
+ *
+ * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate
+ * $sceDelegate} service.  This allows one to get/set the whitelists and blacklists used to ensure
+ * that the URLs used for sourcing Angular templates are safe.  Refer {@link
+ * ng.$sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and
+ * {@link ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}
+ *
+ * For the general details about this service in Angular, read the main page for {@link ng.$sce
+ * Strict Contextual Escaping (SCE)}.
+ *
+ * **Example**:  Consider the following case. <a name="example"></a>
+ *
+ * - your app is hosted at url `http://myapp.example.com/`
+ * - but some of your templates are hosted on other domains you control such as
+ *   `http://srv01.assets.example.com/`, `http://srv02.assets.example.com/`, etc.
+ * - and you have an open redirect at `http://myapp.example.com/clickThru?...`.
+ *
+ * Here is what a secure configuration for this scenario might look like:
+ *
+ * ```
+ *  angular.module('myApp', []).config(function($sceDelegateProvider) {
+ *    $sceDelegateProvider.resourceUrlWhitelist([
+ *      // Allow same origin resource loads.
+ *      'self',
+ *      // Allow loading from our assets domain.  Notice the difference between * and **.
+ *      'http://srv*.assets.example.com/**'
+ *    ]);
+ *
+ *    // The blacklist overrides the whitelist so the open redirect here is blocked.
+ *    $sceDelegateProvider.resourceUrlBlacklist([
+ *      'http://myapp.example.com/clickThru**'
+ *    ]);
+ *  });
+ * ```
+ */
+
+function $SceDelegateProvider() {
+  this.SCE_CONTEXTS = SCE_CONTEXTS;
+
+  // Resource URLs can also be trusted by policy.
+  var resourceUrlWhitelist = ['self'],
+      resourceUrlBlacklist = [];
+
+  /**
+   * @ngdoc method
+   * @name $sceDelegateProvider#resourceUrlWhitelist
+   * @kind function
+   *
+   * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value
+   *    provided.  This must be an array or null.  A snapshot of this array is used so further
+   *    changes to the array are ignored.
+   *
+   *    Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
+   *    allowed in this array.
+   *
+   *    <div class="alert alert-warning">
+   *    **Note:** an empty whitelist array will block all URLs!
+   *    </div>
+   *
+   * @return {Array} the currently set whitelist array.
+   *
+   * The **default value** when no whitelist has been explicitly set is `['self']` allowing only
+   * same origin resource requests.
+   *
+   * @description
+   * Sets/Gets the whitelist of trusted resource URLs.
+   */
+  this.resourceUrlWhitelist = function(value) {
+    if (arguments.length) {
+      resourceUrlWhitelist = adjustMatchers(value);
+    }
+    return resourceUrlWhitelist;
+  };
+
+  /**
+   * @ngdoc method
+   * @name $sceDelegateProvider#resourceUrlBlacklist
+   * @kind function
+   *
+   * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value
+   *    provided.  This must be an array or null.  A snapshot of this array is used so further
+   *    changes to the array are ignored.
+   *
+   *    Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
+   *    allowed in this array.
+   *
+   *    The typical usage for the blacklist is to **block
+   *    [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as
+   *    these would otherwise be trusted but actually return content from the redirected domain.
+   *
+   *    Finally, **the blacklist overrides the whitelist** and has the final say.
+   *
+   * @return {Array} the currently set blacklist array.
+   *
+   * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there
+   * is no blacklist.)
+   *
+   * @description
+   * Sets/Gets the blacklist of trusted resource URLs.
+   */
+
+  this.resourceUrlBlacklist = function(value) {
+    if (arguments.length) {
+      resourceUrlBlacklist = adjustMatchers(value);
+    }
+    return resourceUrlBlacklist;
+  };
+
+  this.$get = ['$injector', function($injector) {
+
+    var htmlSanitizer = function htmlSanitizer(html) {
+      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
+    };
+
+    if ($injector.has('$sanitize')) {
+      htmlSanitizer = $injector.get('$sanitize');
+    }
+
+
+    function matchUrl(matcher, parsedUrl) {
+      if (matcher === 'self') {
+        return urlIsSameOrigin(parsedUrl);
+      } else {
+        // definitely a regex.  See adjustMatchers()
+        return !!matcher.exec(parsedUrl.href);
+      }
+    }
+
+    function isResourceUrlAllowedByPolicy(url) {
+      var parsedUrl = urlResolve(url.toString());
+      var i, n, allowed = false;
+      // Ensure that at least one item from the whitelist allows this url.
+      for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) {
+        if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) {
+          allowed = true;
+          break;
+        }
+      }
+      if (allowed) {
+        // Ensure that no item from the blacklist blocked this url.
+        for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) {
+          if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) {
+            allowed = false;
+            break;
+          }
+        }
+      }
+      return allowed;
+    }
+
+    function generateHolderType(Base) {
+      var holderType = function TrustedValueHolderType(trustedValue) {
+        this.$$unwrapTrustedValue = function() {
+          return trustedValue;
+        };
+      };
+      if (Base) {
+        holderType.prototype = new Base();
+      }
+      holderType.prototype.valueOf = function sceValueOf() {
+        return this.$$unwrapTrustedValue();
+      };
+      holderType.prototype.toString = function sceToString() {
+        return this.$$unwrapTrustedValue().toString();
+      };
+      return holderType;
+    }
+
+    var trustedValueHolderBase = generateHolderType(),
+        byType = {};
+
+    byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase);
+    byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase);
+    byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase);
+    byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase);
+    byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]);
+
+    /**
+     * @ngdoc method
+     * @name $sceDelegate#trustAs
+     *
+     * @description
+     * Returns an object that is trusted by angular for use in specified strict
+     * contextual escaping contexts (such as ng-bind-html, ng-include, any src
+     * attribute interpolation, any dom event binding attribute interpolation
+     * such as for onclick,  etc.) that uses the provided value.
+     * See {@link ng.$sce $sce} for enabling strict contextual escaping.
+     *
+     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,
+     *   resourceUrl, html, js and css.
+     * @param {*} value The value that that should be considered trusted/safe.
+     * @returns {*} A value that can be used to stand in for the provided `value` in places
+     * where Angular expects a $sce.trustAs() return value.
+     */
+    function trustAs(type, trustedValue) {
+      var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
+      if (!Constructor) {
+        throw $sceMinErr('icontext',
+            'Attempted to trust a value in invalid context. Context: {0}; Value: {1}',
+            type, trustedValue);
+      }
+      if (trustedValue === null || isUndefined(trustedValue) || trustedValue === '') {
+        return trustedValue;
+      }
+      // All the current contexts in SCE_CONTEXTS happen to be strings.  In order to avoid trusting
+      // mutable objects, we ensure here that the value passed in is actually a string.
+      if (typeof trustedValue !== 'string') {
+        throw $sceMinErr('itype',
+            'Attempted to trust a non-string value in a content requiring a string: Context: {0}',
+            type);
+      }
+      return new Constructor(trustedValue);
+    }
+
+    /**
+     * @ngdoc method
+     * @name $sceDelegate#valueOf
+     *
+     * @description
+     * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs
+     * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link
+     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.
+     *
+     * If the passed parameter is not a value that had been returned by {@link
+     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, returns it as-is.
+     *
+     * @param {*} value The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}
+     *      call or anything else.
+     * @returns {*} The `value` that was originally provided to {@link ng.$sceDelegate#trustAs
+     *     `$sceDelegate.trustAs`} if `value` is the result of such a call.  Otherwise, returns
+     *     `value` unchanged.
+     */
+    function valueOf(maybeTrusted) {
+      if (maybeTrusted instanceof trustedValueHolderBase) {
+        return maybeTrusted.$$unwrapTrustedValue();
+      } else {
+        return maybeTrusted;
+      }
+    }
+
+    /**
+     * @ngdoc method
+     * @name $sceDelegate#getTrusted
+     *
+     * @description
+     * Takes the result of a {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} call and
+     * returns the originally supplied value if the queried context type is a supertype of the
+     * created type.  If this condition isn't satisfied, throws an exception.
+     *
+     * <div class="alert alert-danger">
+     * Disabling auto-escaping is extremely dangerous, it usually creates a Cross Site Scripting
+     * (XSS) vulnerability in your application.
+     * </div>
+     *
+     * @param {string} type The kind of context in which this value is to be used.
+     * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs
+     *     `$sceDelegate.trustAs`} call.
+     * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs
+     *     `$sceDelegate.trustAs`} if valid in this context.  Otherwise, throws an exception.
+     */
+    function getTrusted(type, maybeTrusted) {
+      if (maybeTrusted === null || isUndefined(maybeTrusted) || maybeTrusted === '') {
+        return maybeTrusted;
+      }
+      var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
+      if (constructor && maybeTrusted instanceof constructor) {
+        return maybeTrusted.$$unwrapTrustedValue();
+      }
+      // If we get here, then we may only take one of two actions.
+      // 1. sanitize the value for the requested type, or
+      // 2. throw an exception.
+      if (type === SCE_CONTEXTS.RESOURCE_URL) {
+        if (isResourceUrlAllowedByPolicy(maybeTrusted)) {
+          return maybeTrusted;
+        } else {
+          throw $sceMinErr('insecurl',
+              'Blocked loading resource from url not allowed by $sceDelegate policy.  URL: {0}',
+              maybeTrusted.toString());
+        }
+      } else if (type === SCE_CONTEXTS.HTML) {
+        return htmlSanitizer(maybeTrusted);
+      }
+      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
+    }
+
+    return { trustAs: trustAs,
+             getTrusted: getTrusted,
+             valueOf: valueOf };
+  }];
+}
+
+
+/**
+ * @ngdoc provider
+ * @name $sceProvider
+ * @this
+ *
+ * @description
+ *
+ * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service.
+ * -   enable/disable Strict Contextual Escaping (SCE) in a module
+ * -   override the default implementation with a custom delegate
+ *
+ * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}.
+ */
+
+/**
+ * @ngdoc service
+ * @name $sce
+ * @kind function
+ *
+ * @description
+ *
+ * `$sce` is a service that provides Strict Contextual Escaping services to AngularJS.
+ *
+ * # Strict Contextual Escaping
+ *
+ * Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain
+ * contexts to result in a value that is marked as safe to use for that context.  One example of
+ * such a context is binding arbitrary html controlled by the user via `ng-bind-html`.  We refer
+ * to these contexts as privileged or SCE contexts.
+ *
+ * As of version 1.2, Angular ships with SCE enabled by default.
+ *
+ * Note:  When enabled (the default), IE<11 in quirks mode is not supported.  In this mode, IE<11 allow
+ * one to execute arbitrary javascript by the use of the expression() syntax.  Refer
+ * <http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx> to learn more about them.
+ * You can ensure your document is in standards mode and not quirks mode by adding `<!doctype html>`
+ * to the top of your HTML document.
+ *
+ * SCE assists in writing code in a way that (a) is secure by default and (b) makes auditing for
+ * security vulnerabilities such as XSS, clickjacking, etc. a lot easier.
+ *
+ * Here's an example of a binding in a privileged context:
+ *
+ * ```
+ * <input ng-model="userHtml" aria-label="User input">
+ * <div ng-bind-html="userHtml"></div>
+ * ```
+ *
+ * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user.  With SCE
+ * disabled, this application allows the user to render arbitrary HTML into the DIV.
+ * In a more realistic example, one may be rendering user comments, blog articles, etc. via
+ * bindings.  (HTML is just one example of a context where rendering user controlled input creates
+ * security vulnerabilities.)
+ *
+ * For the case of HTML, you might use a library, either on the client side, or on the server side,
+ * to sanitize unsafe HTML before binding to the value and rendering it in the document.
+ *
+ * How would you ensure that every place that used these types of bindings was bound to a value that
+ * was sanitized by your library (or returned as safe for rendering by your server?)  How can you
+ * ensure that you didn't accidentally delete the line that sanitized the value, or renamed some
+ * properties/fields and forgot to update the binding to the sanitized value?
+ *
+ * To be secure by default, you want to ensure that any such bindings are disallowed unless you can
+ * determine that something explicitly says it's safe to use a value for binding in that
+ * context.  You can then audit your code (a simple grep would do) to ensure that this is only done
+ * for those values that you can easily tell are safe - because they were received from your server,
+ * sanitized by your library, etc.  You can organize your codebase to help with this - perhaps
+ * allowing only the files in a specific directory to do this.  Ensuring that the internal API
+ * exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task.
+ *
+ * In the case of AngularJS' SCE service, one uses {@link ng.$sce#trustAs $sce.trustAs}
+ * (and shorthand methods such as {@link ng.$sce#trustAsHtml $sce.trustAsHtml}, etc.) to
+ * obtain values that will be accepted by SCE / privileged contexts.
+ *
+ *
+ * ## How does it work?
+ *
+ * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted
+ * $sce.getTrusted(context, value)} rather than to the value directly.  Directives use {@link
+ * ng.$sce#parseAs $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the
+ * {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals.
+ *
+ * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link
+ * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}.  Here's the actual code (slightly
+ * simplified):
+ *
+ * ```
+ * var ngBindHtmlDirective = ['$sce', function($sce) {
+ *   return function(scope, element, attr) {
+ *     scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
+ *       element.html(value || '');
+ *     });
+ *   };
+ * }];
+ * ```
+ *
+ * ## Impact on loading templates
+ *
+ * This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as
+ * `templateUrl`'s specified by {@link guide/directive directives}.
+ *
+ * By default, Angular only loads templates from the same domain and protocol as the application
+ * document.  This is done by calling {@link ng.$sce#getTrustedResourceUrl
+ * $sce.getTrustedResourceUrl} on the template URL.  To load templates from other domains and/or
+ * protocols, you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist
+ * them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value.
+ *
+ * *Please note*:
+ * The browser's
+ * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)
+ * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)
+ * policy apply in addition to this and may further restrict whether the template is successfully
+ * loaded.  This means that without the right CORS policy, loading templates from a different domain
+ * won't work on all browsers.  Also, loading templates from `file://` URL does not work on some
+ * browsers.
+ *
+ * ## This feels like too much overhead
+ *
+ * It's important to remember that SCE only applies to interpolation expressions.
+ *
+ * If your expressions are constant literals, they're automatically trusted and you don't need to
+ * call `$sce.trustAs` on them (remember to include the `ngSanitize` module) (e.g.
+ * `<div ng-bind-html="'<b>implicitly trusted</b>'"></div>`) just works.
+ *
+ * Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them
+ * through {@link ng.$sce#getTrusted $sce.getTrusted}.  SCE doesn't play a role here.
+ *
+ * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load
+ * templates in `ng-include` from your application's domain without having to even know about SCE.
+ * It blocks loading templates from other domains or loading templates over http from an https
+ * served document.  You can change these by setting your own custom {@link
+ * ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link
+ * ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs.
+ *
+ * This significantly reduces the overhead.  It is far easier to pay the small overhead and have an
+ * application that's secure and can be audited to verify that with much more ease than bolting
+ * security onto an application later.
+ *
+ * <a name="contexts"></a>
+ * ## What trusted context types are supported?
+ *
+ * | Context             | Notes          |
+ * |---------------------|----------------|
+ * | `$sce.HTML`         | For HTML that's safe to source into the application.  The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered and the {@link ngSanitize $sanitize} module is present this will sanitize the value instead of throwing an error. |
+ * | `$sce.CSS`          | For CSS that's safe to source into the application.  Currently unused.  Feel free to use it in your own directives. |
+ * | `$sce.URL`          | For URLs that are safe to follow as links.  Currently unused (`<a href=` and `<img src=` sanitize their urls and don't constitute an SCE context. |
+ * | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application.  Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG`, `VIDEO`, `AUDIO`, `SOURCE`, and `TRACK` (e.g. `IFRAME`, `OBJECT`, etc.)  <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. |
+ * | `$sce.JS`           | For JavaScript that is safe to execute in your application's context.  Currently unused.  Feel free to use it in your own directives. |
+ *
+ * ## Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist} <a name="resourceUrlPatternItem"></a>
+ *
+ *  Each element in these arrays must be one of the following:
+ *
+ *  - **'self'**
+ *    - The special **string**, `'self'`, can be used to match against all URLs of the **same
+ *      domain** as the application document using the **same protocol**.
+ *  - **String** (except the special value `'self'`)
+ *    - The string is matched against the full *normalized / absolute URL* of the resource
+ *      being tested (substring matches are not good enough.)
+ *    - There are exactly **two wildcard sequences** - `*` and `**`.  All other characters
+ *      match themselves.
+ *    - `*`: matches zero or more occurrences of any character other than one of the following 6
+ *      characters: '`:`', '`/`', '`.`', '`?`', '`&`' and '`;`'.  It's a useful wildcard for use
+ *      in a whitelist.
+ *    - `**`: matches zero or more occurrences of *any* character.  As such, it's not
+ *      appropriate for use in a scheme, domain, etc. as it would match too much.  (e.g.
+ *      http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might
+ *      not have been the intention.)  Its usage at the very end of the path is ok.  (e.g.
+ *      http://foo.example.com/templates/**).
+ *  - **RegExp** (*see caveat below*)
+ *    - *Caveat*:  While regular expressions are powerful and offer great flexibility,  their syntax
+ *      (and all the inevitable escaping) makes them *harder to maintain*.  It's easy to
+ *      accidentally introduce a bug when one updates a complex expression (imho, all regexes should
+ *      have good test coverage).  For instance, the use of `.` in the regex is correct only in a
+ *      small number of cases.  A `.` character in the regex used when matching the scheme or a
+ *      subdomain could be matched against a `:` or literal `.` that was likely not intended.   It
+ *      is highly recommended to use the string patterns and only fall back to regular expressions
+ *      as a last resort.
+ *    - The regular expression must be an instance of RegExp (i.e. not a string.)  It is
+ *      matched against the **entire** *normalized / absolute URL* of the resource being tested
+ *      (even when the RegExp did not have the `^` and `$` codes.)  In addition, any flags
+ *      present on the RegExp (such as multiline, global, ignoreCase) are ignored.
+ *    - If you are generating your JavaScript from some other templating engine (not
+ *      recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)),
+ *      remember to escape your regular expression (and be aware that you might need more than
+ *      one level of escaping depending on your templating engine and the way you interpolated
+ *      the value.)  Do make use of your platform's escaping mechanism as it might be good
+ *      enough before coding your own.  E.g. Ruby has
+ *      [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape)
+ *      and Python has [re.escape](http://docs.python.org/library/re.html#re.escape).
+ *      Javascript lacks a similar built in function for escaping.  Take a look at Google
+ *      Closure library's [goog.string.regExpEscape(s)](
+ *      http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962).
+ *
+ * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example.
+ *
+ * ## Show me an example using SCE.
+ *
+ * <example module="mySceApp" deps="angular-sanitize.js" name="sce-service">
+ * <file name="index.html">
+ *   <div ng-controller="AppController as myCtrl">
+ *     <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
+ *     <b>User comments</b><br>
+ *     By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when
+ *     $sanitize is available.  If $sanitize isn't available, this results in an error instead of an
+ *     exploit.
+ *     <div class="well">
+ *       <div ng-repeat="userComment in myCtrl.userComments">
+ *         <b>{{userComment.name}}</b>:
+ *         <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span>
+ *         <br>
+ *       </div>
+ *     </div>
+ *   </div>
+ * </file>
+ *
+ * <file name="script.js">
+ *   angular.module('mySceApp', ['ngSanitize'])
+ *     .controller('AppController', ['$http', '$templateCache', '$sce',
+ *       function AppController($http, $templateCache, $sce) {
+ *         var self = this;
+ *         $http.get('test_data.json', {cache: $templateCache}).then(function(response) {
+ *           self.userComments = response.data;
+ *         });
+ *         self.explicitlyTrustedHtml = $sce.trustAsHtml(
+ *             '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
+ *             'sanitization.&quot;">Hover over this text.</span>');
+ *       }]);
+ * </file>
+ *
+ * <file name="test_data.json">
+ * [
+ *   { "name": "Alice",
+ *     "htmlComment":
+ *         "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>"
+ *   },
+ *   { "name": "Bob",
+ *     "htmlComment": "<i>Yes!</i>  Am I the only other one?"
+ *   }
+ * ]
+ * </file>
+ *
+ * <file name="protractor.js" type="protractor">
+ *   describe('SCE doc demo', function() {
+ *     it('should sanitize untrusted values', function() {
+ *       expect(element.all(by.css('.htmlComment')).first().getAttribute('innerHTML'))
+ *           .toBe('<span>Is <i>anyone</i> reading this?</span>');
+ *     });
+ *
+ *     it('should NOT sanitize explicitly trusted values', function() {
+ *       expect(element(by.id('explicitlyTrustedHtml')).getAttribute('innerHTML')).toBe(
+ *           '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
+ *           'sanitization.&quot;">Hover over this text.</span>');
+ *     });
+ *   });
+ * </file>
+ * </example>
+ *
+ *
+ *
+ * ## Can I disable SCE completely?
+ *
+ * Yes, you can.  However, this is strongly discouraged.  SCE gives you a lot of security benefits
+ * for little coding overhead.  It will be much harder to take an SCE disabled application and
+ * either secure it on your own or enable SCE at a later stage.  It might make sense to disable SCE
+ * for cases where you have a lot of existing code that was written before SCE was introduced and
+ * you're migrating them a module at a time.
+ *
+ * That said, here's how you can completely disable SCE:
+ *
+ * ```
+ * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
+ *   // Completely disable SCE.  For demonstration purposes only!
+ *   // Do not use in new projects.
+ *   $sceProvider.enabled(false);
+ * });
+ * ```
+ *
+ */
+
+function $SceProvider() {
+  var enabled = true;
+
+  /**
+   * @ngdoc method
+   * @name $sceProvider#enabled
+   * @kind function
+   *
+   * @param {boolean=} value If provided, then enables/disables SCE.
+   * @return {boolean} true if SCE is enabled, false otherwise.
+   *
+   * @description
+   * Enables/disables SCE and returns the current value.
+   */
+  this.enabled = function(value) {
+    if (arguments.length) {
+      enabled = !!value;
+    }
+    return enabled;
+  };
+
+
+  /* Design notes on the default implementation for SCE.
+   *
+   * The API contract for the SCE delegate
+   * -------------------------------------
+   * The SCE delegate object must provide the following 3 methods:
+   *
+   * - trustAs(contextEnum, value)
+   *     This method is used to tell the SCE service that the provided value is OK to use in the
+   *     contexts specified by contextEnum.  It must return an object that will be accepted by
+   *     getTrusted() for a compatible contextEnum and return this value.
+   *
+   * - valueOf(value)
+   *     For values that were not produced by trustAs(), return them as is.  For values that were
+   *     produced by trustAs(), return the corresponding input value to trustAs.  Basically, if
+   *     trustAs is wrapping the given values into some type, this operation unwraps it when given
+   *     such a value.
+   *
+   * - getTrusted(contextEnum, value)
+   *     This function should return the a value that is safe to use in the context specified by
+   *     contextEnum or throw and exception otherwise.
+   *
+   * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be
+   * opaque or wrapped in some holder object.  That happens to be an implementation detail.  For
+   * instance, an implementation could maintain a registry of all trusted objects by context.  In
+   * such a case, trustAs() would return the same object that was passed in.  getTrusted() would
+   * return the same object passed in if it was found in the registry under a compatible context or
+   * throw an exception otherwise.  An implementation might only wrap values some of the time based
+   * on some criteria.  getTrusted() might return a value and not throw an exception for special
+   * constants or objects even if not wrapped.  All such implementations fulfill this contract.
+   *
+   *
+   * A note on the inheritance model for SCE contexts
+   * ------------------------------------------------
+   * I've used inheritance and made RESOURCE_URL wrapped types a subtype of URL wrapped types.  This
+   * is purely an implementation details.
+   *
+   * The contract is simply this:
+   *
+   *     getTrusted($sce.RESOURCE_URL, value) succeeding implies that getTrusted($sce.URL, value)
+   *     will also succeed.
+   *
+   * Inheritance happens to capture this in a natural way.  In some future, we
+   * may not use inheritance anymore.  That is OK because no code outside of
+   * sce.js and sceSpecs.js would need to be aware of this detail.
+   */
+
+  this.$get = ['$parse', '$sceDelegate', function(
+                $parse,   $sceDelegate) {
+    // Support: IE 9-11 only
+    // Prereq: Ensure that we're not running in IE<11 quirks mode.  In that mode, IE < 11 allow
+    // the "expression(javascript expression)" syntax which is insecure.
+    if (enabled && msie < 8) {
+      throw $sceMinErr('iequirks',
+        'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' +
+        'mode.  You can fix this by adding the text <!doctype html> to the top of your HTML ' +
+        'document.  See http://docs.angularjs.org/api/ng.$sce for more information.');
+    }
+
+    var sce = shallowCopy(SCE_CONTEXTS);
+
+    /**
+     * @ngdoc method
+     * @name $sce#isEnabled
+     * @kind function
+     *
+     * @return {Boolean} true if SCE is enabled, false otherwise.  If you want to set the value, you
+     * have to do it at module config time on {@link ng.$sceProvider $sceProvider}.
+     *
+     * @description
+     * Returns a boolean indicating if SCE is enabled.
+     */
+    sce.isEnabled = function() {
+      return enabled;
+    };
+    sce.trustAs = $sceDelegate.trustAs;
+    sce.getTrusted = $sceDelegate.getTrusted;
+    sce.valueOf = $sceDelegate.valueOf;
+
+    if (!enabled) {
+      sce.trustAs = sce.getTrusted = function(type, value) { return value; };
+      sce.valueOf = identity;
+    }
+
+    /**
+     * @ngdoc method
+     * @name $sce#parseAs
+     *
+     * @description
+     * Converts Angular {@link guide/expression expression} into a function.  This is like {@link
+     * ng.$parse $parse} and is identical when the expression is a literal constant.  Otherwise, it
+     * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*,
+     * *result*)}
+     *
+     * @param {string} type The kind of SCE context in which this result will be used.
+     * @param {string} expression String expression to compile.
+     * @returns {function(context, locals)} a function which represents the compiled expression:
+     *
+     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
+     *      are evaluated against (typically a scope object).
+     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
+     *      `context`.
+     */
+    sce.parseAs = function sceParseAs(type, expr) {
+      var parsed = $parse(expr);
+      if (parsed.literal && parsed.constant) {
+        return parsed;
+      } else {
+        return $parse(expr, function(value) {
+          return sce.getTrusted(type, value);
+        });
+      }
+    };
+
+    /**
+     * @ngdoc method
+     * @name $sce#trustAs
+     *
+     * @description
+     * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.  As such,
+     * returns an object that is trusted by angular for use in specified strict contextual
+     * escaping contexts (such as ng-bind-html, ng-include, any src attribute
+     * interpolation, any dom event binding attribute interpolation such as for onclick,  etc.)
+     * that uses the provided value.  See * {@link ng.$sce $sce} for enabling strict contextual
+     * escaping.
+     *
+     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,
+     *   resourceUrl, html, js and css.
+     * @param {*} value The value that that should be considered trusted/safe.
+     * @returns {*} A value that can be used to stand in for the provided `value` in places
+     * where Angular expects a $sce.trustAs() return value.
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#trustAsHtml
+     *
+     * @description
+     * Shorthand method.  `$sce.trustAsHtml(value)` →
+     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`}
+     *
+     * @param {*} value The value to trustAs.
+     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedHtml
+     *     $sce.getTrustedHtml(value)} to obtain the original value.  (privileged directives
+     *     only accept expressions that are either literal constants or are the
+     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#trustAsUrl
+     *
+     * @description
+     * Shorthand method.  `$sce.trustAsUrl(value)` →
+     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`}
+     *
+     * @param {*} value The value to trustAs.
+     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedUrl
+     *     $sce.getTrustedUrl(value)} to obtain the original value.  (privileged directives
+     *     only accept expressions that are either literal constants or are the
+     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#trustAsResourceUrl
+     *
+     * @description
+     * Shorthand method.  `$sce.trustAsResourceUrl(value)` →
+     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`}
+     *
+     * @param {*} value The value to trustAs.
+     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedResourceUrl
+     *     $sce.getTrustedResourceUrl(value)} to obtain the original value.  (privileged directives
+     *     only accept expressions that are either literal constants or are the return
+     *     value of {@link ng.$sce#trustAs $sce.trustAs}.)
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#trustAsJs
+     *
+     * @description
+     * Shorthand method.  `$sce.trustAsJs(value)` →
+     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`}
+     *
+     * @param {*} value The value to trustAs.
+     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedJs
+     *     $sce.getTrustedJs(value)} to obtain the original value.  (privileged directives
+     *     only accept expressions that are either literal constants or are the
+     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#getTrusted
+     *
+     * @description
+     * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}.  As such,
+     * takes the result of a {@link ng.$sce#trustAs `$sce.trustAs`}() call and returns the
+     * originally supplied value if the queried context type is a supertype of the created type.
+     * If this condition isn't satisfied, throws an exception.
+     *
+     * @param {string} type The kind of context in which this value is to be used.
+     * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs `$sce.trustAs`}
+     *                         call.
+     * @returns {*} The value the was originally provided to
+     *              {@link ng.$sce#trustAs `$sce.trustAs`} if valid in this context.
+     *              Otherwise, throws an exception.
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#getTrustedHtml
+     *
+     * @description
+     * Shorthand method.  `$sce.getTrustedHtml(value)` →
+     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`}
+     *
+     * @param {*} value The value to pass to `$sce.getTrusted`.
+     * @returns {*} The return value of `$sce.getTrusted($sce.HTML, value)`
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#getTrustedCss
+     *
+     * @description
+     * Shorthand method.  `$sce.getTrustedCss(value)` →
+     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`}
+     *
+     * @param {*} value The value to pass to `$sce.getTrusted`.
+     * @returns {*} The return value of `$sce.getTrusted($sce.CSS, value)`
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#getTrustedUrl
+     *
+     * @description
+     * Shorthand method.  `$sce.getTrustedUrl(value)` →
+     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`}
+     *
+     * @param {*} value The value to pass to `$sce.getTrusted`.
+     * @returns {*} The return value of `$sce.getTrusted($sce.URL, value)`
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#getTrustedResourceUrl
+     *
+     * @description
+     * Shorthand method.  `$sce.getTrustedResourceUrl(value)` →
+     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`}
+     *
+     * @param {*} value The value to pass to `$sceDelegate.getTrusted`.
+     * @returns {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)`
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#getTrustedJs
+     *
+     * @description
+     * Shorthand method.  `$sce.getTrustedJs(value)` →
+     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`}
+     *
+     * @param {*} value The value to pass to `$sce.getTrusted`.
+     * @returns {*} The return value of `$sce.getTrusted($sce.JS, value)`
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#parseAsHtml
+     *
+     * @description
+     * Shorthand method.  `$sce.parseAsHtml(expression string)` →
+     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`}
+     *
+     * @param {string} expression String expression to compile.
+     * @returns {function(context, locals)} a function which represents the compiled expression:
+     *
+     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
+     *      are evaluated against (typically a scope object).
+     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
+     *      `context`.
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#parseAsCss
+     *
+     * @description
+     * Shorthand method.  `$sce.parseAsCss(value)` →
+     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`}
+     *
+     * @param {string} expression String expression to compile.
+     * @returns {function(context, locals)} a function which represents the compiled expression:
+     *
+     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
+     *      are evaluated against (typically a scope object).
+     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
+     *      `context`.
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#parseAsUrl
+     *
+     * @description
+     * Shorthand method.  `$sce.parseAsUrl(value)` →
+     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`}
+     *
+     * @param {string} expression String expression to compile.
+     * @returns {function(context, locals)} a function which represents the compiled expression:
+     *
+     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
+     *      are evaluated against (typically a scope object).
+     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
+     *      `context`.
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#parseAsResourceUrl
+     *
+     * @description
+     * Shorthand method.  `$sce.parseAsResourceUrl(value)` →
+     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}
+     *
+     * @param {string} expression String expression to compile.
+     * @returns {function(context, locals)} a function which represents the compiled expression:
+     *
+     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
+     *      are evaluated against (typically a scope object).
+     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
+     *      `context`.
+     */
+
+    /**
+     * @ngdoc method
+     * @name $sce#parseAsJs
+     *
+     * @description
+     * Shorthand method.  `$sce.parseAsJs(value)` →
+     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`}
+     *
+     * @param {string} expression String expression to compile.
+     * @returns {function(context, locals)} a function which represents the compiled expression:
+     *
+     *    * `context` – `{object}` – an object against which any expressions embedded in the strings
+     *      are evaluated against (typically a scope object).
+     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in
+     *      `context`.
+     */
+
+    // Shorthand delegations.
+    var parse = sce.parseAs,
+        getTrusted = sce.getTrusted,
+        trustAs = sce.trustAs;
+
+    forEach(SCE_CONTEXTS, function(enumValue, name) {
+      var lName = lowercase(name);
+      sce[snakeToCamel('parse_as_' + lName)] = function(expr) {
+        return parse(enumValue, expr);
+      };
+      sce[snakeToCamel('get_trusted_' + lName)] = function(value) {
+        return getTrusted(enumValue, value);
+      };
+      sce[snakeToCamel('trust_as_' + lName)] = function(value) {
+        return trustAs(enumValue, value);
+      };
+    });
+
+    return sce;
+  }];
+}
+
+/* exported $SnifferProvider */
+
+/**
+ * !!! This is an undocumented "private" service !!!
+ *
+ * @name $sniffer
+ * @requires $window
+ * @requires $document
+ * @this
+ *
+ * @property {boolean} history Does the browser support html5 history api ?
+ * @property {boolean} transitions Does the browser support CSS transition events ?
+ * @property {boolean} animations Does the browser support CSS animation events ?
+ *
+ * @description
+ * This is very simple implementation of testing browser's features.
+ */
+function $SnifferProvider() {
+  this.$get = ['$window', '$document', function($window, $document) {
+    var eventSupport = {},
+        // Chrome Packaged Apps are not allowed to access `history.pushState`.
+        // If not sandboxed, they can be detected by the presence of `chrome.app.runtime`
+        // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by
+        // the presence of an extension runtime ID and the absence of other Chrome runtime APIs
+        // (see https://developer.chrome.com/apps/manifest/sandbox).
+        // (NW.js apps have access to Chrome APIs, but do support `history`.)
+        isNw = $window.nw && $window.nw.process,
+        isChromePackagedApp =
+            !isNw &&
+            $window.chrome &&
+            ($window.chrome.app && $window.chrome.app.runtime ||
+                !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id),
+        hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState,
+        android =
+          toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
+        boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
+        document = $document[0] || {},
+        bodyStyle = document.body && document.body.style,
+        transitions = false,
+        animations = false;
+
+    if (bodyStyle) {
+      // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x
+      // Mentioned browsers need a -webkit- prefix for transitions & animations.
+      transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle);
+      animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle);
+    }
+
+
+    return {
+      // Android has history.pushState, but it does not update location correctly
+      // so let's not use the history API at all.
+      // http://code.google.com/p/android/issues/detail?id=17471
+      // https://github.com/angular/angular.js/issues/904
+
+      // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has
+      // so let's not use the history API also
+      // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
+      history: !!(hasHistoryPushState && !(android < 4) && !boxee),
+      hasEvent: function(event) {
+        // Support: IE 9-11 only
+        // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
+        // it. In particular the event is not fired when backspace or delete key are pressed or
+        // when cut operation is performed.
+        // IE10+ implements 'input' event but it erroneously fires under various situations,
+        // e.g. when placeholder changes, or a form is focused.
+        if (event === 'input' && msie) return false;
+
+        if (isUndefined(eventSupport[event])) {
+          var divElm = document.createElement('div');
+          eventSupport[event] = 'on' + event in divElm;
+        }
+
+        return eventSupport[event];
+      },
+      csp: csp(),
+      transitions: transitions,
+      animations: animations,
+      android: android
+    };
+  }];
+}
+
+var $templateRequestMinErr = minErr('$compile');
+
+/**
+ * @ngdoc provider
+ * @name $templateRequestProvider
+ * @this
+ *
+ * @description
+ * Used to configure the options passed to the {@link $http} service when making a template request.
+ *
+ * For example, it can be used for specifying the "Accept" header that is sent to the server, when
+ * requesting a template.
+ */
+function $TemplateRequestProvider() {
+
+  var httpOptions;
+
+  /**
+   * @ngdoc method
+   * @name $templateRequestProvider#httpOptions
+   * @description
+   * The options to be passed to the {@link $http} service when making the request.
+   * You can use this to override options such as the "Accept" header for template requests.
+   *
+   * The {@link $templateRequest} will set the `cache` and the `transformResponse` properties of the
+   * options if not overridden here.
+   *
+   * @param {string=} value new value for the {@link $http} options.
+   * @returns {string|self} Returns the {@link $http} options when used as getter and self if used as setter.
+   */
+  this.httpOptions = function(val) {
+    if (val) {
+      httpOptions = val;
+      return this;
+    }
+    return httpOptions;
+  };
+
+  /**
+   * @ngdoc service
+   * @name $templateRequest
+   *
+   * @description
+   * The `$templateRequest` service runs security checks then downloads the provided template using
+   * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request
+   * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the
+   * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the
+   * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted
+   * when `tpl` is of type string and `$templateCache` has the matching entry.
+   *
+   * If you want to pass custom options to the `$http` service, such as setting the Accept header you
+   * can configure this via {@link $templateRequestProvider#httpOptions}.
+   *
+   * @param {string|TrustedResourceUrl} tpl The HTTP request template URL
+   * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty
+   *
+   * @return {Promise} a promise for the HTTP response data of the given URL.
+   *
+   * @property {number} totalPendingRequests total amount of pending template requests being downloaded.
+   */
+  this.$get = ['$exceptionHandler', '$templateCache', '$http', '$q', '$sce',
+    function($exceptionHandler, $templateCache, $http, $q, $sce) {
+
+      function handleRequestFn(tpl, ignoreRequestError) {
+        handleRequestFn.totalPendingRequests++;
+
+        // We consider the template cache holds only trusted templates, so
+        // there's no need to go through whitelisting again for keys that already
+        // are included in there. This also makes Angular accept any script
+        // directive, no matter its name. However, we still need to unwrap trusted
+        // types.
+        if (!isString(tpl) || isUndefined($templateCache.get(tpl))) {
+          tpl = $sce.getTrustedResourceUrl(tpl);
+        }
+
+        var transformResponse = $http.defaults && $http.defaults.transformResponse;
+
+        if (isArray(transformResponse)) {
+          transformResponse = transformResponse.filter(function(transformer) {
+            return transformer !== defaultHttpResponseTransform;
+          });
+        } else if (transformResponse === defaultHttpResponseTransform) {
+          transformResponse = null;
+        }
+
+        return $http.get(tpl, extend({
+            cache: $templateCache,
+            transformResponse: transformResponse
+          }, httpOptions))
+          .finally(function() {
+            handleRequestFn.totalPendingRequests--;
+          })
+          .then(function(response) {
+            $templateCache.put(tpl, response.data);
+            return response.data;
+          }, handleError);
+
+        function handleError(resp) {
+          if (!ignoreRequestError) {
+            resp = $templateRequestMinErr('tpload',
+                'Failed to load template: {0} (HTTP status: {1} {2})',
+                tpl, resp.status, resp.statusText);
+
+            $exceptionHandler(resp);
+          }
+
+          return $q.reject(resp);
+        }
+      }
+
+      handleRequestFn.totalPendingRequests = 0;
+
+      return handleRequestFn;
+    }
+  ];
+}
+
+/** @this */
+function $$TestabilityProvider() {
+  this.$get = ['$rootScope', '$browser', '$location',
+       function($rootScope,   $browser,   $location) {
+
+    /**
+     * @name $testability
+     *
+     * @description
+     * The private $$testability service provides a collection of methods for use when debugging
+     * or by automated test and debugging tools.
+     */
+    var testability = {};
+
+    /**
+     * @name $$testability#findBindings
+     *
+     * @description
+     * Returns an array of elements that are bound (via ng-bind or {{}})
+     * to expressions matching the input.
+     *
+     * @param {Element} element The element root to search from.
+     * @param {string} expression The binding expression to match.
+     * @param {boolean} opt_exactMatch If true, only returns exact matches
+     *     for the expression. Filters and whitespace are ignored.
+     */
+    testability.findBindings = function(element, expression, opt_exactMatch) {
+      var bindings = element.getElementsByClassName('ng-binding');
+      var matches = [];
+      forEach(bindings, function(binding) {
+        var dataBinding = angular.element(binding).data('$binding');
+        if (dataBinding) {
+          forEach(dataBinding, function(bindingName) {
+            if (opt_exactMatch) {
+              var matcher = new RegExp('(^|\\s)' + escapeForRegexp(expression) + '(\\s|\\||$)');
+              if (matcher.test(bindingName)) {
+                matches.push(binding);
+              }
+            } else {
+              if (bindingName.indexOf(expression) !== -1) {
+                matches.push(binding);
+              }
+            }
+          });
+        }
+      });
+      return matches;
+    };
+
+    /**
+     * @name $$testability#findModels
+     *
+     * @description
+     * Returns an array of elements that are two-way found via ng-model to
+     * expressions matching the input.
+     *
+     * @param {Element} element The element root to search from.
+     * @param {string} expression The model expression to match.
+     * @param {boolean} opt_exactMatch If true, only returns exact matches
+     *     for the expression.
+     */
+    testability.findModels = function(element, expression, opt_exactMatch) {
+      var prefixes = ['ng-', 'data-ng-', 'ng\\:'];
+      for (var p = 0; p < prefixes.length; ++p) {
+        var attributeEquals = opt_exactMatch ? '=' : '*=';
+        var selector = '[' + prefixes[p] + 'model' + attributeEquals + '"' + expression + '"]';
+        var elements = element.querySelectorAll(selector);
+        if (elements.length) {
+          return elements;
+        }
+      }
+    };
+
+    /**
+     * @name $$testability#getLocation
+     *
+     * @description
+     * Shortcut for getting the location in a browser agnostic way. Returns
+     *     the path, search, and hash. (e.g. /path?a=b#hash)
+     */
+    testability.getLocation = function() {
+      return $location.url();
+    };
+
+    /**
+     * @name $$testability#setLocation
+     *
+     * @description
+     * Shortcut for navigating to a location without doing a full page reload.
+     *
+     * @param {string} url The location url (path, search and hash,
+     *     e.g. /path?a=b#hash) to go to.
+     */
+    testability.setLocation = function(url) {
+      if (url !== $location.url()) {
+        $location.url(url);
+        $rootScope.$digest();
+      }
+    };
+
+    /**
+     * @name $$testability#whenStable
+     *
+     * @description
+     * Calls the callback when $timeout and $http requests are completed.
+     *
+     * @param {function} callback
+     */
+    testability.whenStable = function(callback) {
+      $browser.notifyWhenNoOutstandingRequests(callback);
+    };
+
+    return testability;
+  }];
+}
+
+/** @this */
+function $TimeoutProvider() {
+  this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
+       function($rootScope,   $browser,   $q,   $$q,   $exceptionHandler) {
+
+    var deferreds = {};
+
+
+     /**
+      * @ngdoc service
+      * @name $timeout
+      *
+      * @description
+      * Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch
+      * block and delegates any exceptions to
+      * {@link ng.$exceptionHandler $exceptionHandler} service.
+      *
+      * The return value of calling `$timeout` is a promise, which will be resolved when
+      * the delay has passed and the timeout function, if provided, is executed.
+      *
+      * To cancel a timeout request, call `$timeout.cancel(promise)`.
+      *
+      * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
+      * synchronously flush the queue of deferred functions.
+      *
+      * If you only want a promise that will be resolved after some specified delay
+      * then you can call `$timeout` without the `fn` function.
+      *
+      * @param {function()=} fn A function, whose execution should be delayed.
+      * @param {number=} [delay=0] Delay in milliseconds.
+      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
+      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
+      * @param {...*=} Pass additional parameters to the executed function.
+      * @returns {Promise} Promise that will be resolved when the timeout is reached. The promise
+      *   will be resolved with the return value of the `fn` function.
+      *
+      */
+    function timeout(fn, delay, invokeApply) {
+      if (!isFunction(fn)) {
+        invokeApply = delay;
+        delay = fn;
+        fn = noop;
+      }
+
+      var args = sliceArgs(arguments, 3),
+          skipApply = (isDefined(invokeApply) && !invokeApply),
+          deferred = (skipApply ? $$q : $q).defer(),
+          promise = deferred.promise,
+          timeoutId;
+
+      timeoutId = $browser.defer(function() {
+        try {
+          deferred.resolve(fn.apply(null, args));
+        } catch (e) {
+          deferred.reject(e);
+          $exceptionHandler(e);
+        } finally {
+          delete deferreds[promise.$$timeoutId];
+        }
+
+        if (!skipApply) $rootScope.$apply();
+      }, delay);
+
+      promise.$$timeoutId = timeoutId;
+      deferreds[timeoutId] = deferred;
+
+      return promise;
+    }
+
+
+     /**
+      * @ngdoc method
+      * @name $timeout#cancel
+      *
+      * @description
+      * Cancels a task associated with the `promise`. As a result of this, the promise will be
+      * resolved with a rejection.
+      *
+      * @param {Promise=} promise Promise returned by the `$timeout` function.
+      * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
+      *   canceled.
+      */
+    timeout.cancel = function(promise) {
+      if (promise && promise.$$timeoutId in deferreds) {
+        // Timeout cancels should not report an unhandled promise.
+        deferreds[promise.$$timeoutId].promise.catch(noop);
+        deferreds[promise.$$timeoutId].reject('canceled');
+        delete deferreds[promise.$$timeoutId];
+        return $browser.defer.cancel(promise.$$timeoutId);
+      }
+      return false;
+    };
+
+    return timeout;
+  }];
+}
+
+// NOTE:  The usage of window and document instead of $window and $document here is
+// deliberate.  This service depends on the specific behavior of anchor nodes created by the
+// browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and
+// cause us to break tests.  In addition, when the browser resolves a URL for XHR, it
+// doesn't know about mocked locations and resolves URLs to the real document - which is
+// exactly the behavior needed here.  There is little value is mocking these out for this
+// service.
+var urlParsingNode = window.document.createElement('a');
+var originUrl = urlResolve(window.location.href);
+
+
+/**
+ *
+ * Implementation Notes for non-IE browsers
+ * ----------------------------------------
+ * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,
+ * results both in the normalizing and parsing of the URL.  Normalizing means that a relative
+ * URL will be resolved into an absolute URL in the context of the application document.
+ * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related
+ * properties are all populated to reflect the normalized URL.  This approach has wide
+ * compatibility - Safari 1+, Mozilla 1+ etc.  See
+ * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
+ *
+ * Implementation Notes for IE
+ * ---------------------------
+ * IE <= 10 normalizes the URL when assigned to the anchor node similar to the other
+ * browsers.  However, the parsed components will not be set if the URL assigned did not specify
+ * them.  (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.)  We
+ * work around that by performing the parsing in a 2nd step by taking a previously normalized
+ * URL (e.g. by assigning to a.href) and assigning it a.href again.  This correctly populates the
+ * properties such as protocol, hostname, port, etc.
+ *
+ * References:
+ *   http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement
+ *   http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
+ *   http://url.spec.whatwg.org/#urlutils
+ *   https://github.com/angular/angular.js/pull/2902
+ *   http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
+ *
+ * @kind function
+ * @param {string} url The URL to be parsed.
+ * @description Normalizes and parses a URL.
+ * @returns {object} Returns the normalized URL as a dictionary.
+ *
+ *   | member name   | Description    |
+ *   |---------------|----------------|
+ *   | href          | A normalized version of the provided URL if it was not an absolute URL |
+ *   | protocol      | The protocol including the trailing colon                              |
+ *   | host          | The host and port (if the port is non-default) of the normalizedUrl    |
+ *   | search        | The search params, minus the question mark                             |
+ *   | hash          | The hash string, minus the hash symbol
+ *   | hostname      | The hostname
+ *   | port          | The port, without ":"
+ *   | pathname      | The pathname, beginning with "/"
+ *
+ */
+function urlResolve(url) {
+  var href = url;
+
+  // Support: IE 9-11 only
+  if (msie) {
+    // Normalize before parse.  Refer Implementation Notes on why this is
+    // done in two steps on IE.
+    urlParsingNode.setAttribute('href', href);
+    href = urlParsingNode.href;
+  }
+
+  urlParsingNode.setAttribute('href', href);
+
+  // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
+  return {
+    href: urlParsingNode.href,
+    protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
+    host: urlParsingNode.host,
+    search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
+    hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
+    hostname: urlParsingNode.hostname,
+    port: urlParsingNode.port,
+    pathname: (urlParsingNode.pathname.charAt(0) === '/')
+      ? urlParsingNode.pathname
+      : '/' + urlParsingNode.pathname
+  };
+}
+
+/**
+ * Parse a request URL and determine whether this is a same-origin request as the application document.
+ *
+ * @param {string|object} requestUrl The url of the request as a string that will be resolved
+ * or a parsed URL object.
+ * @returns {boolean} Whether the request is for the same origin as the application document.
+ */
+function urlIsSameOrigin(requestUrl) {
+  var parsed = (isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl;
+  return (parsed.protocol === originUrl.protocol &&
+          parsed.host === originUrl.host);
+}
+
+/**
+ * @ngdoc service
+ * @name $window
+ * @this
+ *
+ * @description
+ * A reference to the browser's `window` object. While `window`
+ * is globally available in JavaScript, it causes testability problems, because
+ * it is a global variable. In angular we always refer to it through the
+ * `$window` service, so it may be overridden, removed or mocked for testing.
+ *
+ * Expressions, like the one defined for the `ngClick` directive in the example
+ * below, are evaluated with respect to the current scope.  Therefore, there is
+ * no risk of inadvertently coding in a dependency on a global value in such an
+ * expression.
+ *
+ * @example
+   <example module="windowExample" name="window-service">
+     <file name="index.html">
+       <script>
+         angular.module('windowExample', [])
+           .controller('ExampleController', ['$scope', '$window', function($scope, $window) {
+             $scope.greeting = 'Hello, World!';
+             $scope.doGreeting = function(greeting) {
+               $window.alert(greeting);
+             };
+           }]);
+       </script>
+       <div ng-controller="ExampleController">
+         <input type="text" ng-model="greeting" aria-label="greeting" />
+         <button ng-click="doGreeting(greeting)">ALERT</button>
+       </div>
+     </file>
+     <file name="protractor.js" type="protractor">
+      it('should display the greeting in the input box', function() {
+       element(by.model('greeting')).sendKeys('Hello, E2E Tests');
+       // If we click the button it will block the test runner
+       // element(':button').click();
+      });
+     </file>
+   </example>
+ */
+function $WindowProvider() {
+  this.$get = valueFn(window);
+}
+
+/**
+ * @name $$cookieReader
+ * @requires $document
+ *
+ * @description
+ * This is a private service for reading cookies used by $http and ngCookies
+ *
+ * @return {Object} a key/value map of the current cookies
+ */
+function $$CookieReader($document) {
+  var rawDocument = $document[0] || {};
+  var lastCookies = {};
+  var lastCookieString = '';
+
+  function safeGetCookie(rawDocument) {
+    try {
+      return rawDocument.cookie || '';
+    } catch (e) {
+      return '';
+    }
+  }
+
+  function safeDecodeURIComponent(str) {
+    try {
+      return decodeURIComponent(str);
+    } catch (e) {
+      return str;
+    }
+  }
+
+  return function() {
+    var cookieArray, cookie, i, index, name;
+    var currentCookieString = safeGetCookie(rawDocument);
+
+    if (currentCookieString !== lastCookieString) {
+      lastCookieString = currentCookieString;
+      cookieArray = lastCookieString.split('; ');
+      lastCookies = {};
+
+      for (i = 0; i < cookieArray.length; i++) {
+        cookie = cookieArray[i];
+        index = cookie.indexOf('=');
+        if (index > 0) { //ignore nameless cookies
+          name = safeDecodeURIComponent(cookie.substring(0, index));
+          // the first value that is seen for a cookie is the most
+          // specific one.  values for the same cookie name that
+          // follow are for less specific paths.
+          if (isUndefined(lastCookies[name])) {
+            lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
+          }
+        }
+      }
+    }
+    return lastCookies;
+  };
+}
+
+$$CookieReader.$inject = ['$document'];
+
+/** @this */
+function $$CookieReaderProvider() {
+  this.$get = $$CookieReader;
+}
+
+/* global currencyFilter: true,
+ dateFilter: true,
+ filterFilter: true,
+ jsonFilter: true,
+ limitToFilter: true,
+ lowercaseFilter: true,
+ numberFilter: true,
+ orderByFilter: true,
+ uppercaseFilter: true,
+ */
+
+/**
+ * @ngdoc provider
+ * @name $filterProvider
+ * @description
+ *
+ * Filters are just functions which transform input to an output. However filters need to be
+ * Dependency Injected. To achieve this a filter definition consists of a factory function which is
+ * annotated with dependencies and is responsible for creating a filter function.
+ *
+ * <div class="alert alert-warning">
+ * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
+ * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
+ * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
+ * (`myapp_subsection_filterx`).
+ * </div>
+ *
+ * ```js
+ *   // Filter registration
+ *   function MyModule($provide, $filterProvider) {
+ *     // create a service to demonstrate injection (not always needed)
+ *     $provide.value('greet', function(name){
+ *       return 'Hello ' + name + '!';
+ *     });
+ *
+ *     // register a filter factory which uses the
+ *     // greet service to demonstrate DI.
+ *     $filterProvider.register('greet', function(greet){
+ *       // return the filter function which uses the greet service
+ *       // to generate salutation
+ *       return function(text) {
+ *         // filters need to be forgiving so check input validity
+ *         return text && greet(text) || text;
+ *       };
+ *     });
+ *   }
+ * ```
+ *
+ * The filter function is registered with the `$injector` under the filter name suffix with
+ * `Filter`.
+ *
+ * ```js
+ *   it('should be the same instance', inject(
+ *     function($filterProvider) {
+ *       $filterProvider.register('reverse', function(){
+ *         return ...;
+ *       });
+ *     },
+ *     function($filter, reverseFilter) {
+ *       expect($filter('reverse')).toBe(reverseFilter);
+ *     });
+ * ```
+ *
+ *
+ * For more information about how angular filters work, and how to create your own filters, see
+ * {@link guide/filter Filters} in the Angular Developer Guide.
+ */
+
+/**
+ * @ngdoc service
+ * @name $filter
+ * @kind function
+ * @description
+ * Filters are used for formatting data displayed to the user.
+ *
+ * They can be used in view templates, controllers or services.Angular comes
+ * with a collection of [built-in filters](api/ng/filter), but it is easy to
+ * define your own as well.
+ *
+ * The general syntax in templates is as follows:
+ *
+ * ```html
+ * {{ expression [| filter_name[:parameter_value] ... ] }}
+ * ```
+ *
+ * @param {String} name Name of the filter function to retrieve
+ * @return {Function} the filter function
+ * @example
+   <example name="$filter" module="filterExample">
+     <file name="index.html">
+       <div ng-controller="MainCtrl">
+        <h3>{{ originalText }}</h3>
+        <h3>{{ filteredText }}</h3>
+       </div>
+     </file>
+
+     <file name="script.js">
+      angular.module('filterExample', [])
+      .controller('MainCtrl', function($scope, $filter) {
+        $scope.originalText = 'hello';
+        $scope.filteredText = $filter('uppercase')($scope.originalText);
+      });
+     </file>
+   </example>
+  */
+$FilterProvider.$inject = ['$provide'];
+/** @this */
+function $FilterProvider($provide) {
+  var suffix = 'Filter';
+
+  /**
+   * @ngdoc method
+   * @name $filterProvider#register
+   * @param {string|Object} name Name of the filter function, or an object map of filters where
+   *    the keys are the filter names and the values are the filter factories.
+   *
+   *    <div class="alert alert-warning">
+   *    **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
+   *    Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
+   *    your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
+   *    (`myapp_subsection_filterx`).
+   *    </div>
+    * @param {Function} factory If the first argument was a string, a factory function for the filter to be registered.
+   * @returns {Object} Registered filter instance, or if a map of filters was provided then a map
+   *    of the registered filter instances.
+   */
+  function register(name, factory) {
+    if (isObject(name)) {
+      var filters = {};
+      forEach(name, function(filter, key) {
+        filters[key] = register(key, filter);
+      });
+      return filters;
+    } else {
+      return $provide.factory(name + suffix, factory);
+    }
+  }
+  this.register = register;
+
+  this.$get = ['$injector', function($injector) {
+    return function(name) {
+      return $injector.get(name + suffix);
+    };
+  }];
+
+  ////////////////////////////////////////
+
+  /* global
+    currencyFilter: false,
+    dateFilter: false,
+    filterFilter: false,
+    jsonFilter: false,
+    limitToFilter: false,
+    lowercaseFilter: false,
+    numberFilter: false,
+    orderByFilter: false,
+    uppercaseFilter: false
+  */
+
+  register('currency', currencyFilter);
+  register('date', dateFilter);
+  register('filter', filterFilter);
+  register('json', jsonFilter);
+  register('limitTo', limitToFilter);
+  register('lowercase', lowercaseFilter);
+  register('number', numberFilter);
+  register('orderBy', orderByFilter);
+  register('uppercase', uppercaseFilter);
+}
+
+/**
+ * @ngdoc filter
+ * @name filter
+ * @kind function
+ *
+ * @description
+ * Selects a subset of items from `array` and returns it as a new array.
+ *
+ * @param {Array} array The source array.
+ * <div class="alert alert-info">
+ *   **Note**: If the array contains objects that reference themselves, filtering is not possible.
+ * </div>
+ * @param {string|Object|function()} expression The predicate to be used for selecting items from
+ *   `array`.
+ *
+ *   Can be one of:
+ *
+ *   - `string`: The string is used for matching against the contents of the `array`. All strings or
+ *     objects with string properties in `array` that match this string will be returned. This also
+ *     applies to nested object properties.
+ *     The predicate can be negated by prefixing the string with `!`.
+ *
+ *   - `Object`: A pattern object can be used to filter specific properties on objects contained
+ *     by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items
+ *     which have property `name` containing "M" and property `phone` containing "1". A special
+ *     property name (`$` by default) can be used (e.g. as in `{$: "text"}`) to accept a match
+ *     against any property of the object or its nested object properties. That's equivalent to the
+ *     simple substring match with a `string` as described above. The special property name can be
+ *     overwritten, using the `anyPropertyKey` parameter.
+ *     The predicate can be negated by prefixing the string with `!`.
+ *     For example `{name: "!M"}` predicate will return an array of items which have property `name`
+ *     not containing "M".
+ *
+ *     Note that a named property will match properties on the same level only, while the special
+ *     `$` property will match properties on the same level or deeper. E.g. an array item like
+ *     `{name: {first: 'John', last: 'Doe'}}` will **not** be matched by `{name: 'John'}`, but
+ *     **will** be matched by `{$: 'John'}`.
+ *
+ *   - `function(value, index, array)`: A predicate function can be used to write arbitrary filters.
+ *     The function is called for each element of the array, with the element, its index, and
+ *     the entire array itself as arguments.
+ *
+ *     The final result is an array of those elements that the predicate returned true for.
+ *
+ * @param {function(actual, expected)|true|false} [comparator] Comparator which is used in
+ *     determining if the expected value (from the filter expression) and actual value (from
+ *     the object in the array) should be considered a match.
+ *
+ *   Can be one of:
+ *
+ *   - `function(actual, expected)`:
+ *     The function will be given the object value and the predicate value to compare and
+ *     should return true if both values should be considered equal.
+ *
+ *   - `true`: A shorthand for `function(actual, expected) { return angular.equals(actual, expected)}`.
+ *     This is essentially strict comparison of expected and actual.
+ *
+ *   - `false`: A short hand for a function which will look for a substring match in a case
+ *     insensitive way. Primitive values are converted to strings. Objects are not compared against
+ *     primitives, unless they have a custom `toString` method (e.g. `Date` objects).
+ *
+ *
+ *   Defaults to `false`.
+ *
+ * @param {string} [anyPropertyKey] The special property name that matches against any property.
+ *     By default `$`.
+ *
+ * @example
+   <example name="filter-filter">
+     <file name="index.html">
+       <div ng-init="friends = [{name:'John', phone:'555-1276'},
+                                {name:'Mary', phone:'800-BIG-MARY'},
+                                {name:'Mike', phone:'555-4321'},
+                                {name:'Adam', phone:'555-5678'},
+                                {name:'Julie', phone:'555-8765'},
+                                {name:'Juliette', phone:'555-5678'}]"></div>
+
+       <label>Search: <input ng-model="searchText"></label>
+       <table id="searchTextResults">
+         <tr><th>Name</th><th>Phone</th></tr>
+         <tr ng-repeat="friend in friends | filter:searchText">
+           <td>{{friend.name}}</td>
+           <td>{{friend.phone}}</td>
+         </tr>
+       </table>
+       <hr>
+       <label>Any: <input ng-model="search.$"></label> <br>
+       <label>Name only <input ng-model="search.name"></label><br>
+       <label>Phone only <input ng-model="search.phone"></label><br>
+       <label>Equality <input type="checkbox" ng-model="strict"></label><br>
+       <table id="searchObjResults">
+         <tr><th>Name</th><th>Phone</th></tr>
+         <tr ng-repeat="friendObj in friends | filter:search:strict">
+           <td>{{friendObj.name}}</td>
+           <td>{{friendObj.phone}}</td>
+         </tr>
+       </table>
+     </file>
+     <file name="protractor.js" type="protractor">
+       var expectFriendNames = function(expectedNames, key) {
+         element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
+           arr.forEach(function(wd, i) {
+             expect(wd.getText()).toMatch(expectedNames[i]);
+           });
+         });
+       };
+
+       it('should search across all fields when filtering with a string', function() {
+         var searchText = element(by.model('searchText'));
+         searchText.clear();
+         searchText.sendKeys('m');
+         expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');
+
+         searchText.clear();
+         searchText.sendKeys('76');
+         expectFriendNames(['John', 'Julie'], 'friend');
+       });
+
+       it('should search in specific fields when filtering with a predicate object', function() {
+         var searchAny = element(by.model('search.$'));
+         searchAny.clear();
+         searchAny.sendKeys('i');
+         expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
+       });
+       it('should use a equal comparison when comparator is true', function() {
+         var searchName = element(by.model('search.name'));
+         var strict = element(by.model('strict'));
+         searchName.clear();
+         searchName.sendKeys('Julie');
+         strict.click();
+         expectFriendNames(['Julie'], 'friendObj');
+       });
+     </file>
+   </example>
+ */
+
+function filterFilter() {
+  return function(array, expression, comparator, anyPropertyKey) {
+    if (!isArrayLike(array)) {
+      if (array == null) {
+        return array;
+      } else {
+        throw minErr('filter')('notarray', 'Expected array but received: {0}', array);
+      }
+    }
+
+    anyPropertyKey = anyPropertyKey || '$';
+    var expressionType = getTypeForFilter(expression);
+    var predicateFn;
+    var matchAgainstAnyProp;
+
+    switch (expressionType) {
+      case 'function':
+        predicateFn = expression;
+        break;
+      case 'boolean':
+      case 'null':
+      case 'number':
+      case 'string':
+        matchAgainstAnyProp = true;
+        // falls through
+      case 'object':
+        predicateFn = createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp);
+        break;
+      default:
+        return array;
+    }
+
+    return Array.prototype.filter.call(array, predicateFn);
+  };
+}
+
+// Helper functions for `filterFilter`
+function createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp) {
+  var shouldMatchPrimitives = isObject(expression) && (anyPropertyKey in expression);
+  var predicateFn;
+
+  if (comparator === true) {
+    comparator = equals;
+  } else if (!isFunction(comparator)) {
+    comparator = function(actual, expected) {
+      if (isUndefined(actual)) {
+        // No substring matching against `undefined`
+        return false;
+      }
+      if ((actual === null) || (expected === null)) {
+        // No substring matching against `null`; only match against `null`
+        return actual === expected;
+      }
+      if (isObject(expected) || (isObject(actual) && !hasCustomToString(actual))) {
+        // Should not compare primitives against objects, unless they have custom `toString` method
+        return false;
+      }
+
+      actual = lowercase('' + actual);
+      expected = lowercase('' + expected);
+      return actual.indexOf(expected) !== -1;
+    };
+  }
+
+  predicateFn = function(item) {
+    if (shouldMatchPrimitives && !isObject(item)) {
+      return deepCompare(item, expression[anyPropertyKey], comparator, anyPropertyKey, false);
+    }
+    return deepCompare(item, expression, comparator, anyPropertyKey, matchAgainstAnyProp);
+  };
+
+  return predicateFn;
+}
+
+function deepCompare(actual, expected, comparator, anyPropertyKey, matchAgainstAnyProp, dontMatchWholeObject) {
+  var actualType = getTypeForFilter(actual);
+  var expectedType = getTypeForFilter(expected);
+
+  if ((expectedType === 'string') && (expected.charAt(0) === '!')) {
+    return !deepCompare(actual, expected.substring(1), comparator, anyPropertyKey, matchAgainstAnyProp);
+  } else if (isArray(actual)) {
+    // In case `actual` is an array, consider it a match
+    // if ANY of it's items matches `expected`
+    return actual.some(function(item) {
+      return deepCompare(item, expected, comparator, anyPropertyKey, matchAgainstAnyProp);
+    });
+  }
+
+  switch (actualType) {
+    case 'object':
+      var key;
+      if (matchAgainstAnyProp) {
+        for (key in actual) {
+          // Under certain, rare, circumstances, key may not be a string and `charAt` will be undefined
+          // See: https://github.com/angular/angular.js/issues/15644
+          if (key.charAt && (key.charAt(0) !== '$') &&
+              deepCompare(actual[key], expected, comparator, anyPropertyKey, true)) {
+            return true;
+          }
+        }
+        return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, anyPropertyKey, false);
+      } else if (expectedType === 'object') {
+        for (key in expected) {
+          var expectedVal = expected[key];
+          if (isFunction(expectedVal) || isUndefined(expectedVal)) {
+            continue;
+          }
+
+          var matchAnyProperty = key === anyPropertyKey;
+          var actualVal = matchAnyProperty ? actual : actual[key];
+          if (!deepCompare(actualVal, expectedVal, comparator, anyPropertyKey, matchAnyProperty, matchAnyProperty)) {
+            return false;
+          }
+        }
+        return true;
+      } else {
+        return comparator(actual, expected);
+      }
+    case 'function':
+      return false;
+    default:
+      return comparator(actual, expected);
+  }
+}
+
+// Used for easily differentiating between `null` and actual `object`
+function getTypeForFilter(val) {
+  return (val === null) ? 'null' : typeof val;
+}
+
+var MAX_DIGITS = 22;
+var DECIMAL_SEP = '.';
+var ZERO_CHAR = '0';
+
+/**
+ * @ngdoc filter
+ * @name currency
+ * @kind function
+ *
+ * @description
+ * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default
+ * symbol for current locale is used.
+ *
+ * @param {number} amount Input to filter.
+ * @param {string=} symbol Currency symbol or identifier to be displayed.
+ * @param {number=} fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale
+ * @returns {string} Formatted number.
+ *
+ *
+ * @example
+   <example module="currencyExample" name="currency-filter">
+     <file name="index.html">
+       <script>
+         angular.module('currencyExample', [])
+           .controller('ExampleController', ['$scope', function($scope) {
+             $scope.amount = 1234.56;
+           }]);
+       </script>
+       <div ng-controller="ExampleController">
+         <input type="number" ng-model="amount" aria-label="amount"> <br>
+         default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
+         custom currency identifier (USD$): <span id="currency-custom">{{amount | currency:"USD$"}}</span><br>
+         no fractions (0): <span id="currency-no-fractions">{{amount | currency:"USD$":0}}</span>
+       </div>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should init with 1234.56', function() {
+         expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');
+         expect(element(by.id('currency-custom')).getText()).toBe('USD$1,234.56');
+         expect(element(by.id('currency-no-fractions')).getText()).toBe('USD$1,235');
+       });
+       it('should update', function() {
+         if (browser.params.browser === 'safari') {
+           // Safari does not understand the minus key. See
+           // https://github.com/angular/protractor/issues/481
+           return;
+         }
+         element(by.model('amount')).clear();
+         element(by.model('amount')).sendKeys('-1234');
+         expect(element(by.id('currency-default')).getText()).toBe('-$1,234.00');
+         expect(element(by.id('currency-custom')).getText()).toBe('-USD$1,234.00');
+         expect(element(by.id('currency-no-fractions')).getText()).toBe('-USD$1,234');
+       });
+     </file>
+   </example>
+ */
+currencyFilter.$inject = ['$locale'];
+function currencyFilter($locale) {
+  var formats = $locale.NUMBER_FORMATS;
+  return function(amount, currencySymbol, fractionSize) {
+    if (isUndefined(currencySymbol)) {
+      currencySymbol = formats.CURRENCY_SYM;
+    }
+
+    if (isUndefined(fractionSize)) {
+      fractionSize = formats.PATTERNS[1].maxFrac;
+    }
+
+    // if null or undefined pass it through
+    return (amount == null)
+        ? amount
+        : formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize).
+            replace(/\u00A4/g, currencySymbol);
+  };
+}
+
+/**
+ * @ngdoc filter
+ * @name number
+ * @kind function
+ *
+ * @description
+ * Formats a number as text.
+ *
+ * If the input is null or undefined, it will just be returned.
+ * If the input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or '-∞' is returned, respectively.
+ * If the input is not a number an empty string is returned.
+ *
+ *
+ * @param {number|string} number Number to format.
+ * @param {(number|string)=} fractionSize Number of decimal places to round the number to.
+ * If this is not provided then the fraction size is computed from the current locale's number
+ * formatting pattern. In the case of the default locale, it will be 3.
+ * @returns {string} Number rounded to `fractionSize` appropriately formatted based on the current
+ *                   locale (e.g., in the en_US locale it will have "." as the decimal separator and
+ *                   include "," group separators after each third digit).
+ *
+ * @example
+   <example module="numberFilterExample" name="number-filter">
+     <file name="index.html">
+       <script>
+         angular.module('numberFilterExample', [])
+           .controller('ExampleController', ['$scope', function($scope) {
+             $scope.val = 1234.56789;
+           }]);
+       </script>
+       <div ng-controller="ExampleController">
+         <label>Enter number: <input ng-model='val'></label><br>
+         Default formatting: <span id='number-default'>{{val | number}}</span><br>
+         No fractions: <span>{{val | number:0}}</span><br>
+         Negative number: <span>{{-val | number:4}}</span>
+       </div>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should format numbers', function() {
+         expect(element(by.id('number-default')).getText()).toBe('1,234.568');
+         expect(element(by.binding('val | number:0')).getText()).toBe('1,235');
+         expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679');
+       });
+
+       it('should update', function() {
+         element(by.model('val')).clear();
+         element(by.model('val')).sendKeys('3374.333');
+         expect(element(by.id('number-default')).getText()).toBe('3,374.333');
+         expect(element(by.binding('val | number:0')).getText()).toBe('3,374');
+         expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330');
+      });
+     </file>
+   </example>
+ */
+numberFilter.$inject = ['$locale'];
+function numberFilter($locale) {
+  var formats = $locale.NUMBER_FORMATS;
+  return function(number, fractionSize) {
+
+    // if null or undefined pass it through
+    return (number == null)
+        ? number
+        : formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP,
+                       fractionSize);
+  };
+}
+
+/**
+ * Parse a number (as a string) into three components that can be used
+ * for formatting the number.
+ *
+ * (Significant bits of this parse algorithm came from https://github.com/MikeMcl/big.js/)
+ *
+ * @param  {string} numStr The number to parse
+ * @return {object} An object describing this number, containing the following keys:
+ *  - d : an array of digits containing leading zeros as necessary
+ *  - i : the number of the digits in `d` that are to the left of the decimal point
+ *  - e : the exponent for numbers that would need more than `MAX_DIGITS` digits in `d`
+ *
+ */
+function parse(numStr) {
+  var exponent = 0, digits, numberOfIntegerDigits;
+  var i, j, zeros;
+
+  // Decimal point?
+  if ((numberOfIntegerDigits = numStr.indexOf(DECIMAL_SEP)) > -1) {
+    numStr = numStr.replace(DECIMAL_SEP, '');
+  }
+
+  // Exponential form?
+  if ((i = numStr.search(/e/i)) > 0) {
+    // Work out the exponent.
+    if (numberOfIntegerDigits < 0) numberOfIntegerDigits = i;
+    numberOfIntegerDigits += +numStr.slice(i + 1);
+    numStr = numStr.substring(0, i);
+  } else if (numberOfIntegerDigits < 0) {
+    // There was no decimal point or exponent so it is an integer.
+    numberOfIntegerDigits = numStr.length;
+  }
+
+  // Count the number of leading zeros.
+  for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) { /* empty */ }
+
+  if (i === (zeros = numStr.length)) {
+    // The digits are all zero.
+    digits = [0];
+    numberOfIntegerDigits = 1;
+  } else {
+    // Count the number of trailing zeros
+    zeros--;
+    while (numStr.charAt(zeros) === ZERO_CHAR) zeros--;
+
+    // Trailing zeros are insignificant so ignore them
+    numberOfIntegerDigits -= i;
+    digits = [];
+    // Convert string to array of digits without leading/trailing zeros.
+    for (j = 0; i <= zeros; i++, j++) {
+      digits[j] = +numStr.charAt(i);
+    }
+  }
+
+  // If the number overflows the maximum allowed digits then use an exponent.
+  if (numberOfIntegerDigits > MAX_DIGITS) {
+    digits = digits.splice(0, MAX_DIGITS - 1);
+    exponent = numberOfIntegerDigits - 1;
+    numberOfIntegerDigits = 1;
+  }
+
+  return { d: digits, e: exponent, i: numberOfIntegerDigits };
+}
+
+/**
+ * Round the parsed number to the specified number of decimal places
+ * This function changed the parsedNumber in-place
+ */
+function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {
+    var digits = parsedNumber.d;
+    var fractionLen = digits.length - parsedNumber.i;
+
+    // determine fractionSize if it is not specified; `+fractionSize` converts it to a number
+    fractionSize = (isUndefined(fractionSize)) ? Math.min(Math.max(minFrac, fractionLen), maxFrac) : +fractionSize;
+
+    // The index of the digit to where rounding is to occur
+    var roundAt = fractionSize + parsedNumber.i;
+    var digit = digits[roundAt];
+
+    if (roundAt > 0) {
+      // Drop fractional digits beyond `roundAt`
+      digits.splice(Math.max(parsedNumber.i, roundAt));
+
+      // Set non-fractional digits beyond `roundAt` to 0
+      for (var j = roundAt; j < digits.length; j++) {
+        digits[j] = 0;
+      }
+    } else {
+      // We rounded to zero so reset the parsedNumber
+      fractionLen = Math.max(0, fractionLen);
+      parsedNumber.i = 1;
+      digits.length = Math.max(1, roundAt = fractionSize + 1);
+      digits[0] = 0;
+      for (var i = 1; i < roundAt; i++) digits[i] = 0;
+    }
+
+    if (digit >= 5) {
+      if (roundAt - 1 < 0) {
+        for (var k = 0; k > roundAt; k--) {
+          digits.unshift(0);
+          parsedNumber.i++;
+        }
+        digits.unshift(1);
+        parsedNumber.i++;
+      } else {
+        digits[roundAt - 1]++;
+      }
+    }
+
+    // Pad out with zeros to get the required fraction length
+    for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
+
+
+    // Do any carrying, e.g. a digit was rounded up to 10
+    var carry = digits.reduceRight(function(carry, d, i, digits) {
+      d = d + carry;
+      digits[i] = d % 10;
+      return Math.floor(d / 10);
+    }, 0);
+    if (carry) {
+      digits.unshift(carry);
+      parsedNumber.i++;
+    }
+}
+
+/**
+ * Format a number into a string
+ * @param  {number} number       The number to format
+ * @param  {{
+ *           minFrac, // the minimum number of digits required in the fraction part of the number
+ *           maxFrac, // the maximum number of digits required in the fraction part of the number
+ *           gSize,   // number of digits in each group of separated digits
+ *           lgSize,  // number of digits in the last group of digits before the decimal separator
+ *           negPre,  // the string to go in front of a negative number (e.g. `-` or `(`))
+ *           posPre,  // the string to go in front of a positive number
+ *           negSuf,  // the string to go after a negative number (e.g. `)`)
+ *           posSuf   // the string to go after a positive number
+ *         }} pattern
+ * @param  {string} groupSep     The string to separate groups of number (e.g. `,`)
+ * @param  {string} decimalSep   The string to act as the decimal separator (e.g. `.`)
+ * @param  {[type]} fractionSize The size of the fractional part of the number
+ * @return {string}              The number formatted as a string
+ */
+function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
+
+  if (!(isString(number) || isNumber(number)) || isNaN(number)) return '';
+
+  var isInfinity = !isFinite(number);
+  var isZero = false;
+  var numStr = Math.abs(number) + '',
+      formattedText = '',
+      parsedNumber;
+
+  if (isInfinity) {
+    formattedText = '\u221e';
+  } else {
+    parsedNumber = parse(numStr);
+
+    roundNumber(parsedNumber, fractionSize, pattern.minFrac, pattern.maxFrac);
+
+    var digits = parsedNumber.d;
+    var integerLen = parsedNumber.i;
+    var exponent = parsedNumber.e;
+    var decimals = [];
+    isZero = digits.reduce(function(isZero, d) { return isZero && !d; }, true);
+
+    // pad zeros for small numbers
+    while (integerLen < 0) {
+      digits.unshift(0);
+      integerLen++;
+    }
+
+    // extract decimals digits
+    if (integerLen > 0) {
+      decimals = digits.splice(integerLen, digits.length);
+    } else {
+      decimals = digits;
+      digits = [0];
+    }
+
+    // format the integer digits with grouping separators
+    var groups = [];
+    if (digits.length >= pattern.lgSize) {
+      groups.unshift(digits.splice(-pattern.lgSize, digits.length).join(''));
+    }
+    while (digits.length > pattern.gSize) {
+      groups.unshift(digits.splice(-pattern.gSize, digits.length).join(''));
+    }
+    if (digits.length) {
+      groups.unshift(digits.join(''));
+    }
+    formattedText = groups.join(groupSep);
+
+    // append the decimal digits
+    if (decimals.length) {
+      formattedText += decimalSep + decimals.join('');
+    }
+
+    if (exponent) {
+      formattedText += 'e+' + exponent;
+    }
+  }
+  if (number < 0 && !isZero) {
+    return pattern.negPre + formattedText + pattern.negSuf;
+  } else {
+    return pattern.posPre + formattedText + pattern.posSuf;
+  }
+}
+
+function padNumber(num, digits, trim, negWrap) {
+  var neg = '';
+  if (num < 0 || (negWrap && num <= 0)) {
+    if (negWrap) {
+      num = -num + 1;
+    } else {
+      num = -num;
+      neg = '-';
+    }
+  }
+  num = '' + num;
+  while (num.length < digits) num = ZERO_CHAR + num;
+  if (trim) {
+    num = num.substr(num.length - digits);
+  }
+  return neg + num;
+}
+
+
+function dateGetter(name, size, offset, trim, negWrap) {
+  offset = offset || 0;
+  return function(date) {
+    var value = date['get' + name]();
+    if (offset > 0 || value > -offset) {
+      value += offset;
+    }
+    if (value === 0 && offset === -12) value = 12;
+    return padNumber(value, size, trim, negWrap);
+  };
+}
+
+function dateStrGetter(name, shortForm, standAlone) {
+  return function(date, formats) {
+    var value = date['get' + name]();
+    var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : '');
+    var get = uppercase(propPrefix + name);
+
+    return formats[get][value];
+  };
+}
+
+function timeZoneGetter(date, formats, offset) {
+  var zone = -1 * offset;
+  var paddedZone = (zone >= 0) ? '+' : '';
+
+  paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
+                padNumber(Math.abs(zone % 60), 2);
+
+  return paddedZone;
+}
+
+function getFirstThursdayOfYear(year) {
+    // 0 = index of January
+    var dayOfWeekOnFirst = (new Date(year, 0, 1)).getDay();
+    // 4 = index of Thursday (+1 to account for 1st = 5)
+    // 11 = index of *next* Thursday (+1 account for 1st = 12)
+    return new Date(year, 0, ((dayOfWeekOnFirst <= 4) ? 5 : 12) - dayOfWeekOnFirst);
+}
+
+function getThursdayThisWeek(datetime) {
+    return new Date(datetime.getFullYear(), datetime.getMonth(),
+      // 4 = index of Thursday
+      datetime.getDate() + (4 - datetime.getDay()));
+}
+
+function weekGetter(size) {
+   return function(date) {
+      var firstThurs = getFirstThursdayOfYear(date.getFullYear()),
+         thisThurs = getThursdayThisWeek(date);
+
+      var diff = +thisThurs - +firstThurs,
+         result = 1 + Math.round(diff / 6.048e8); // 6.048e8 ms per week
+
+      return padNumber(result, size);
+   };
+}
+
+function ampmGetter(date, formats) {
+  return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1];
+}
+
+function eraGetter(date, formats) {
+  return date.getFullYear() <= 0 ? formats.ERAS[0] : formats.ERAS[1];
+}
+
+function longEraGetter(date, formats) {
+  return date.getFullYear() <= 0 ? formats.ERANAMES[0] : formats.ERANAMES[1];
+}
+
+var DATE_FORMATS = {
+  yyyy: dateGetter('FullYear', 4, 0, false, true),
+    yy: dateGetter('FullYear', 2, 0, true, true),
+     y: dateGetter('FullYear', 1, 0, false, true),
+  MMMM: dateStrGetter('Month'),
+   MMM: dateStrGetter('Month', true),
+    MM: dateGetter('Month', 2, 1),
+     M: dateGetter('Month', 1, 1),
+  LLLL: dateStrGetter('Month', false, true),
+    dd: dateGetter('Date', 2),
+     d: dateGetter('Date', 1),
+    HH: dateGetter('Hours', 2),
+     H: dateGetter('Hours', 1),
+    hh: dateGetter('Hours', 2, -12),
+     h: dateGetter('Hours', 1, -12),
+    mm: dateGetter('Minutes', 2),
+     m: dateGetter('Minutes', 1),
+    ss: dateGetter('Seconds', 2),
+     s: dateGetter('Seconds', 1),
+     // while ISO 8601 requires fractions to be prefixed with `.` or `,`
+     // we can be just safely rely on using `sss` since we currently don't support single or two digit fractions
+   sss: dateGetter('Milliseconds', 3),
+  EEEE: dateStrGetter('Day'),
+   EEE: dateStrGetter('Day', true),
+     a: ampmGetter,
+     Z: timeZoneGetter,
+    ww: weekGetter(2),
+     w: weekGetter(1),
+     G: eraGetter,
+     GG: eraGetter,
+     GGG: eraGetter,
+     GGGG: longEraGetter
+};
+
+var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
+    NUMBER_STRING = /^-?\d+$/;
+
+/**
+ * @ngdoc filter
+ * @name date
+ * @kind function
+ *
+ * @description
+ *   Formats `date` to a string based on the requested `format`.
+ *
+ *   `format` string can be composed of the following elements:
+ *
+ *   * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010)
+ *   * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10)
+ *   * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199)
+ *   * `'MMMM'`: Month in year (January-December)
+ *   * `'MMM'`: Month in year (Jan-Dec)
+ *   * `'MM'`: Month in year, padded (01-12)
+ *   * `'M'`: Month in year (1-12)
+ *   * `'LLLL'`: Stand-alone month in year (January-December)
+ *   * `'dd'`: Day in month, padded (01-31)
+ *   * `'d'`: Day in month (1-31)
+ *   * `'EEEE'`: Day in Week,(Sunday-Saturday)
+ *   * `'EEE'`: Day in Week, (Sun-Sat)
+ *   * `'HH'`: Hour in day, padded (00-23)
+ *   * `'H'`: Hour in day (0-23)
+ *   * `'hh'`: Hour in AM/PM, padded (01-12)
+ *   * `'h'`: Hour in AM/PM, (1-12)
+ *   * `'mm'`: Minute in hour, padded (00-59)
+ *   * `'m'`: Minute in hour (0-59)
+ *   * `'ss'`: Second in minute, padded (00-59)
+ *   * `'s'`: Second in minute (0-59)
+ *   * `'sss'`: Millisecond in second, padded (000-999)
+ *   * `'a'`: AM/PM marker
+ *   * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)
+ *   * `'ww'`: Week of year, padded (00-53). Week 01 is the week with the first Thursday of the year
+ *   * `'w'`: Week of year (0-53). Week 1 is the week with the first Thursday of the year
+ *   * `'G'`, `'GG'`, `'GGG'`: The abbreviated form of the era string (e.g. 'AD')
+ *   * `'GGGG'`: The long form of the era string (e.g. 'Anno Domini')
+ *
+ *   `format` string can also be one of the following predefined
+ *   {@link guide/i18n localizable formats}:
+ *
+ *   * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale
+ *     (e.g. Sep 3, 2010 12:05:08 PM)
+ *   * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US  locale (e.g. 9/3/10 12:05 PM)
+ *   * `'fullDate'`: equivalent to `'EEEE, MMMM d, y'` for en_US  locale
+ *     (e.g. Friday, September 3, 2010)
+ *   * `'longDate'`: equivalent to `'MMMM d, y'` for en_US  locale (e.g. September 3, 2010)
+ *   * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US  locale (e.g. Sep 3, 2010)
+ *   * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)
+ *   * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 PM)
+ *   * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 PM)
+ *
+ *   `format` string can contain literal values. These need to be escaped by surrounding with single quotes (e.g.
+ *   `"h 'in the morning'"`). In order to output a single quote, escape it - i.e., two single quotes in a sequence
+ *   (e.g. `"h 'o''clock'"`).
+ *
+ * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
+ *    number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its
+ *    shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
+ *    specified in the string input, the time is considered to be in the local timezone.
+ * @param {string=} format Formatting rules (see Description). If not specified,
+ *    `mediumDate` is used.
+ * @param {string=} timezone Timezone to be used for formatting. It understands UTC/GMT and the
+ *    continental US time zone abbreviations, but for general use, use a time zone offset, for
+ *    example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)
+ *    If not specified, the timezone of the browser will be used.
+ * @returns {string} Formatted string or the input if input is not recognized as date/millis.
+ *
+ * @example
+   <example name="filter-date">
+     <file name="index.html">
+       <span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:
+           <span>{{1288323623006 | date:'medium'}}</span><br>
+       <span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:
+          <span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>
+       <span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:
+          <span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>
+       <span ng-non-bindable>{{1288323623006 | date:"MM/dd/yyyy 'at' h:mma"}}</span>:
+          <span>{{'1288323623006' | date:"MM/dd/yyyy 'at' h:mma"}}</span><br>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should format date', function() {
+         expect(element(by.binding("1288323623006 | date:'medium'")).getText()).
+            toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
+         expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()).
+            toMatch(/2010-10-2\d \d{2}:\d{2}:\d{2} (-|\+)?\d{4}/);
+         expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()).
+            toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
+         expect(element(by.binding("'1288323623006' | date:\"MM/dd/yyyy 'at' h:mma\"")).getText()).
+            toMatch(/10\/2\d\/2010 at \d{1,2}:\d{2}(AM|PM)/);
+       });
+     </file>
+   </example>
+ */
+dateFilter.$inject = ['$locale'];
+function dateFilter($locale) {
+
+
+  var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
+                     // 1        2       3         4          5          6          7          8  9     10      11
+  function jsonStringToDate(string) {
+    var match;
+    if ((match = string.match(R_ISO8601_STR))) {
+      var date = new Date(0),
+          tzHour = 0,
+          tzMin  = 0,
+          dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,
+          timeSetter = match[8] ? date.setUTCHours : date.setHours;
+
+      if (match[9]) {
+        tzHour = toInt(match[9] + match[10]);
+        tzMin = toInt(match[9] + match[11]);
+      }
+      dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));
+      var h = toInt(match[4] || 0) - tzHour;
+      var m = toInt(match[5] || 0) - tzMin;
+      var s = toInt(match[6] || 0);
+      var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);
+      timeSetter.call(date, h, m, s, ms);
+      return date;
+    }
+    return string;
+  }
+
+
+  return function(date, format, timezone) {
+    var text = '',
+        parts = [],
+        fn, match;
+
+    format = format || 'mediumDate';
+    format = $locale.DATETIME_FORMATS[format] || format;
+    if (isString(date)) {
+      date = NUMBER_STRING.test(date) ? toInt(date) : jsonStringToDate(date);
+    }
+
+    if (isNumber(date)) {
+      date = new Date(date);
+    }
+
+    if (!isDate(date) || !isFinite(date.getTime())) {
+      return date;
+    }
+
+    while (format) {
+      match = DATE_FORMATS_SPLIT.exec(format);
+      if (match) {
+        parts = concat(parts, match, 1);
+        format = parts.pop();
+      } else {
+        parts.push(format);
+        format = null;
+      }
+    }
+
+    var dateTimezoneOffset = date.getTimezoneOffset();
+    if (timezone) {
+      dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
+      date = convertTimezoneToLocal(date, timezone, true);
+    }
+    forEach(parts, function(value) {
+      fn = DATE_FORMATS[value];
+      text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset)
+                 : value === '\'\'' ? '\'' : value.replace(/(^'|'$)/g, '').replace(/''/g, '\'');
+    });
+
+    return text;
+  };
+}
+
+
+/**
+ * @ngdoc filter
+ * @name json
+ * @kind function
+ *
+ * @description
+ *   Allows you to convert a JavaScript object into JSON string.
+ *
+ *   This filter is mostly useful for debugging. When using the double curly {{value}} notation
+ *   the binding is automatically converted to JSON.
+ *
+ * @param {*} object Any JavaScript object (including arrays and primitive types) to filter.
+ * @param {number=} spacing The number of spaces to use per indentation, defaults to 2.
+ * @returns {string} JSON string.
+ *
+ *
+ * @example
+   <example name="filter-json">
+     <file name="index.html">
+       <pre id="default-spacing">{{ {'name':'value'} | json }}</pre>
+       <pre id="custom-spacing">{{ {'name':'value'} | json:4 }}</pre>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should jsonify filtered objects', function() {
+         expect(element(by.id('default-spacing')).getText()).toMatch(/\{\n {2}"name": ?"value"\n}/);
+         expect(element(by.id('custom-spacing')).getText()).toMatch(/\{\n {4}"name": ?"value"\n}/);
+       });
+     </file>
+   </example>
+ *
+ */
+function jsonFilter() {
+  return function(object, spacing) {
+    if (isUndefined(spacing)) {
+        spacing = 2;
+    }
+    return toJson(object, spacing);
+  };
+}
+
+
+/**
+ * @ngdoc filter
+ * @name lowercase
+ * @kind function
+ * @description
+ * Converts string to lowercase.
+ * @see angular.lowercase
+ */
+var lowercaseFilter = valueFn(lowercase);
+
+
+/**
+ * @ngdoc filter
+ * @name uppercase
+ * @kind function
+ * @description
+ * Converts string to uppercase.
+ * @see angular.uppercase
+ */
+var uppercaseFilter = valueFn(uppercase);
+
+/**
+ * @ngdoc filter
+ * @name limitTo
+ * @kind function
+ *
+ * @description
+ * Creates a new array or string containing only a specified number of elements. The elements are
+ * taken from either the beginning or the end of the source array, string or number, as specified by
+ * the value and sign (positive or negative) of `limit`. Other array-like objects are also supported
+ * (e.g. array subclasses, NodeLists, jqLite/jQuery collections etc). If a number is used as input,
+ * it is converted to a string.
+ *
+ * @param {Array|ArrayLike|string|number} input - Array/array-like, string or number to be limited.
+ * @param {string|number} limit - The length of the returned array or string. If the `limit` number
+ *     is positive, `limit` number of items from the beginning of the source array/string are copied.
+ *     If the number is negative, `limit` number  of items from the end of the source array/string
+ *     are copied. The `limit` will be trimmed if it exceeds `array.length`. If `limit` is undefined,
+ *     the input will be returned unchanged.
+ * @param {(string|number)=} begin - Index at which to begin limitation. As a negative index,
+ *     `begin` indicates an offset from the end of `input`. Defaults to `0`.
+ * @returns {Array|string} A new sub-array or substring of length `limit` or less if the input had
+ *     less than `limit` elements.
+ *
+ * @example
+   <example module="limitToExample" name="limit-to-filter">
+     <file name="index.html">
+       <script>
+         angular.module('limitToExample', [])
+           .controller('ExampleController', ['$scope', function($scope) {
+             $scope.numbers = [1,2,3,4,5,6,7,8,9];
+             $scope.letters = "abcdefghi";
+             $scope.longNumber = 2345432342;
+             $scope.numLimit = 3;
+             $scope.letterLimit = 3;
+             $scope.longNumberLimit = 3;
+           }]);
+       </script>
+       <div ng-controller="ExampleController">
+         <label>
+            Limit {{numbers}} to:
+            <input type="number" step="1" ng-model="numLimit">
+         </label>
+         <p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
+         <label>
+            Limit {{letters}} to:
+            <input type="number" step="1" ng-model="letterLimit">
+         </label>
+         <p>Output letters: {{ letters | limitTo:letterLimit }}</p>
+         <label>
+            Limit {{longNumber}} to:
+            <input type="number" step="1" ng-model="longNumberLimit">
+         </label>
+         <p>Output long number: {{ longNumber | limitTo:longNumberLimit }}</p>
+       </div>
+     </file>
+     <file name="protractor.js" type="protractor">
+       var numLimitInput = element(by.model('numLimit'));
+       var letterLimitInput = element(by.model('letterLimit'));
+       var longNumberLimitInput = element(by.model('longNumberLimit'));
+       var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));
+       var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));
+       var limitedLongNumber = element(by.binding('longNumber | limitTo:longNumberLimit'));
+
+       it('should limit the number array to first three items', function() {
+         expect(numLimitInput.getAttribute('value')).toBe('3');
+         expect(letterLimitInput.getAttribute('value')).toBe('3');
+         expect(longNumberLimitInput.getAttribute('value')).toBe('3');
+         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');
+         expect(limitedLetters.getText()).toEqual('Output letters: abc');
+         expect(limitedLongNumber.getText()).toEqual('Output long number: 234');
+       });
+
+       // There is a bug in safari and protractor that doesn't like the minus key
+       // it('should update the output when -3 is entered', function() {
+       //   numLimitInput.clear();
+       //   numLimitInput.sendKeys('-3');
+       //   letterLimitInput.clear();
+       //   letterLimitInput.sendKeys('-3');
+       //   longNumberLimitInput.clear();
+       //   longNumberLimitInput.sendKeys('-3');
+       //   expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
+       //   expect(limitedLetters.getText()).toEqual('Output letters: ghi');
+       //   expect(limitedLongNumber.getText()).toEqual('Output long number: 342');
+       // });
+
+       it('should not exceed the maximum size of input array', function() {
+         numLimitInput.clear();
+         numLimitInput.sendKeys('100');
+         letterLimitInput.clear();
+         letterLimitInput.sendKeys('100');
+         longNumberLimitInput.clear();
+         longNumberLimitInput.sendKeys('100');
+         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
+         expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');
+         expect(limitedLongNumber.getText()).toEqual('Output long number: 2345432342');
+       });
+     </file>
+   </example>
+*/
+function limitToFilter() {
+  return function(input, limit, begin) {
+    if (Math.abs(Number(limit)) === Infinity) {
+      limit = Number(limit);
+    } else {
+      limit = toInt(limit);
+    }
+    if (isNumberNaN(limit)) return input;
+
+    if (isNumber(input)) input = input.toString();
+    if (!isArrayLike(input)) return input;
+
+    begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);
+    begin = (begin < 0) ? Math.max(0, input.length + begin) : begin;
+
+    if (limit >= 0) {
+      return sliceFn(input, begin, begin + limit);
+    } else {
+      if (begin === 0) {
+        return sliceFn(input, limit, input.length);
+      } else {
+        return sliceFn(input, Math.max(0, begin + limit), begin);
+      }
+    }
+  };
+}
+
+function sliceFn(input, begin, end) {
+  if (isString(input)) return input.slice(begin, end);
+
+  return slice.call(input, begin, end);
+}
+
+/**
+ * @ngdoc filter
+ * @name orderBy
+ * @kind function
+ *
+ * @description
+ * Returns an array containing the items from the specified `collection`, ordered by a `comparator`
+ * function based on the values computed using the `expression` predicate.
+ *
+ * For example, `[{id: 'foo'}, {id: 'bar'}] | orderBy:'id'` would result in
+ * `[{id: 'bar'}, {id: 'foo'}]`.
+ *
+ * The `collection` can be an Array or array-like object (e.g. NodeList, jQuery object, TypedArray,
+ * String, etc).
+ *
+ * The `expression` can be a single predicate, or a list of predicates each serving as a tie-breaker
+ * for the preceding one. The `expression` is evaluated against each item and the output is used
+ * for comparing with other items.
+ *
+ * You can change the sorting order by setting `reverse` to `true`. By default, items are sorted in
+ * ascending order.
+ *
+ * The comparison is done using the `comparator` function. If none is specified, a default, built-in
+ * comparator is used (see below for details - in a nutshell, it compares numbers numerically and
+ * strings alphabetically).
+ *
+ * ### Under the hood
+ *
+ * Ordering the specified `collection` happens in two phases:
+ *
+ * 1. All items are passed through the predicate (or predicates), and the returned values are saved
+ *    along with their type (`string`, `number` etc). For example, an item `{label: 'foo'}`, passed
+ *    through a predicate that extracts the value of the `label` property, would be transformed to:
+ *    ```
+ *    {
+ *      value: 'foo',
+ *      type: 'string',
+ *      index: ...
+ *    }
+ *    ```
+ * 2. The comparator function is used to sort the items, based on the derived values, types and
+ *    indices.
+ *
+ * If you use a custom comparator, it will be called with pairs of objects of the form
+ * `{value: ..., type: '...', index: ...}` and is expected to return `0` if the objects are equal
+ * (as far as the comparator is concerned), `-1` if the 1st one should be ranked higher than the
+ * second, or `1` otherwise.
+ *
+ * In order to ensure that the sorting will be deterministic across platforms, if none of the
+ * specified predicates can distinguish between two items, `orderBy` will automatically introduce a
+ * dummy predicate that returns the item's index as `value`.
+ * (If you are using a custom comparator, make sure it can handle this predicate as well.)
+ *
+ * Finally, in an attempt to simplify things, if a predicate returns an object as the extracted
+ * value for an item, `orderBy` will try to convert that object to a primitive value, before passing
+ * it to the comparator. The following rules govern the conversion:
+ *
+ * 1. If the object has a `valueOf()` method that returns a primitive, its return value will be
+ *    used instead.<br />
+ *    (If the object has a `valueOf()` method that returns another object, then the returned object
+ *    will be used in subsequent steps.)
+ * 2. If the object has a custom `toString()` method (i.e. not the one inherited from `Object`) that
+ *    returns a primitive, its return value will be used instead.<br />
+ *    (If the object has a `toString()` method that returns another object, then the returned object
+ *    will be used in subsequent steps.)
+ * 3. No conversion; the object itself is used.
+ *
+ * ### The default comparator
+ *
+ * The default, built-in comparator should be sufficient for most usecases. In short, it compares
+ * numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to
+ * using their index in the original collection, and sorts values of different types by type.
+ *
+ * More specifically, it follows these steps to determine the relative order of items:
+ *
+ * 1. If the compared values are of different types, compare the types themselves alphabetically.
+ * 2. If both values are of type `string`, compare them alphabetically in a case- and
+ *    locale-insensitive way.
+ * 3. If both values are objects, compare their indices instead.
+ * 4. Otherwise, return:
+ *    -  `0`, if the values are equal (by strict equality comparison, i.e. using `===`).
+ *    - `-1`, if the 1st value is "less than" the 2nd value (compared using the `<` operator).
+ *    -  `1`, otherwise.
+ *
+ * **Note:** If you notice numbers not being sorted as expected, make sure they are actually being
+ *           saved as numbers and not strings.
+ * **Note:** For the purpose of sorting, `null` values are treated as the string `'null'` (i.e.
+ *           `type: 'string'`, `value: 'null'`). This may cause unexpected sort order relative to
+ *           other values.
+ *
+ * @param {Array|ArrayLike} collection - The collection (array or array-like object) to sort.
+ * @param {(Function|string|Array.<Function|string>)=} expression - A predicate (or list of
+ *    predicates) to be used by the comparator to determine the order of elements.
+ *
+ *    Can be one of:
+ *
+ *    - `Function`: A getter function. This function will be called with each item as argument and
+ *      the return value will be used for sorting.
+ *    - `string`: An Angular expression. This expression will be evaluated against each item and the
+ *      result will be used for sorting. For example, use `'label'` to sort by a property called
+ *      `label` or `'label.substring(0, 3)'` to sort by the first 3 characters of the `label`
+ *      property.<br />
+ *      (The result of a constant expression is interpreted as a property name to be used for
+ *      comparison. For example, use `'"special name"'` (note the extra pair of quotes) to sort by a
+ *      property called `special name`.)<br />
+ *      An expression can be optionally prefixed with `+` or `-` to control the sorting direction,
+ *      ascending or descending. For example, `'+label'` or `'-label'`. If no property is provided,
+ *      (e.g. `'+'` or `'-'`), the collection element itself is used in comparisons.
+ *    - `Array`: An array of function and/or string predicates. If a predicate cannot determine the
+ *      relative order of two items, the next predicate is used as a tie-breaker.
+ *
+ * **Note:** If the predicate is missing or empty then it defaults to `'+'`.
+ *
+ * @param {boolean=} reverse - If `true`, reverse the sorting order.
+ * @param {(Function)=} comparator - The comparator function used to determine the relative order of
+ *    value pairs. If omitted, the built-in comparator will be used.
+ *
+ * @returns {Array} - The sorted array.
+ *
+ *
+ * @example
+ * ### Ordering a table with `ngRepeat`
+ *
+ * The example below demonstrates a simple {@link ngRepeat ngRepeat}, where the data is sorted by
+ * age in descending order (expression is set to `'-age'`). The `comparator` is not set, which means
+ * it defaults to the built-in comparator.
+ *
+   <example name="orderBy-static" module="orderByExample1">
+     <file name="index.html">
+       <div ng-controller="ExampleController">
+         <table class="friends">
+           <tr>
+             <th>Name</th>
+             <th>Phone Number</th>
+             <th>Age</th>
+           </tr>
+           <tr ng-repeat="friend in friends | orderBy:'-age'">
+             <td>{{friend.name}}</td>
+             <td>{{friend.phone}}</td>
+             <td>{{friend.age}}</td>
+           </tr>
+         </table>
+       </div>
+     </file>
+     <file name="script.js">
+       angular.module('orderByExample1', [])
+         .controller('ExampleController', ['$scope', function($scope) {
+           $scope.friends = [
+             {name: 'John',   phone: '555-1212',  age: 10},
+             {name: 'Mary',   phone: '555-9876',  age: 19},
+             {name: 'Mike',   phone: '555-4321',  age: 21},
+             {name: 'Adam',   phone: '555-5678',  age: 35},
+             {name: 'Julie',  phone: '555-8765',  age: 29}
+           ];
+         }]);
+     </file>
+     <file name="style.css">
+       .friends {
+         border-collapse: collapse;
+       }
+
+       .friends th {
+         border-bottom: 1px solid;
+       }
+       .friends td, .friends th {
+         border-left: 1px solid;
+         padding: 5px 10px;
+       }
+       .friends td:first-child, .friends th:first-child {
+         border-left: none;
+       }
+     </file>
+     <file name="protractor.js" type="protractor">
+       // Element locators
+       var names = element.all(by.repeater('friends').column('friend.name'));
+
+       it('should sort friends by age in reverse order', function() {
+         expect(names.get(0).getText()).toBe('Adam');
+         expect(names.get(1).getText()).toBe('Julie');
+         expect(names.get(2).getText()).toBe('Mike');
+         expect(names.get(3).getText()).toBe('Mary');
+         expect(names.get(4).getText()).toBe('John');
+       });
+     </file>
+   </example>
+ * <hr />
+ *
+ * @example
+ * ### Changing parameters dynamically
+ *
+ * All parameters can be changed dynamically. The next example shows how you can make the columns of
+ * a table sortable, by binding the `expression` and `reverse` parameters to scope properties.
+ *
+   <example name="orderBy-dynamic" module="orderByExample2">
+     <file name="index.html">
+       <div ng-controller="ExampleController">
+         <pre>Sort by = {{propertyName}}; reverse = {{reverse}}</pre>
+         <hr/>
+         <button ng-click="propertyName = null; reverse = false">Set to unsorted</button>
+         <hr/>
+         <table class="friends">
+           <tr>
+             <th>
+               <button ng-click="sortBy('name')">Name</button>
+               <span class="sortorder" ng-show="propertyName === 'name'" ng-class="{reverse: reverse}"></span>
+             </th>
+             <th>
+               <button ng-click="sortBy('phone')">Phone Number</button>
+               <span class="sortorder" ng-show="propertyName === 'phone'" ng-class="{reverse: reverse}"></span>
+             </th>
+             <th>
+               <button ng-click="sortBy('age')">Age</button>
+               <span class="sortorder" ng-show="propertyName === 'age'" ng-class="{reverse: reverse}"></span>
+             </th>
+           </tr>
+           <tr ng-repeat="friend in friends | orderBy:propertyName:reverse">
+             <td>{{friend.name}}</td>
+             <td>{{friend.phone}}</td>
+             <td>{{friend.age}}</td>
+           </tr>
+         </table>
+       </div>
+     </file>
+     <file name="script.js">
+       angular.module('orderByExample2', [])
+         .controller('ExampleController', ['$scope', function($scope) {
+           var friends = [
+             {name: 'John',   phone: '555-1212',  age: 10},
+             {name: 'Mary',   phone: '555-9876',  age: 19},
+             {name: 'Mike',   phone: '555-4321',  age: 21},
+             {name: 'Adam',   phone: '555-5678',  age: 35},
+             {name: 'Julie',  phone: '555-8765',  age: 29}
+           ];
+
+           $scope.propertyName = 'age';
+           $scope.reverse = true;
+           $scope.friends = friends;
+
+           $scope.sortBy = function(propertyName) {
+             $scope.reverse = ($scope.propertyName === propertyName) ? !$scope.reverse : false;
+             $scope.propertyName = propertyName;
+           };
+         }]);
+     </file>
+     <file name="style.css">
+       .friends {
+         border-collapse: collapse;
+       }
+
+       .friends th {
+         border-bottom: 1px solid;
+       }
+       .friends td, .friends th {
+         border-left: 1px solid;
+         padding: 5px 10px;
+       }
+       .friends td:first-child, .friends th:first-child {
+         border-left: none;
+       }
+
+       .sortorder:after {
+         content: '\25b2';   // BLACK UP-POINTING TRIANGLE
+       }
+       .sortorder.reverse:after {
+         content: '\25bc';   // BLACK DOWN-POINTING TRIANGLE
+       }
+     </file>
+     <file name="protractor.js" type="protractor">
+       // Element locators
+       var unsortButton = element(by.partialButtonText('unsorted'));
+       var nameHeader = element(by.partialButtonText('Name'));
+       var phoneHeader = element(by.partialButtonText('Phone'));
+       var ageHeader = element(by.partialButtonText('Age'));
+       var firstName = element(by.repeater('friends').column('friend.name').row(0));
+       var lastName = element(by.repeater('friends').column('friend.name').row(4));
+
+       it('should sort friends by some property, when clicking on the column header', function() {
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('John');
+
+         phoneHeader.click();
+         expect(firstName.getText()).toBe('John');
+         expect(lastName.getText()).toBe('Mary');
+
+         nameHeader.click();
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('Mike');
+
+         ageHeader.click();
+         expect(firstName.getText()).toBe('John');
+         expect(lastName.getText()).toBe('Adam');
+       });
+
+       it('should sort friends in reverse order, when clicking on the same column', function() {
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('John');
+
+         ageHeader.click();
+         expect(firstName.getText()).toBe('John');
+         expect(lastName.getText()).toBe('Adam');
+
+         ageHeader.click();
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('John');
+       });
+
+       it('should restore the original order, when clicking "Set to unsorted"', function() {
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('John');
+
+         unsortButton.click();
+         expect(firstName.getText()).toBe('John');
+         expect(lastName.getText()).toBe('Julie');
+       });
+     </file>
+   </example>
+ * <hr />
+ *
+ * @example
+ * ### Using `orderBy` inside a controller
+ *
+ * It is also possible to call the `orderBy` filter manually, by injecting `orderByFilter`, and
+ * calling it with the desired parameters. (Alternatively, you could inject the `$filter` factory
+ * and retrieve the `orderBy` filter with `$filter('orderBy')`.)
+ *
+   <example name="orderBy-call-manually" module="orderByExample3">
+     <file name="index.html">
+       <div ng-controller="ExampleController">
+         <pre>Sort by = {{propertyName}}; reverse = {{reverse}}</pre>
+         <hr/>
+         <button ng-click="sortBy(null)">Set to unsorted</button>
+         <hr/>
+         <table class="friends">
+           <tr>
+             <th>
+               <button ng-click="sortBy('name')">Name</button>
+               <span class="sortorder" ng-show="propertyName === 'name'" ng-class="{reverse: reverse}"></span>
+             </th>
+             <th>
+               <button ng-click="sortBy('phone')">Phone Number</button>
+               <span class="sortorder" ng-show="propertyName === 'phone'" ng-class="{reverse: reverse}"></span>
+             </th>
+             <th>
+               <button ng-click="sortBy('age')">Age</button>
+               <span class="sortorder" ng-show="propertyName === 'age'" ng-class="{reverse: reverse}"></span>
+             </th>
+           </tr>
+           <tr ng-repeat="friend in friends">
+             <td>{{friend.name}}</td>
+             <td>{{friend.phone}}</td>
+             <td>{{friend.age}}</td>
+           </tr>
+         </table>
+       </div>
+     </file>
+     <file name="script.js">
+       angular.module('orderByExample3', [])
+         .controller('ExampleController', ['$scope', 'orderByFilter', function($scope, orderBy) {
+           var friends = [
+             {name: 'John',   phone: '555-1212',  age: 10},
+             {name: 'Mary',   phone: '555-9876',  age: 19},
+             {name: 'Mike',   phone: '555-4321',  age: 21},
+             {name: 'Adam',   phone: '555-5678',  age: 35},
+             {name: 'Julie',  phone: '555-8765',  age: 29}
+           ];
+
+           $scope.propertyName = 'age';
+           $scope.reverse = true;
+           $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse);
+
+           $scope.sortBy = function(propertyName) {
+             $scope.reverse = (propertyName !== null && $scope.propertyName === propertyName)
+                 ? !$scope.reverse : false;
+             $scope.propertyName = propertyName;
+             $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse);
+           };
+         }]);
+     </file>
+     <file name="style.css">
+       .friends {
+         border-collapse: collapse;
+       }
+
+       .friends th {
+         border-bottom: 1px solid;
+       }
+       .friends td, .friends th {
+         border-left: 1px solid;
+         padding: 5px 10px;
+       }
+       .friends td:first-child, .friends th:first-child {
+         border-left: none;
+       }
+
+       .sortorder:after {
+         content: '\25b2';   // BLACK UP-POINTING TRIANGLE
+       }
+       .sortorder.reverse:after {
+         content: '\25bc';   // BLACK DOWN-POINTING TRIANGLE
+       }
+     </file>
+     <file name="protractor.js" type="protractor">
+       // Element locators
+       var unsortButton = element(by.partialButtonText('unsorted'));
+       var nameHeader = element(by.partialButtonText('Name'));
+       var phoneHeader = element(by.partialButtonText('Phone'));
+       var ageHeader = element(by.partialButtonText('Age'));
+       var firstName = element(by.repeater('friends').column('friend.name').row(0));
+       var lastName = element(by.repeater('friends').column('friend.name').row(4));
+
+       it('should sort friends by some property, when clicking on the column header', function() {
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('John');
+
+         phoneHeader.click();
+         expect(firstName.getText()).toBe('John');
+         expect(lastName.getText()).toBe('Mary');
+
+         nameHeader.click();
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('Mike');
+
+         ageHeader.click();
+         expect(firstName.getText()).toBe('John');
+         expect(lastName.getText()).toBe('Adam');
+       });
+
+       it('should sort friends in reverse order, when clicking on the same column', function() {
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('John');
+
+         ageHeader.click();
+         expect(firstName.getText()).toBe('John');
+         expect(lastName.getText()).toBe('Adam');
+
+         ageHeader.click();
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('John');
+       });
+
+       it('should restore the original order, when clicking "Set to unsorted"', function() {
+         expect(firstName.getText()).toBe('Adam');
+         expect(lastName.getText()).toBe('John');
+
+         unsortButton.click();
+         expect(firstName.getText()).toBe('John');
+         expect(lastName.getText()).toBe('Julie');
+       });
+     </file>
+   </example>
+ * <hr />
+ *
+ * @example
+ * ### Using a custom comparator
+ *
+ * If you have very specific requirements about the way items are sorted, you can pass your own
+ * comparator function. For example, you might need to compare some strings in a locale-sensitive
+ * way. (When specifying a custom comparator, you also need to pass a value for the `reverse`
+ * argument - passing `false` retains the default sorting order, i.e. ascending.)
+ *
+   <example name="orderBy-custom-comparator" module="orderByExample4">
+     <file name="index.html">
+       <div ng-controller="ExampleController">
+         <div class="friends-container custom-comparator">
+           <h3>Locale-sensitive Comparator</h3>
+           <table class="friends">
+             <tr>
+               <th>Name</th>
+               <th>Favorite Letter</th>
+             </tr>
+             <tr ng-repeat="friend in friends | orderBy:'favoriteLetter':false:localeSensitiveComparator">
+               <td>{{friend.name}}</td>
+               <td>{{friend.favoriteLetter}}</td>
+             </tr>
+           </table>
+         </div>
+         <div class="friends-container default-comparator">
+           <h3>Default Comparator</h3>
+           <table class="friends">
+             <tr>
+               <th>Name</th>
+               <th>Favorite Letter</th>
+             </tr>
+             <tr ng-repeat="friend in friends | orderBy:'favoriteLetter'">
+               <td>{{friend.name}}</td>
+               <td>{{friend.favoriteLetter}}</td>
+             </tr>
+           </table>
+         </div>
+       </div>
+     </file>
+     <file name="script.js">
+       angular.module('orderByExample4', [])
+         .controller('ExampleController', ['$scope', function($scope) {
+           $scope.friends = [
+             {name: 'John',   favoriteLetter: 'Ä'},
+             {name: 'Mary',   favoriteLetter: 'Ü'},
+             {name: 'Mike',   favoriteLetter: 'Ö'},
+             {name: 'Adam',   favoriteLetter: 'H'},
+             {name: 'Julie',  favoriteLetter: 'Z'}
+           ];
+
+           $scope.localeSensitiveComparator = function(v1, v2) {
+             // If we don't get strings, just compare by index
+             if (v1.type !== 'string' || v2.type !== 'string') {
+               return (v1.index < v2.index) ? -1 : 1;
+             }
+
+             // Compare strings alphabetically, taking locale into account
+             return v1.value.localeCompare(v2.value);
+           };
+         }]);
+     </file>
+     <file name="style.css">
+       .friends-container {
+         display: inline-block;
+         margin: 0 30px;
+       }
+
+       .friends {
+         border-collapse: collapse;
+       }
+
+       .friends th {
+         border-bottom: 1px solid;
+       }
+       .friends td, .friends th {
+         border-left: 1px solid;
+         padding: 5px 10px;
+       }
+       .friends td:first-child, .friends th:first-child {
+         border-left: none;
+       }
+     </file>
+     <file name="protractor.js" type="protractor">
+       // Element locators
+       var container = element(by.css('.custom-comparator'));
+       var names = container.all(by.repeater('friends').column('friend.name'));
+
+       it('should sort friends by favorite letter (in correct alphabetical order)', function() {
+         expect(names.get(0).getText()).toBe('John');
+         expect(names.get(1).getText()).toBe('Adam');
+         expect(names.get(2).getText()).toBe('Mike');
+         expect(names.get(3).getText()).toBe('Mary');
+         expect(names.get(4).getText()).toBe('Julie');
+       });
+     </file>
+   </example>
+ *
+ */
+orderByFilter.$inject = ['$parse'];
+function orderByFilter($parse) {
+  return function(array, sortPredicate, reverseOrder, compareFn) {
+
+    if (array == null) return array;
+    if (!isArrayLike(array)) {
+      throw minErr('orderBy')('notarray', 'Expected array but received: {0}', array);
+    }
+
+    if (!isArray(sortPredicate)) { sortPredicate = [sortPredicate]; }
+    if (sortPredicate.length === 0) { sortPredicate = ['+']; }
+
+    var predicates = processPredicates(sortPredicate);
+
+    var descending = reverseOrder ? -1 : 1;
+
+    // Define the `compare()` function. Use a default comparator if none is specified.
+    var compare = isFunction(compareFn) ? compareFn : defaultCompare;
+
+    // The next three lines are a version of a Swartzian Transform idiom from Perl
+    // (sometimes called the Decorate-Sort-Undecorate idiom)
+    // See https://en.wikipedia.org/wiki/Schwartzian_transform
+    var compareValues = Array.prototype.map.call(array, getComparisonObject);
+    compareValues.sort(doComparison);
+    array = compareValues.map(function(item) { return item.value; });
+
+    return array;
+
+    function getComparisonObject(value, index) {
+      // NOTE: We are adding an extra `tieBreaker` value based on the element's index.
+      // This will be used to keep the sort stable when none of the input predicates can
+      // distinguish between two elements.
+      return {
+        value: value,
+        tieBreaker: {value: index, type: 'number', index: index},
+        predicateValues: predicates.map(function(predicate) {
+          return getPredicateValue(predicate.get(value), index);
+        })
+      };
+    }
+
+    function doComparison(v1, v2) {
+      for (var i = 0, ii = predicates.length; i < ii; i++) {
+        var result = compare(v1.predicateValues[i], v2.predicateValues[i]);
+        if (result) {
+          return result * predicates[i].descending * descending;
+        }
+      }
+
+      return compare(v1.tieBreaker, v2.tieBreaker) * descending;
+    }
+  };
+
+  function processPredicates(sortPredicates) {
+    return sortPredicates.map(function(predicate) {
+      var descending = 1, get = identity;
+
+      if (isFunction(predicate)) {
+        get = predicate;
+      } else if (isString(predicate)) {
+        if ((predicate.charAt(0) === '+' || predicate.charAt(0) === '-')) {
+          descending = predicate.charAt(0) === '-' ? -1 : 1;
+          predicate = predicate.substring(1);
+        }
+        if (predicate !== '') {
+          get = $parse(predicate);
+          if (get.constant) {
+            var key = get();
+            get = function(value) { return value[key]; };
+          }
+        }
+      }
+      return {get: get, descending: descending};
+    });
+  }
+
+  function isPrimitive(value) {
+    switch (typeof value) {
+      case 'number': /* falls through */
+      case 'boolean': /* falls through */
+      case 'string':
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  function objectValue(value) {
+    // If `valueOf` is a valid function use that
+    if (isFunction(value.valueOf)) {
+      value = value.valueOf();
+      if (isPrimitive(value)) return value;
+    }
+    // If `toString` is a valid function and not the one from `Object.prototype` use that
+    if (hasCustomToString(value)) {
+      value = value.toString();
+      if (isPrimitive(value)) return value;
+    }
+
+    return value;
+  }
+
+  function getPredicateValue(value, index) {
+    var type = typeof value;
+    if (value === null) {
+      type = 'string';
+      value = 'null';
+    } else if (type === 'object') {
+      value = objectValue(value);
+    }
+    return {value: value, type: type, index: index};
+  }
+
+  function defaultCompare(v1, v2) {
+    var result = 0;
+    var type1 = v1.type;
+    var type2 = v2.type;
+
+    if (type1 === type2) {
+      var value1 = v1.value;
+      var value2 = v2.value;
+
+      if (type1 === 'string') {
+        // Compare strings case-insensitively
+        value1 = value1.toLowerCase();
+        value2 = value2.toLowerCase();
+      } else if (type1 === 'object') {
+        // For basic objects, use the position of the object
+        // in the collection instead of the value
+        if (isObject(value1)) value1 = v1.index;
+        if (isObject(value2)) value2 = v2.index;
+      }
+
+      if (value1 !== value2) {
+        result = value1 < value2 ? -1 : 1;
+      }
+    } else {
+      result = type1 < type2 ? -1 : 1;
+    }
+
+    return result;
+  }
+}
+
+function ngDirective(directive) {
+  if (isFunction(directive)) {
+    directive = {
+      link: directive
+    };
+  }
+  directive.restrict = directive.restrict || 'AC';
+  return valueFn(directive);
+}
+
+/**
+ * @ngdoc directive
+ * @name a
+ * @restrict E
+ *
+ * @description
+ * Modifies the default behavior of the html a tag so that the default action is prevented when
+ * the href attribute is empty.
+ *
+ * For dynamically creating `href` attributes for a tags, see the {@link ng.ngHref `ngHref`} directive.
+ */
+var htmlAnchorDirective = valueFn({
+  restrict: 'E',
+  compile: function(element, attr) {
+    if (!attr.href && !attr.xlinkHref) {
+      return function(scope, element) {
+        // If the linked element is not an anchor tag anymore, do nothing
+        if (element[0].nodeName.toLowerCase() !== 'a') return;
+
+        // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
+        var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
+                   'xlink:href' : 'href';
+        element.on('click', function(event) {
+          // if we have no href url, then don't navigate anywhere.
+          if (!element.attr(href)) {
+            event.preventDefault();
+          }
+        });
+      };
+    }
+  }
+});
+
+/**
+ * @ngdoc directive
+ * @name ngHref
+ * @restrict A
+ * @priority 99
+ *
+ * @description
+ * Using Angular markup like `{{hash}}` in an href attribute will
+ * make the link go to the wrong URL if the user clicks it before
+ * Angular has a chance to replace the `{{hash}}` markup with its
+ * value. Until Angular replaces the markup the link will be broken
+ * and will most likely return a 404 error. The `ngHref` directive
+ * solves this problem.
+ *
+ * The wrong way to write it:
+ * ```html
+ * <a href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
+ * ```
+ *
+ * The correct way to write it:
+ * ```html
+ * <a ng-href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
+ * ```
+ *
+ * @element A
+ * @param {template} ngHref any string which can contain `{{}}` markup.
+ *
+ * @example
+ * This example shows various combinations of `href`, `ng-href` and `ng-click` attributes
+ * in links and their different behaviors:
+    <example name="ng-href">
+      <file name="index.html">
+        <input ng-model="value" /><br />
+        <a id="link-1" href ng-click="value = 1">link 1</a> (link, don't reload)<br />
+        <a id="link-2" href="" ng-click="value = 2">link 2</a> (link, don't reload)<br />
+        <a id="link-3" ng-href="/{{'123'}}">link 3</a> (link, reload!)<br />
+        <a id="link-4" href="" name="xx" ng-click="value = 4">anchor</a> (link, don't reload)<br />
+        <a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br />
+        <a id="link-6" ng-href="{{value}}">link</a> (link, change location)
+      </file>
+      <file name="protractor.js" type="protractor">
+        it('should execute ng-click but not reload when href without value', function() {
+          element(by.id('link-1')).click();
+          expect(element(by.model('value')).getAttribute('value')).toEqual('1');
+          expect(element(by.id('link-1')).getAttribute('href')).toBe('');
+        });
+
+        it('should execute ng-click but not reload when href empty string', function() {
+          element(by.id('link-2')).click();
+          expect(element(by.model('value')).getAttribute('value')).toEqual('2');
+          expect(element(by.id('link-2')).getAttribute('href')).toBe('');
+        });
+
+        it('should execute ng-click and change url when ng-href specified', function() {
+          expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\/123$/);
+
+          element(by.id('link-3')).click();
+
+          // At this point, we navigate away from an Angular page, so we need
+          // to use browser.driver to get the base webdriver.
+
+          browser.wait(function() {
+            return browser.driver.getCurrentUrl().then(function(url) {
+              return url.match(/\/123$/);
+            });
+          }, 5000, 'page should navigate to /123');
+        });
+
+        it('should execute ng-click but not reload when href empty string and name specified', function() {
+          element(by.id('link-4')).click();
+          expect(element(by.model('value')).getAttribute('value')).toEqual('4');
+          expect(element(by.id('link-4')).getAttribute('href')).toBe('');
+        });
+
+        it('should execute ng-click but not reload when no href but name specified', function() {
+          element(by.id('link-5')).click();
+          expect(element(by.model('value')).getAttribute('value')).toEqual('5');
+          expect(element(by.id('link-5')).getAttribute('href')).toBe(null);
+        });
+
+        it('should only change url when only ng-href', function() {
+          element(by.model('value')).clear();
+          element(by.model('value')).sendKeys('6');
+          expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\/6$/);
+
+          element(by.id('link-6')).click();
+
+          // At this point, we navigate away from an Angular page, so we need
+          // to use browser.driver to get the base webdriver.
+          browser.wait(function() {
+            return browser.driver.getCurrentUrl().then(function(url) {
+              return url.match(/\/6$/);
+            });
+          }, 5000, 'page should navigate to /6');
+        });
+      </file>
+    </example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngSrc
+ * @restrict A
+ * @priority 99
+ *
+ * @description
+ * Using Angular markup like `{{hash}}` in a `src` attribute doesn't
+ * work right: The browser will fetch from the URL with the literal
+ * text `{{hash}}` until Angular replaces the expression inside
+ * `{{hash}}`. The `ngSrc` directive solves this problem.
+ *
+ * The buggy way to write it:
+ * ```html
+ * <img src="http://www.gravatar.com/avatar/{{hash}}" alt="Description"/>
+ * ```
+ *
+ * The correct way to write it:
+ * ```html
+ * <img ng-src="http://www.gravatar.com/avatar/{{hash}}" alt="Description" />
+ * ```
+ *
+ * @element IMG
+ * @param {template} ngSrc any string which can contain `{{}}` markup.
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngSrcset
+ * @restrict A
+ * @priority 99
+ *
+ * @description
+ * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't
+ * work right: The browser will fetch from the URL with the literal
+ * text `{{hash}}` until Angular replaces the expression inside
+ * `{{hash}}`. The `ngSrcset` directive solves this problem.
+ *
+ * The buggy way to write it:
+ * ```html
+ * <img srcset="http://www.gravatar.com/avatar/{{hash}} 2x" alt="Description"/>
+ * ```
+ *
+ * The correct way to write it:
+ * ```html
+ * <img ng-srcset="http://www.gravatar.com/avatar/{{hash}} 2x" alt="Description" />
+ * ```
+ *
+ * @element IMG
+ * @param {template} ngSrcset any string which can contain `{{}}` markup.
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngDisabled
+ * @restrict A
+ * @priority 100
+ *
+ * @description
+ *
+ * This directive sets the `disabled` attribute on the element (typically a form control,
+ * e.g. `input`, `button`, `select` etc.) if the
+ * {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.
+ *
+ * A special directive is necessary because we cannot use interpolation inside the `disabled`
+ * attribute. See the {@link guide/interpolation interpolation guide} for more info.
+ *
+ * @example
+    <example name="ng-disabled">
+      <file name="index.html">
+        <label>Click me to toggle: <input type="checkbox" ng-model="checked"></label><br/>
+        <button ng-model="button" ng-disabled="checked">Button</button>
+      </file>
+      <file name="protractor.js" type="protractor">
+        it('should toggle button', function() {
+          expect(element(by.css('button')).getAttribute('disabled')).toBeFalsy();
+          element(by.model('checked')).click();
+          expect(element(by.css('button')).getAttribute('disabled')).toBeTruthy();
+        });
+      </file>
+    </example>
+ *
+ * @element INPUT
+ * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy,
+ *     then the `disabled` attribute will be set on the element
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngChecked
+ * @restrict A
+ * @priority 100
+ *
+ * @description
+ * Sets the `checked` attribute on the element, if the expression inside `ngChecked` is truthy.
+ *
+ * Note that this directive should not be used together with {@link ngModel `ngModel`},
+ * as this can lead to unexpected behavior.
+ *
+ * A special directive is necessary because we cannot use interpolation inside the `checked`
+ * attribute. See the {@link guide/interpolation interpolation guide} for more info.
+ *
+ * @example
+    <example name="ng-checked">
+      <file name="index.html">
+        <label>Check me to check both: <input type="checkbox" ng-model="master"></label><br/>
+        <input id="checkSlave" type="checkbox" ng-checked="master" aria-label="Slave input">
+      </file>
+      <file name="protractor.js" type="protractor">
+        it('should check both checkBoxes', function() {
+          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy();
+          element(by.model('master')).click();
+          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy();
+        });
+      </file>
+    </example>
+ *
+ * @element INPUT
+ * @param {expression} ngChecked If the {@link guide/expression expression} is truthy,
+ *     then the `checked` attribute will be set on the element
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngReadonly
+ * @restrict A
+ * @priority 100
+ *
+ * @description
+ *
+ * Sets the `readonly` attribute on the element, if the expression inside `ngReadonly` is truthy.
+ * Note that `readonly` applies only to `input` elements with specific types. [See the input docs on
+ * MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-readonly) for more information.
+ *
+ * A special directive is necessary because we cannot use interpolation inside the `readonly`
+ * attribute. See the {@link guide/interpolation interpolation guide} for more info.
+ *
+ * @example
+    <example name="ng-readonly">
+      <file name="index.html">
+        <label>Check me to make text readonly: <input type="checkbox" ng-model="checked"></label><br/>
+        <input type="text" ng-readonly="checked" value="I'm Angular" aria-label="Readonly field" />
+      </file>
+      <file name="protractor.js" type="protractor">
+        it('should toggle readonly attr', function() {
+          expect(element(by.css('[type="text"]')).getAttribute('readonly')).toBeFalsy();
+          element(by.model('checked')).click();
+          expect(element(by.css('[type="text"]')).getAttribute('readonly')).toBeTruthy();
+        });
+      </file>
+    </example>
+ *
+ * @element INPUT
+ * @param {expression} ngReadonly If the {@link guide/expression expression} is truthy,
+ *     then special attribute "readonly" will be set on the element
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngSelected
+ * @restrict A
+ * @priority 100
+ *
+ * @description
+ *
+ * Sets the `selected` attribute on the element, if the expression inside `ngSelected` is truthy.
+ *
+ * A special directive is necessary because we cannot use interpolation inside the `selected`
+ * attribute. See the {@link guide/interpolation interpolation guide} for more info.
+ *
+ * <div class="alert alert-warning">
+ *   **Note:** `ngSelected` does not interact with the `select` and `ngModel` directives, it only
+ *   sets the `selected` attribute on the element. If you are using `ngModel` on the select, you
+ *   should not use `ngSelected` on the options, as `ngModel` will set the select value and
+ *   selected options.
+ * </div>
+ *
+ * @example
+    <example name="ng-selected">
+      <file name="index.html">
+        <label>Check me to select: <input type="checkbox" ng-model="selected"></label><br/>
+        <select aria-label="ngSelected demo">
+          <option>Hello!</option>
+          <option id="greet" ng-selected="selected">Greetings!</option>
+        </select>
+      </file>
+      <file name="protractor.js" type="protractor">
+        it('should select Greetings!', function() {
+          expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy();
+          element(by.model('selected')).click();
+          expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy();
+        });
+      </file>
+    </example>
+ *
+ * @element OPTION
+ * @param {expression} ngSelected If the {@link guide/expression expression} is truthy,
+ *     then special attribute "selected" will be set on the element
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngOpen
+ * @restrict A
+ * @priority 100
+ *
+ * @description
+ *
+ * Sets the `open` attribute on the element, if the expression inside `ngOpen` is truthy.
+ *
+ * A special directive is necessary because we cannot use interpolation inside the `open`
+ * attribute. See the {@link guide/interpolation interpolation guide} for more info.
+ *
+ * ## A note about browser compatibility
+ *
+ * Edge, Firefox, and Internet Explorer do not support the `details` element, it is
+ * recommended to use {@link ng.ngShow} and {@link ng.ngHide} instead.
+ *
+ * @example
+     <example name="ng-open">
+       <file name="index.html">
+         <label>Check me check multiple: <input type="checkbox" ng-model="open"></label><br/>
+         <details id="details" ng-open="open">
+            <summary>Show/Hide me</summary>
+         </details>
+       </file>
+       <file name="protractor.js" type="protractor">
+         it('should toggle open', function() {
+           expect(element(by.id('details')).getAttribute('open')).toBeFalsy();
+           element(by.model('open')).click();
+           expect(element(by.id('details')).getAttribute('open')).toBeTruthy();
+         });
+       </file>
+     </example>
+ *
+ * @element DETAILS
+ * @param {expression} ngOpen If the {@link guide/expression expression} is truthy,
+ *     then special attribute "open" will be set on the element
+ */
+
+var ngAttributeAliasDirectives = {};
+
+// boolean attrs are evaluated
+forEach(BOOLEAN_ATTR, function(propName, attrName) {
+  // binding to multiple is not supported
+  if (propName === 'multiple') return;
+
+  function defaultLinkFn(scope, element, attr) {
+    scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
+      attr.$set(attrName, !!value);
+    });
+  }
+
+  var normalized = directiveNormalize('ng-' + attrName);
+  var linkFn = defaultLinkFn;
+
+  if (propName === 'checked') {
+    linkFn = function(scope, element, attr) {
+      // ensuring ngChecked doesn't interfere with ngModel when both are set on the same input
+      if (attr.ngModel !== attr[normalized]) {
+        defaultLinkFn(scope, element, attr);
+      }
+    };
+  }
+
+  ngAttributeAliasDirectives[normalized] = function() {
+    return {
+      restrict: 'A',
+      priority: 100,
+      link: linkFn
+    };
+  };
+});
+
+// aliased input attrs are evaluated
+forEach(ALIASED_ATTR, function(htmlAttr, ngAttr) {
+  ngAttributeAliasDirectives[ngAttr] = function() {
+    return {
+      priority: 100,
+      link: function(scope, element, attr) {
+        //special case ngPattern when a literal regular expression value
+        //is used as the expression (this way we don't have to watch anything).
+        if (ngAttr === 'ngPattern' && attr.ngPattern.charAt(0) === '/') {
+          var match = attr.ngPattern.match(REGEX_STRING_REGEXP);
+          if (match) {
+            attr.$set('ngPattern', new RegExp(match[1], match[2]));
+            return;
+          }
+        }
+
+        scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) {
+          attr.$set(ngAttr, value);
+        });
+      }
+    };
+  };
+});
+
+// ng-src, ng-srcset, ng-href are interpolated
+forEach(['src', 'srcset', 'href'], function(attrName) {
+  var normalized = directiveNormalize('ng-' + attrName);
+  ngAttributeAliasDirectives[normalized] = function() {
+    return {
+      priority: 99, // it needs to run after the attributes are interpolated
+      link: function(scope, element, attr) {
+        var propName = attrName,
+            name = attrName;
+
+        if (attrName === 'href' &&
+            toString.call(element.prop('href')) === '[object SVGAnimatedString]') {
+          name = 'xlinkHref';
+          attr.$attr[name] = 'xlink:href';
+          propName = null;
+        }
+
+        attr.$observe(normalized, function(value) {
+          if (!value) {
+            if (attrName === 'href') {
+              attr.$set(name, null);
+            }
+            return;
+          }
+
+          attr.$set(name, value);
+
+          // Support: IE 9-11 only
+          // On IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
+          // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
+          // to set the property as well to achieve the desired effect.
+          // We use attr[attrName] value since $set can sanitize the url.
+          if (msie && propName) element.prop(propName, attr[name]);
+        });
+      }
+    };
+  };
+});
+
+/* global -nullFormCtrl, -PENDING_CLASS, -SUBMITTED_CLASS
+ */
+var nullFormCtrl = {
+  $addControl: noop,
+  $$renameControl: nullFormRenameControl,
+  $removeControl: noop,
+  $setValidity: noop,
+  $setDirty: noop,
+  $setPristine: noop,
+  $setSubmitted: noop
+},
+PENDING_CLASS = 'ng-pending',
+SUBMITTED_CLASS = 'ng-submitted';
+
+function nullFormRenameControl(control, name) {
+  control.$name = name;
+}
+
+/**
+ * @ngdoc type
+ * @name form.FormController
+ *
+ * @property {boolean} $pristine True if user has not interacted with the form yet.
+ * @property {boolean} $dirty True if user has already interacted with the form.
+ * @property {boolean} $valid True if all of the containing forms and controls are valid.
+ * @property {boolean} $invalid True if at least one containing control or form is invalid.
+ * @property {boolean} $pending True if at least one containing control or form is pending.
+ * @property {boolean} $submitted True if user has submitted the form even if its invalid.
+ *
+ * @property {Object} $error Is an object hash, containing references to controls or
+ *  forms with failing validators, where:
+ *
+ *  - keys are validation tokens (error names),
+ *  - values are arrays of controls or forms that have a failing validator for given error name.
+ *
+ *  Built-in validation tokens:
+ *
+ *  - `email`
+ *  - `max`
+ *  - `maxlength`
+ *  - `min`
+ *  - `minlength`
+ *  - `number`
+ *  - `pattern`
+ *  - `required`
+ *  - `url`
+ *  - `date`
+ *  - `datetimelocal`
+ *  - `time`
+ *  - `week`
+ *  - `month`
+ *
+ * @description
+ * `FormController` keeps track of all its controls and nested forms as well as the state of them,
+ * such as being valid/invalid or dirty/pristine.
+ *
+ * Each {@link ng.directive:form form} directive creates an instance
+ * of `FormController`.
+ *
+ */
+//asks for $scope to fool the BC controller module
+FormController.$inject = ['$element', '$attrs', '$scope', '$animate', '$interpolate'];
+function FormController($element, $attrs, $scope, $animate, $interpolate) {
+  this.$$controls = [];
+
+  // init state
+  this.$error = {};
+  this.$$success = {};
+  this.$pending = undefined;
+  this.$name = $interpolate($attrs.name || $attrs.ngForm || '')($scope);
+  this.$dirty = false;
+  this.$pristine = true;
+  this.$valid = true;
+  this.$invalid = false;
+  this.$submitted = false;
+  this.$$parentForm = nullFormCtrl;
+
+  this.$$element = $element;
+  this.$$animate = $animate;
+
+  setupValidity(this);
+}
+
+FormController.prototype = {
+  /**
+   * @ngdoc method
+   * @name form.FormController#$rollbackViewValue
+   *
+   * @description
+   * Rollback all form controls pending updates to the `$modelValue`.
+   *
+   * Updates may be pending by a debounced event or because the input is waiting for a some future
+   * event defined in `ng-model-options`. This method is typically needed by the reset button of
+   * a form that uses `ng-model-options` to pend updates.
+   */
+  $rollbackViewValue: function() {
+    forEach(this.$$controls, function(control) {
+      control.$rollbackViewValue();
+    });
+  },
+
+  /**
+   * @ngdoc method
+   * @name form.FormController#$commitViewValue
+   *
+   * @description
+   * Commit all form controls pending updates to the `$modelValue`.
+   *
+   * Updates may be pending by a debounced event or because the input is waiting for a some future
+   * event defined in `ng-model-options`. This method is rarely needed as `NgModelController`
+   * usually handles calling this in response to input events.
+   */
+  $commitViewValue: function() {
+    forEach(this.$$controls, function(control) {
+      control.$commitViewValue();
+    });
+  },
+
+  /**
+   * @ngdoc method
+   * @name form.FormController#$addControl
+   * @param {object} control control object, either a {@link form.FormController} or an
+   * {@link ngModel.NgModelController}
+   *
+   * @description
+   * Register a control with the form. Input elements using ngModelController do this automatically
+   * when they are linked.
+   *
+   * Note that the current state of the control will not be reflected on the new parent form. This
+   * is not an issue with normal use, as freshly compiled and linked controls are in a `$pristine`
+   * state.
+   *
+   * However, if the method is used programmatically, for example by adding dynamically created controls,
+   * or controls that have been previously removed without destroying their corresponding DOM element,
+   * it's the developers responsibility to make sure the current state propagates to the parent form.
+   *
+   * For example, if an input control is added that is already `$dirty` and has `$error` properties,
+   * calling `$setDirty()` and `$validate()` afterwards will propagate the state to the parent form.
+   */
+  $addControl: function(control) {
+    // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored
+    // and not added to the scope.  Now we throw an error.
+    assertNotHasOwnProperty(control.$name, 'input');
+    this.$$controls.push(control);
+
+    if (control.$name) {
+      this[control.$name] = control;
+    }
+
+    control.$$parentForm = this;
+  },
+
+  // Private API: rename a form control
+  $$renameControl: function(control, newName) {
+    var oldName = control.$name;
+
+    if (this[oldName] === control) {
+      delete this[oldName];
+    }
+    this[newName] = control;
+    control.$name = newName;
+  },
+
+  /**
+   * @ngdoc method
+   * @name form.FormController#$removeControl
+   * @param {object} control control object, either a {@link form.FormController} or an
+   * {@link ngModel.NgModelController}
+   *
+   * @description
+   * Deregister a control from the form.
+   *
+   * Input elements using ngModelController do this automatically when they are destroyed.
+   *
+   * Note that only the removed control's validation state (`$errors`etc.) will be removed from the
+   * form. `$dirty`, `$submitted` states will not be changed, because the expected behavior can be
+   * different from case to case. For example, removing the only `$dirty` control from a form may or
+   * may not mean that the form is still `$dirty`.
+   */
+  $removeControl: function(control) {
+    if (control.$name && this[control.$name] === control) {
+      delete this[control.$name];
+    }
+    forEach(this.$pending, function(value, name) {
+      // eslint-disable-next-line no-invalid-this
+      this.$setValidity(name, null, control);
+    }, this);
+    forEach(this.$error, function(value, name) {
+      // eslint-disable-next-line no-invalid-this
+      this.$setValidity(name, null, control);
+    }, this);
+    forEach(this.$$success, function(value, name) {
+      // eslint-disable-next-line no-invalid-this
+      this.$setValidity(name, null, control);
+    }, this);
+
+    arrayRemove(this.$$controls, control);
+    control.$$parentForm = nullFormCtrl;
+  },
+
+  /**
+   * @ngdoc method
+   * @name form.FormController#$setDirty
+   *
+   * @description
+   * Sets the form to a dirty state.
+   *
+   * This method can be called to add the 'ng-dirty' class and set the form to a dirty
+   * state (ng-dirty class). This method will also propagate to parent forms.
+   */
+  $setDirty: function() {
+    this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);
+    this.$$animate.addClass(this.$$element, DIRTY_CLASS);
+    this.$dirty = true;
+    this.$pristine = false;
+    this.$$parentForm.$setDirty();
+  },
+
+  /**
+   * @ngdoc method
+   * @name form.FormController#$setPristine
+   *
+   * @description
+   * Sets the form to its pristine state.
+   *
+   * This method sets the form's `$pristine` state to true, the `$dirty` state to false, removes
+   * the `ng-dirty` class and adds the `ng-pristine` class. Additionally, it sets the `$submitted`
+   * state to false.
+   *
+   * This method will also propagate to all the controls contained in this form.
+   *
+   * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
+   * saving or resetting it.
+   */
+  $setPristine: function() {
+    this.$$animate.setClass(this.$$element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);
+    this.$dirty = false;
+    this.$pristine = true;
+    this.$submitted = false;
+    forEach(this.$$controls, function(control) {
+      control.$setPristine();
+    });
+  },
+
+  /**
+   * @ngdoc method
+   * @name form.FormController#$setUntouched
+   *
+   * @description
+   * Sets the form to its untouched state.
+   *
+   * This method can be called to remove the 'ng-touched' class and set the form controls to their
+   * untouched state (ng-untouched class).
+   *
+   * Setting a form controls back to their untouched state is often useful when setting the form
+   * back to its pristine state.
+   */
+  $setUntouched: function() {
+    forEach(this.$$controls, function(control) {
+      control.$setUntouched();
+    });
+  },
+
+  /**
+   * @ngdoc method
+   * @name form.FormController#$setSubmitted
+   *
+   * @description
+   * Sets the form to its submitted state.
+   */
+  $setSubmitted: function() {
+    this.$$animate.addClass(this.$$element, SUBMITTED_CLASS);
+    this.$submitted = true;
+    this.$$parentForm.$setSubmitted();
+  }
+};
+
+/**
+ * @ngdoc method
+ * @name form.FormController#$setValidity
+ *
+ * @description
+ * Sets the validity of a form control.
+ *
+ * This method will also propagate to parent forms.
+ */
+addSetValidityMethod({
+  clazz: FormController,
+  set: function(object, property, controller) {
+    var list = object[property];
+    if (!list) {
+      object[property] = [controller];
+    } else {
+      var index = list.indexOf(controller);
+      if (index === -1) {
+        list.push(controller);
+      }
+    }
+  },
+  unset: function(object, property, controller) {
+    var list = object[property];
+    if (!list) {
+      return;
+    }
+    arrayRemove(list, controller);
+    if (list.length === 0) {
+      delete object[property];
+    }
+  }
+});
+
+/**
+ * @ngdoc directive
+ * @name ngForm
+ * @restrict EAC
+ *
+ * @description
+ * Nestable alias of {@link ng.directive:form `form`} directive. HTML
+ * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a
+ * sub-group of controls needs to be determined.
+ *
+ * Note: the purpose of `ngForm` is to group controls,
+ * but not to be a replacement for the `<form>` tag with all of its capabilities
+ * (e.g. posting to the server, ...).
+ *
+ * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into
+ *                       related scope, under this name.
+ *
+ */
+
+ /**
+ * @ngdoc directive
+ * @name form
+ * @restrict E
+ *
+ * @description
+ * Directive that instantiates
+ * {@link form.FormController FormController}.
+ *
+ * If the `name` attribute is specified, the form controller is published onto the current scope under
+ * this name.
+ *
+ * # Alias: {@link ng.directive:ngForm `ngForm`}
+ *
+ * In Angular, forms can be nested. This means that the outer form is valid when all of the child
+ * forms are valid as well. However, browsers do not allow nesting of `<form>` elements, so
+ * Angular provides the {@link ng.directive:ngForm `ngForm`} directive, which behaves identically to
+ * `form` but can be nested. Nested forms can be useful, for example, if the validity of a sub-group
+ * of controls needs to be determined.
+ *
+ * # CSS classes
+ *  - `ng-valid` is set if the form is valid.
+ *  - `ng-invalid` is set if the form is invalid.
+ *  - `ng-pending` is set if the form is pending.
+ *  - `ng-pristine` is set if the form is pristine.
+ *  - `ng-dirty` is set if the form is dirty.
+ *  - `ng-submitted` is set if the form was submitted.
+ *
+ * Keep in mind that ngAnimate can detect each of these classes when added and removed.
+ *
+ *
+ * # Submitting a form and preventing the default action
+ *
+ * Since the role of forms in client-side Angular applications is different than in classical
+ * roundtrip apps, it is desirable for the browser not to translate the form submission into a full
+ * page reload that sends the data to the server. Instead some javascript logic should be triggered
+ * to handle the form submission in an application-specific way.
+ *
+ * For this reason, Angular prevents the default action (form submission to the server) unless the
+ * `<form>` element has an `action` attribute specified.
+ *
+ * You can use one of the following two ways to specify what javascript method should be called when
+ * a form is submitted:
+ *
+ * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element
+ * - {@link ng.directive:ngClick ngClick} directive on the first
+  *  button or input field of type submit (input[type=submit])
+ *
+ * To prevent double execution of the handler, use only one of the {@link ng.directive:ngSubmit ngSubmit}
+ * or {@link ng.directive:ngClick ngClick} directives.
+ * This is because of the following form submission rules in the HTML specification:
+ *
+ * - If a form has only one input field then hitting enter in this field triggers form submit
+ * (`ngSubmit`)
+ * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter
+ * doesn't trigger submit
+ * - if a form has one or more input fields and one or more buttons or input[type=submit] then
+ * hitting enter in any of the input fields will trigger the click handler on the *first* button or
+ * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`)
+ *
+ * Any pending `ngModelOptions` changes will take place immediately when an enclosing form is
+ * submitted. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`
+ * to have access to the updated model.
+ *
+ * ## Animation Hooks
+ *
+ * Animations in ngForm are triggered when any of the associated CSS classes are added and removed.
+ * These classes are: `.ng-pristine`, `.ng-dirty`, `.ng-invalid` and `.ng-valid` as well as any
+ * other validations that are performed within the form. Animations in ngForm are similar to how
+ * they work in ngClass and animations can be hooked into using CSS transitions, keyframes as well
+ * as JS animations.
+ *
+ * The following example shows a simple way to utilize CSS transitions to style a form element
+ * that has been rendered as invalid after it has been validated:
+ *
+ * <pre>
+ * //be sure to include ngAnimate as a module to hook into more
+ * //advanced animations
+ * .my-form {
+ *   transition:0.5s linear all;
+ *   background: white;
+ * }
+ * .my-form.ng-invalid {
+ *   background: red;
+ *   color:white;
+ * }
+ * </pre>
+ *
+ * @example
+    <example name="ng-form" deps="angular-animate.js" animations="true" fixBase="true" module="formExample">
+      <file name="index.html">
+       <script>
+         angular.module('formExample', [])
+           .controller('FormController', ['$scope', function($scope) {
+             $scope.userType = 'guest';
+           }]);
+       </script>
+       <style>
+        .my-form {
+          transition:all linear 0.5s;
+          background: transparent;
+        }
+        .my-form.ng-invalid {
+          background: red;
+        }
+       </style>
+       <form name="myForm" ng-controller="FormController" class="my-form">
+         userType: <input name="input" ng-model="userType" required>
+         <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
+         <code>userType = {{userType}}</code><br>
+         <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br>
+         <code>myForm.input.$error = {{myForm.input.$error}}</code><br>
+         <code>myForm.$valid = {{myForm.$valid}}</code><br>
+         <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br>
+        </form>
+      </file>
+      <file name="protractor.js" type="protractor">
+        it('should initialize to model', function() {
+          var userType = element(by.binding('userType'));
+          var valid = element(by.binding('myForm.input.$valid'));
+
+          expect(userType.getText()).toContain('guest');
+          expect(valid.getText()).toContain('true');
+        });
+
+        it('should be invalid if empty', function() {
+          var userType = element(by.binding('userType'));
+          var valid = element(by.binding('myForm.input.$valid'));
+          var userInput = element(by.model('userType'));
+
+          userInput.clear();
+          userInput.sendKeys('');
+
+          expect(userType.getText()).toEqual('userType =');
+          expect(valid.getText()).toContain('false');
+        });
+      </file>
+    </example>
+ *
+ * @param {string=} name Name of the form. If specified, the form controller will be published into
+ *                       related scope, under this name.
+ */
+var formDirectiveFactory = function(isNgForm) {
+  return ['$timeout', '$parse', function($timeout, $parse) {
+    var formDirective = {
+      name: 'form',
+      restrict: isNgForm ? 'EAC' : 'E',
+      require: ['form', '^^?form'], //first is the form's own ctrl, second is an optional parent form
+      controller: FormController,
+      compile: function ngFormCompile(formElement, attr) {
+        // Setup initial state of the control
+        formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS);
+
+        var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false);
+
+        return {
+          pre: function ngFormPreLink(scope, formElement, attr, ctrls) {
+            var controller = ctrls[0];
+
+            // if `action` attr is not present on the form, prevent the default action (submission)
+            if (!('action' in attr)) {
+              // we can't use jq events because if a form is destroyed during submission the default
+              // action is not prevented. see #1238
+              //
+              // IE 9 is not affected because it doesn't fire a submit event and try to do a full
+              // page reload if the form was destroyed by submission of the form via a click handler
+              // on a button in the form. Looks like an IE9 specific bug.
+              var handleFormSubmission = function(event) {
+                scope.$apply(function() {
+                  controller.$commitViewValue();
+                  controller.$setSubmitted();
+                });
+
+                event.preventDefault();
+              };
+
+              formElement[0].addEventListener('submit', handleFormSubmission);
+
+              // unregister the preventDefault listener so that we don't not leak memory but in a
+              // way that will achieve the prevention of the default action.
+              formElement.on('$destroy', function() {
+                $timeout(function() {
+                  formElement[0].removeEventListener('submit', handleFormSubmission);
+                }, 0, false);
+              });
+            }
+
+            var parentFormCtrl = ctrls[1] || controller.$$parentForm;
+            parentFormCtrl.$addControl(controller);
+
+            var setter = nameAttr ? getSetter(controller.$name) : noop;
+
+            if (nameAttr) {
+              setter(scope, controller);
+              attr.$observe(nameAttr, function(newValue) {
+                if (controller.$name === newValue) return;
+                setter(scope, undefined);
+                controller.$$parentForm.$$renameControl(controller, newValue);
+                setter = getSetter(controller.$name);
+                setter(scope, controller);
+              });
+            }
+            formElement.on('$destroy', function() {
+              controller.$$parentForm.$removeControl(controller);
+              setter(scope, undefined);
+              extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
+            });
+          }
+        };
+      }
+    };
+
+    return formDirective;
+
+    function getSetter(expression) {
+      if (expression === '') {
+        //create an assignable expression, so forms with an empty name can be renamed later
+        return $parse('this[""]').assign;
+      }
+      return $parse(expression).assign || noop;
+    }
+  }];
+};
+
+var formDirective = formDirectiveFactory();
+var ngFormDirective = formDirectiveFactory(true);
+
+
+
+// helper methods
+function setupValidity(instance) {
+  instance.$$classCache = {};
+  instance.$$classCache[INVALID_CLASS] = !(instance.$$classCache[VALID_CLASS] = instance.$$element.hasClass(VALID_CLASS));
+}
+function addSetValidityMethod(context) {
+  var clazz = context.clazz,
+      set = context.set,
+      unset = context.unset;
+
+  clazz.prototype.$setValidity = function(validationErrorKey, state, controller) {
+    if (isUndefined(state)) {
+      createAndSet(this, '$pending', validationErrorKey, controller);
+    } else {
+      unsetAndCleanup(this, '$pending', validationErrorKey, controller);
+    }
+    if (!isBoolean(state)) {
+      unset(this.$error, validationErrorKey, controller);
+      unset(this.$$success, validationErrorKey, controller);
+    } else {
+      if (state) {
+        unset(this.$error, validationErrorKey, controller);
+        set(this.$$success, validationErrorKey, controller);
+      } else {
+        set(this.$error, validationErrorKey, controller);
+        unset(this.$$success, validationErrorKey, controller);
+      }
+    }
+    if (this.$pending) {
+      cachedToggleClass(this, PENDING_CLASS, true);
+      this.$valid = this.$invalid = undefined;
+      toggleValidationCss(this, '', null);
+    } else {
+      cachedToggleClass(this, PENDING_CLASS, false);
+      this.$valid = isObjectEmpty(this.$error);
+      this.$invalid = !this.$valid;
+      toggleValidationCss(this, '', this.$valid);
+    }
+
+    // re-read the state as the set/unset methods could have
+    // combined state in this.$error[validationError] (used for forms),
+    // where setting/unsetting only increments/decrements the value,
+    // and does not replace it.
+    var combinedState;
+    if (this.$pending && this.$pending[validationErrorKey]) {
+      combinedState = undefined;
+    } else if (this.$error[validationErrorKey]) {
+      combinedState = false;
+    } else if (this.$$success[validationErrorKey]) {
+      combinedState = true;
+    } else {
+      combinedState = null;
+    }
+
+    toggleValidationCss(this, validationErrorKey, combinedState);
+    this.$$parentForm.$setValidity(validationErrorKey, combinedState, this);
+  };
+
+  function createAndSet(ctrl, name, value, controller) {
+    if (!ctrl[name]) {
+      ctrl[name] = {};
+    }
+    set(ctrl[name], value, controller);
+  }
+
+  function unsetAndCleanup(ctrl, name, value, controller) {
+    if (ctrl[name]) {
+      unset(ctrl[name], value, controller);
+    }
+    if (isObjectEmpty(ctrl[name])) {
+      ctrl[name] = undefined;
+    }
+  }
+
+  function cachedToggleClass(ctrl, className, switchValue) {
+    if (switchValue && !ctrl.$$classCache[className]) {
+      ctrl.$$animate.addClass(ctrl.$$element, className);
+      ctrl.$$classCache[className] = true;
+    } else if (!switchValue && ctrl.$$classCache[className]) {
+      ctrl.$$animate.removeClass(ctrl.$$element, className);
+      ctrl.$$classCache[className] = false;
+    }
+  }
+
+  function toggleValidationCss(ctrl, validationErrorKey, isValid) {
+    validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';
+
+    cachedToggleClass(ctrl, VALID_CLASS + validationErrorKey, isValid === true);
+    cachedToggleClass(ctrl, INVALID_CLASS + validationErrorKey, isValid === false);
+  }
+}
+
+function isObjectEmpty(obj) {
+  if (obj) {
+    for (var prop in obj) {
+      if (obj.hasOwnProperty(prop)) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+/* global
+  VALID_CLASS: false,
+  INVALID_CLASS: false,
+  PRISTINE_CLASS: false,
+  DIRTY_CLASS: false,
+  ngModelMinErr: false
+*/
+
+// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231
+var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/;
+// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)
+// Note: We are being more lenient, because browsers are too.
+//   1. Scheme
+//   2. Slashes
+//   3. Username
+//   4. Password
+//   5. Hostname
+//   6. Port
+//   7. Path
+//   8. Query
+//   9. Fragment
+//                 1111111111111111 222   333333    44444        55555555555555555555555     666     77777777     8888888     999
+var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i;
+// eslint-disable-next-line max-len
+var EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
+var NUMBER_REGEXP = /^\s*(-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/;
+var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/;
+var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
+var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/;
+var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/;
+var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
+
+var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown';
+var PARTIAL_VALIDATION_TYPES = createMap();
+forEach('date,datetime-local,month,time,week'.split(','), function(type) {
+  PARTIAL_VALIDATION_TYPES[type] = true;
+});
+
+var inputType = {
+
+  /**
+   * @ngdoc input
+   * @name input[text]
+   *
+   * @description
+   * Standard HTML text input with angular data binding, inherited by most of the `input` elements.
+   *
+   *
+   * @param {string} ngModel Assignable angular expression to data-bind to.
+   * @param {string=} name Property name of the form under which the control is published.
+   * @param {string=} required Adds `required` validation error key if the value is not entered.
+   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+   *    `required` when you want to data-bind to the `required` attribute.
+   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
+   *    minlength.
+   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
+   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
+   *    any length.
+   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
+   *    that contains the regular expression body that will be converted to a regular expression
+   *    as in the ngPattern directive.
+   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
+   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
+   *    If the expression evaluates to a RegExp object, then this is used directly.
+   *    If the expression evaluates to a string, then it will be converted to a RegExp
+   *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
+   *    `new RegExp('^abc$')`.<br />
+   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
+   *    start at the index of the last search's match, thus not taking the whole input value into
+   *    account.
+   * @param {string=} ngChange Angular expression to be executed when input changes due to user
+   *    interaction with the input element.
+   * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
+   *    This parameter is ignored for input[type=password] controls, which will never trim the
+   *    input.
+   *
+   * @example
+      <example name="text-input-directive" module="textInputExample">
+        <file name="index.html">
+         <script>
+           angular.module('textInputExample', [])
+             .controller('ExampleController', ['$scope', function($scope) {
+               $scope.example = {
+                 text: 'guest',
+                 word: /^\s*\w*\s*$/
+               };
+             }]);
+         </script>
+         <form name="myForm" ng-controller="ExampleController">
+           <label>Single word:
+             <input type="text" name="input" ng-model="example.text"
+                    ng-pattern="example.word" required ng-trim="false">
+           </label>
+           <div role="alert">
+             <span class="error" ng-show="myForm.input.$error.required">
+               Required!</span>
+             <span class="error" ng-show="myForm.input.$error.pattern">
+               Single word only!</span>
+           </div>
+           <code>text = {{example.text}}</code><br/>
+           <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br/>
+           <code>myForm.input.$error = {{myForm.input.$error}}</code><br/>
+           <code>myForm.$valid = {{myForm.$valid}}</code><br/>
+           <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br/>
+          </form>
+        </file>
+        <file name="protractor.js" type="protractor">
+          var text = element(by.binding('example.text'));
+          var valid = element(by.binding('myForm.input.$valid'));
+          var input = element(by.model('example.text'));
+
+          it('should initialize to model', function() {
+            expect(text.getText()).toContain('guest');
+            expect(valid.getText()).toContain('true');
+          });
+
+          it('should be invalid if empty', function() {
+            input.clear();
+            input.sendKeys('');
+
+            expect(text.getText()).toEqual('text =');
+            expect(valid.getText()).toContain('false');
+          });
+
+          it('should be invalid if multi word', function() {
+            input.clear();
+            input.sendKeys('hello world');
+
+            expect(valid.getText()).toContain('false');
+          });
+        </file>
+      </example>
+   */
+  'text': textInputType,
+
+    /**
+     * @ngdoc input
+     * @name input[date]
+     *
+     * @description
+     * Input with date validation and transformation. In browsers that do not yet support
+     * the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601
+     * date format (yyyy-MM-dd), for example: `2009-01-06`. Since many
+     * modern browsers do not yet support this input type, it is important to provide cues to users on the
+     * expected input format via a placeholder or label.
+     *
+     * The model must always be a Date object, otherwise Angular will throw an error.
+     * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
+     *
+     * The timezone to be used to read/write the `Date` instance in the model can be defined using
+     * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+     *
+     * @param {string} ngModel Assignable angular expression to data-bind to.
+     * @param {string=} name Property name of the form under which the control is published.
+     * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
+     *   valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute
+     *   (e.g. `min="{{minDate | date:'yyyy-MM-dd'}}"`). Note that `min` will also add native HTML5
+     *   constraint validation.
+     * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be
+     *   a valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute
+     *   (e.g. `max="{{maxDate | date:'yyyy-MM-dd'}}"`). Note that `max` will also add native HTML5
+     *   constraint validation.
+     * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO date string
+     *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
+     * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO date string
+     *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
+     * @param {string=} required Sets `required` validation error key if the value is not entered.
+     * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+     *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+     *    `required` when you want to data-bind to the `required` attribute.
+     * @param {string=} ngChange Angular expression to be executed when input changes due to user
+     *    interaction with the input element.
+     *
+     * @example
+     <example name="date-input-directive" module="dateInputExample">
+     <file name="index.html">
+       <script>
+          angular.module('dateInputExample', [])
+            .controller('DateController', ['$scope', function($scope) {
+              $scope.example = {
+                value: new Date(2013, 9, 22)
+              };
+            }]);
+       </script>
+       <form name="myForm" ng-controller="DateController as dateCtrl">
+          <label for="exampleInput">Pick a date in 2013:</label>
+          <input type="date" id="exampleInput" name="input" ng-model="example.value"
+              placeholder="yyyy-MM-dd" min="2013-01-01" max="2013-12-31" required />
+          <div role="alert">
+            <span class="error" ng-show="myForm.input.$error.required">
+                Required!</span>
+            <span class="error" ng-show="myForm.input.$error.date">
+                Not a valid date!</span>
+           </div>
+           <tt>value = {{example.value | date: "yyyy-MM-dd"}}</tt><br/>
+           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
+           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
+           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+       </form>
+     </file>
+     <file name="protractor.js" type="protractor">
+        var value = element(by.binding('example.value | date: "yyyy-MM-dd"'));
+        var valid = element(by.binding('myForm.input.$valid'));
+
+        // currently protractor/webdriver does not support
+        // sending keys to all known HTML5 input controls
+        // for various browsers (see https://github.com/angular/protractor/issues/562).
+        function setInput(val) {
+          // set the value of the element and force validation.
+          var scr = "var ipt = document.getElementById('exampleInput'); " +
+          "ipt.value = '" + val + "';" +
+          "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
+          browser.executeScript(scr);
+        }
+
+        it('should initialize to model', function() {
+          expect(value.getText()).toContain('2013-10-22');
+          expect(valid.getText()).toContain('myForm.input.$valid = true');
+        });
+
+        it('should be invalid if empty', function() {
+          setInput('');
+          expect(value.getText()).toEqual('value =');
+          expect(valid.getText()).toContain('myForm.input.$valid = false');
+        });
+
+        it('should be invalid if over max', function() {
+          setInput('2015-01-01');
+          expect(value.getText()).toContain('');
+          expect(valid.getText()).toContain('myForm.input.$valid = false');
+        });
+     </file>
+     </example>
+     */
+  'date': createDateInputType('date', DATE_REGEXP,
+         createDateParser(DATE_REGEXP, ['yyyy', 'MM', 'dd']),
+         'yyyy-MM-dd'),
+
+   /**
+    * @ngdoc input
+    * @name input[datetime-local]
+    *
+    * @description
+    * Input with datetime validation and transformation. In browsers that do not yet support
+    * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
+    * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`.
+    *
+    * The model must always be a Date object, otherwise Angular will throw an error.
+    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
+    *
+    * The timezone to be used to read/write the `Date` instance in the model can be defined using
+    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+    *
+    * @param {string} ngModel Assignable angular expression to data-bind to.
+    * @param {string=} name Property name of the form under which the control is published.
+    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
+    *   This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation
+    *   inside this attribute (e.g. `min="{{minDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`).
+    *   Note that `min` will also add native HTML5 constraint validation.
+    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
+    *   This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation
+    *   inside this attribute (e.g. `max="{{maxDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`).
+    *   Note that `max` will also add native HTML5 constraint validation.
+    * @param {(date|string)=} ngMin Sets the `min` validation error key to the Date / ISO datetime string
+    *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
+    * @param {(date|string)=} ngMax Sets the `max` validation error key to the Date / ISO datetime string
+    *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
+    * @param {string=} required Sets `required` validation error key if the value is not entered.
+    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+    *    `required` when you want to data-bind to the `required` attribute.
+    * @param {string=} ngChange Angular expression to be executed when input changes due to user
+    *    interaction with the input element.
+    *
+    * @example
+    <example name="datetimelocal-input-directive" module="dateExample">
+    <file name="index.html">
+      <script>
+        angular.module('dateExample', [])
+          .controller('DateController', ['$scope', function($scope) {
+            $scope.example = {
+              value: new Date(2010, 11, 28, 14, 57)
+            };
+          }]);
+      </script>
+      <form name="myForm" ng-controller="DateController as dateCtrl">
+        <label for="exampleInput">Pick a date between in 2013:</label>
+        <input type="datetime-local" id="exampleInput" name="input" ng-model="example.value"
+            placeholder="yyyy-MM-ddTHH:mm:ss" min="2001-01-01T00:00:00" max="2013-12-31T00:00:00" required />
+        <div role="alert">
+          <span class="error" ng-show="myForm.input.$error.required">
+              Required!</span>
+          <span class="error" ng-show="myForm.input.$error.datetimelocal">
+              Not a valid date!</span>
+        </div>
+        <tt>value = {{example.value | date: "yyyy-MM-ddTHH:mm:ss"}}</tt><br/>
+        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
+        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
+        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+      </form>
+    </file>
+    <file name="protractor.js" type="protractor">
+      var value = element(by.binding('example.value | date: "yyyy-MM-ddTHH:mm:ss"'));
+      var valid = element(by.binding('myForm.input.$valid'));
+
+      // currently protractor/webdriver does not support
+      // sending keys to all known HTML5 input controls
+      // for various browsers (https://github.com/angular/protractor/issues/562).
+      function setInput(val) {
+        // set the value of the element and force validation.
+        var scr = "var ipt = document.getElementById('exampleInput'); " +
+        "ipt.value = '" + val + "';" +
+        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
+        browser.executeScript(scr);
+      }
+
+      it('should initialize to model', function() {
+        expect(value.getText()).toContain('2010-12-28T14:57:00');
+        expect(valid.getText()).toContain('myForm.input.$valid = true');
+      });
+
+      it('should be invalid if empty', function() {
+        setInput('');
+        expect(value.getText()).toEqual('value =');
+        expect(valid.getText()).toContain('myForm.input.$valid = false');
+      });
+
+      it('should be invalid if over max', function() {
+        setInput('2015-01-01T23:59:00');
+        expect(value.getText()).toContain('');
+        expect(valid.getText()).toContain('myForm.input.$valid = false');
+      });
+    </file>
+    </example>
+    */
+  'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP,
+      createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']),
+      'yyyy-MM-ddTHH:mm:ss.sss'),
+
+  /**
+   * @ngdoc input
+   * @name input[time]
+   *
+   * @description
+   * Input with time validation and transformation. In browsers that do not yet support
+   * the HTML5 time input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
+   * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a
+   * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`.
+   *
+   * The model must always be a Date object, otherwise Angular will throw an error.
+   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
+   *
+   * The timezone to be used to read/write the `Date` instance in the model can be defined using
+   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+   *
+   * @param {string} ngModel Assignable angular expression to data-bind to.
+   * @param {string=} name Property name of the form under which the control is published.
+   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
+   *   This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this
+   *   attribute (e.g. `min="{{minTime | date:'HH:mm:ss'}}"`). Note that `min` will also add
+   *   native HTML5 constraint validation.
+   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
+   *   This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this
+   *   attribute (e.g. `max="{{maxTime | date:'HH:mm:ss'}}"`). Note that `max` will also add
+   *   native HTML5 constraint validation.
+   * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO time string the
+   *   `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
+   * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO time string the
+   *   `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
+   * @param {string=} required Sets `required` validation error key if the value is not entered.
+   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+   *    `required` when you want to data-bind to the `required` attribute.
+   * @param {string=} ngChange Angular expression to be executed when input changes due to user
+   *    interaction with the input element.
+   *
+   * @example
+   <example name="time-input-directive" module="timeExample">
+   <file name="index.html">
+     <script>
+      angular.module('timeExample', [])
+        .controller('DateController', ['$scope', function($scope) {
+          $scope.example = {
+            value: new Date(1970, 0, 1, 14, 57, 0)
+          };
+        }]);
+     </script>
+     <form name="myForm" ng-controller="DateController as dateCtrl">
+        <label for="exampleInput">Pick a time between 8am and 5pm:</label>
+        <input type="time" id="exampleInput" name="input" ng-model="example.value"
+            placeholder="HH:mm:ss" min="08:00:00" max="17:00:00" required />
+        <div role="alert">
+          <span class="error" ng-show="myForm.input.$error.required">
+              Required!</span>
+          <span class="error" ng-show="myForm.input.$error.time">
+              Not a valid date!</span>
+        </div>
+        <tt>value = {{example.value | date: "HH:mm:ss"}}</tt><br/>
+        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
+        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
+        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+     </form>
+   </file>
+   <file name="protractor.js" type="protractor">
+      var value = element(by.binding('example.value | date: "HH:mm:ss"'));
+      var valid = element(by.binding('myForm.input.$valid'));
+
+      // currently protractor/webdriver does not support
+      // sending keys to all known HTML5 input controls
+      // for various browsers (https://github.com/angular/protractor/issues/562).
+      function setInput(val) {
+        // set the value of the element and force validation.
+        var scr = "var ipt = document.getElementById('exampleInput'); " +
+        "ipt.value = '" + val + "';" +
+        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
+        browser.executeScript(scr);
+      }
+
+      it('should initialize to model', function() {
+        expect(value.getText()).toContain('14:57:00');
+        expect(valid.getText()).toContain('myForm.input.$valid = true');
+      });
+
+      it('should be invalid if empty', function() {
+        setInput('');
+        expect(value.getText()).toEqual('value =');
+        expect(valid.getText()).toContain('myForm.input.$valid = false');
+      });
+
+      it('should be invalid if over max', function() {
+        setInput('23:59:00');
+        expect(value.getText()).toContain('');
+        expect(valid.getText()).toContain('myForm.input.$valid = false');
+      });
+   </file>
+   </example>
+   */
+  'time': createDateInputType('time', TIME_REGEXP,
+      createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']),
+     'HH:mm:ss.sss'),
+
+   /**
+    * @ngdoc input
+    * @name input[week]
+    *
+    * @description
+    * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support
+    * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
+    * week format (yyyy-W##), for example: `2013-W02`.
+    *
+    * The model must always be a Date object, otherwise Angular will throw an error.
+    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
+    *
+    * The timezone to be used to read/write the `Date` instance in the model can be defined using
+    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+    *
+    * @param {string} ngModel Assignable angular expression to data-bind to.
+    * @param {string=} name Property name of the form under which the control is published.
+    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
+    *   This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this
+    *   attribute (e.g. `min="{{minWeek | date:'yyyy-Www'}}"`). Note that `min` will also add
+    *   native HTML5 constraint validation.
+    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
+    *   This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this
+    *   attribute (e.g. `max="{{maxWeek | date:'yyyy-Www'}}"`). Note that `max` will also add
+    *   native HTML5 constraint validation.
+    * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string
+    *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
+    * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string
+    *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
+    * @param {string=} required Sets `required` validation error key if the value is not entered.
+    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+    *    `required` when you want to data-bind to the `required` attribute.
+    * @param {string=} ngChange Angular expression to be executed when input changes due to user
+    *    interaction with the input element.
+    *
+    * @example
+    <example name="week-input-directive" module="weekExample">
+    <file name="index.html">
+      <script>
+      angular.module('weekExample', [])
+        .controller('DateController', ['$scope', function($scope) {
+          $scope.example = {
+            value: new Date(2013, 0, 3)
+          };
+        }]);
+      </script>
+      <form name="myForm" ng-controller="DateController as dateCtrl">
+        <label>Pick a date between in 2013:
+          <input id="exampleInput" type="week" name="input" ng-model="example.value"
+                 placeholder="YYYY-W##" min="2012-W32"
+                 max="2013-W52" required />
+        </label>
+        <div role="alert">
+          <span class="error" ng-show="myForm.input.$error.required">
+              Required!</span>
+          <span class="error" ng-show="myForm.input.$error.week">
+              Not a valid date!</span>
+        </div>
+        <tt>value = {{example.value | date: "yyyy-Www"}}</tt><br/>
+        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
+        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
+        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+      </form>
+    </file>
+    <file name="protractor.js" type="protractor">
+      var value = element(by.binding('example.value | date: "yyyy-Www"'));
+      var valid = element(by.binding('myForm.input.$valid'));
+
+      // currently protractor/webdriver does not support
+      // sending keys to all known HTML5 input controls
+      // for various browsers (https://github.com/angular/protractor/issues/562).
+      function setInput(val) {
+        // set the value of the element and force validation.
+        var scr = "var ipt = document.getElementById('exampleInput'); " +
+        "ipt.value = '" + val + "';" +
+        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
+        browser.executeScript(scr);
+      }
+
+      it('should initialize to model', function() {
+        expect(value.getText()).toContain('2013-W01');
+        expect(valid.getText()).toContain('myForm.input.$valid = true');
+      });
+
+      it('should be invalid if empty', function() {
+        setInput('');
+        expect(value.getText()).toEqual('value =');
+        expect(valid.getText()).toContain('myForm.input.$valid = false');
+      });
+
+      it('should be invalid if over max', function() {
+        setInput('2015-W01');
+        expect(value.getText()).toContain('');
+        expect(valid.getText()).toContain('myForm.input.$valid = false');
+      });
+    </file>
+    </example>
+    */
+  'week': createDateInputType('week', WEEK_REGEXP, weekParser, 'yyyy-Www'),
+
+  /**
+   * @ngdoc input
+   * @name input[month]
+   *
+   * @description
+   * Input with month validation and transformation. In browsers that do not yet support
+   * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
+   * month format (yyyy-MM), for example: `2009-01`.
+   *
+   * The model must always be a Date object, otherwise Angular will throw an error.
+   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
+   * If the model is not set to the first of the month, the next view to model update will set it
+   * to the first of the month.
+   *
+   * The timezone to be used to read/write the `Date` instance in the model can be defined using
+   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+   *
+   * @param {string} ngModel Assignable angular expression to data-bind to.
+   * @param {string=} name Property name of the form under which the control is published.
+   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
+   *   This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this
+   *   attribute (e.g. `min="{{minMonth | date:'yyyy-MM'}}"`). Note that `min` will also add
+   *   native HTML5 constraint validation.
+   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
+   *   This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this
+   *   attribute (e.g. `max="{{maxMonth | date:'yyyy-MM'}}"`). Note that `max` will also add
+   *   native HTML5 constraint validation.
+   * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string
+   *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
+   * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string
+   *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
+
+   * @param {string=} required Sets `required` validation error key if the value is not entered.
+   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+   *    `required` when you want to data-bind to the `required` attribute.
+   * @param {string=} ngChange Angular expression to be executed when input changes due to user
+   *    interaction with the input element.
+   *
+   * @example
+   <example name="month-input-directive" module="monthExample">
+   <file name="index.html">
+     <script>
+      angular.module('monthExample', [])
+        .controller('DateController', ['$scope', function($scope) {
+          $scope.example = {
+            value: new Date(2013, 9, 1)
+          };
+        }]);
+     </script>
+     <form name="myForm" ng-controller="DateController as dateCtrl">
+       <label for="exampleInput">Pick a month in 2013:</label>
+       <input id="exampleInput" type="month" name="input" ng-model="example.value"
+          placeholder="yyyy-MM" min="2013-01" max="2013-12" required />
+       <div role="alert">
+         <span class="error" ng-show="myForm.input.$error.required">
+            Required!</span>
+         <span class="error" ng-show="myForm.input.$error.month">
+            Not a valid month!</span>
+       </div>
+       <tt>value = {{example.value | date: "yyyy-MM"}}</tt><br/>
+       <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
+       <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
+       <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+       <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+     </form>
+   </file>
+   <file name="protractor.js" type="protractor">
+      var value = element(by.binding('example.value | date: "yyyy-MM"'));
+      var valid = element(by.binding('myForm.input.$valid'));
+
+      // currently protractor/webdriver does not support
+      // sending keys to all known HTML5 input controls
+      // for various browsers (https://github.com/angular/protractor/issues/562).
+      function setInput(val) {
+        // set the value of the element and force validation.
+        var scr = "var ipt = document.getElementById('exampleInput'); " +
+        "ipt.value = '" + val + "';" +
+        "angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('" + val + "'); });";
+        browser.executeScript(scr);
+      }
+
+      it('should initialize to model', function() {
+        expect(value.getText()).toContain('2013-10');
+        expect(valid.getText()).toContain('myForm.input.$valid = true');
+      });
+
+      it('should be invalid if empty', function() {
+        setInput('');
+        expect(value.getText()).toEqual('value =');
+        expect(valid.getText()).toContain('myForm.input.$valid = false');
+      });
+
+      it('should be invalid if over max', function() {
+        setInput('2015-01');
+        expect(value.getText()).toContain('');
+        expect(valid.getText()).toContain('myForm.input.$valid = false');
+      });
+   </file>
+   </example>
+   */
+  'month': createDateInputType('month', MONTH_REGEXP,
+     createDateParser(MONTH_REGEXP, ['yyyy', 'MM']),
+     'yyyy-MM'),
+
+  /**
+   * @ngdoc input
+   * @name input[number]
+   *
+   * @description
+   * Text input with number validation and transformation. Sets the `number` validation
+   * error if not a valid number.
+   *
+   * <div class="alert alert-warning">
+   * The model must always be of type `number` otherwise Angular will throw an error.
+   * Be aware that a string containing a number is not enough. See the {@link ngModel:numfmt}
+   * error docs for more information and an example of how to convert your model if necessary.
+   * </div>
+   *
+   * ## Issues with HTML5 constraint validation
+   *
+   * In browsers that follow the
+   * [HTML5 specification](https://html.spec.whatwg.org/multipage/forms.html#number-state-%28type=number%29),
+   * `input[number]` does not work as expected with {@link ngModelOptions `ngModelOptions.allowInvalid`}.
+   * If a non-number is entered in the input, the browser will report the value as an empty string,
+   * which means the view / model values in `ngModel` and subsequently the scope value
+   * will also be an empty string.
+   *
+   *
+   * @param {string} ngModel Assignable angular expression to data-bind to.
+   * @param {string=} name Property name of the form under which the control is published.
+   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
+   *    Can be interpolated.
+   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
+   *    Can be interpolated.
+   * @param {string=} ngMin Like `min`, sets the `min` validation error key if the value entered is less than `ngMin`,
+   *    but does not trigger HTML5 native validation. Takes an expression.
+   * @param {string=} ngMax Like `max`, sets the `max` validation error key if the value entered is greater than `ngMax`,
+   *    but does not trigger HTML5 native validation. Takes an expression.
+   * @param {string=} step Sets the `step` validation error key if the value entered does not fit the `step` constraint.
+   *    Can be interpolated.
+   * @param {string=} ngStep Like `step`, sets the `step` validation error key if the value entered does not fit the `ngStep` constraint,
+   *    but does not trigger HTML5 native validation. Takes an expression.
+   * @param {string=} required Sets `required` validation error key if the value is not entered.
+   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+   *    `required` when you want to data-bind to the `required` attribute.
+   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
+   *    minlength.
+   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
+   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
+   *    any length.
+   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
+   *    that contains the regular expression body that will be converted to a regular expression
+   *    as in the ngPattern directive.
+   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
+   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
+   *    If the expression evaluates to a RegExp object, then this is used directly.
+   *    If the expression evaluates to a string, then it will be converted to a RegExp
+   *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
+   *    `new RegExp('^abc$')`.<br />
+   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
+   *    start at the index of the last search's match, thus not taking the whole input value into
+   *    account.
+   * @param {string=} ngChange Angular expression to be executed when input changes due to user
+   *    interaction with the input element.
+   *
+   * @example
+      <example name="number-input-directive" module="numberExample">
+        <file name="index.html">
+         <script>
+           angular.module('numberExample', [])
+             .controller('ExampleController', ['$scope', function($scope) {
+               $scope.example = {
+                 value: 12
+               };
+             }]);
+         </script>
+         <form name="myForm" ng-controller="ExampleController">
+           <label>Number:
+             <input type="number" name="input" ng-model="example.value"
+                    min="0" max="99" required>
+          </label>
+           <div role="alert">
+             <span class="error" ng-show="myForm.input.$error.required">
+               Required!</span>
+             <span class="error" ng-show="myForm.input.$error.number">
+               Not valid number!</span>
+           </div>
+           <tt>value = {{example.value}}</tt><br/>
+           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
+           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
+           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+          </form>
+        </file>
+        <file name="protractor.js" type="protractor">
+          var value = element(by.binding('example.value'));
+          var valid = element(by.binding('myForm.input.$valid'));
+          var input = element(by.model('example.value'));
+
+          it('should initialize to model', function() {
+            expect(value.getText()).toContain('12');
+            expect(valid.getText()).toContain('true');
+          });
+
+          it('should be invalid if empty', function() {
+            input.clear();
+            input.sendKeys('');
+            expect(value.getText()).toEqual('value =');
+            expect(valid.getText()).toContain('false');
+          });
+
+          it('should be invalid if over max', function() {
+            input.clear();
+            input.sendKeys('123');
+            expect(value.getText()).toEqual('value =');
+            expect(valid.getText()).toContain('false');
+          });
+        </file>
+      </example>
+   */
+  'number': numberInputType,
+
+
+  /**
+   * @ngdoc input
+   * @name input[url]
+   *
+   * @description
+   * Text input with URL validation. Sets the `url` validation error key if the content is not a
+   * valid URL.
+   *
+   * <div class="alert alert-warning">
+   * **Note:** `input[url]` uses a regex to validate urls that is derived from the regex
+   * used in Chromium. If you need stricter validation, you can use `ng-pattern` or modify
+   * the built-in validators (see the {@link guide/forms Forms guide})
+   * </div>
+   *
+   * @param {string} ngModel Assignable angular expression to data-bind to.
+   * @param {string=} name Property name of the form under which the control is published.
+   * @param {string=} required Sets `required` validation error key if the value is not entered.
+   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+   *    `required` when you want to data-bind to the `required` attribute.
+   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
+   *    minlength.
+   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
+   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
+   *    any length.
+   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
+   *    that contains the regular expression body that will be converted to a regular expression
+   *    as in the ngPattern directive.
+   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
+   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
+   *    If the expression evaluates to a RegExp object, then this is used directly.
+   *    If the expression evaluates to a string, then it will be converted to a RegExp
+   *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
+   *    `new RegExp('^abc$')`.<br />
+   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
+   *    start at the index of the last search's match, thus not taking the whole input value into
+   *    account.
+   * @param {string=} ngChange Angular expression to be executed when input changes due to user
+   *    interaction with the input element.
+   *
+   * @example
+      <example name="url-input-directive" module="urlExample">
+        <file name="index.html">
+         <script>
+           angular.module('urlExample', [])
+             .controller('ExampleController', ['$scope', function($scope) {
+               $scope.url = {
+                 text: 'http://google.com'
+               };
+             }]);
+         </script>
+         <form name="myForm" ng-controller="ExampleController">
+           <label>URL:
+             <input type="url" name="input" ng-model="url.text" required>
+           <label>
+           <div role="alert">
+             <span class="error" ng-show="myForm.input.$error.required">
+               Required!</span>
+             <span class="error" ng-show="myForm.input.$error.url">
+               Not valid url!</span>
+           </div>
+           <tt>text = {{url.text}}</tt><br/>
+           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
+           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
+           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+           <tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/>
+          </form>
+        </file>
+        <file name="protractor.js" type="protractor">
+          var text = element(by.binding('url.text'));
+          var valid = element(by.binding('myForm.input.$valid'));
+          var input = element(by.model('url.text'));
+
+          it('should initialize to model', function() {
+            expect(text.getText()).toContain('http://google.com');
+            expect(valid.getText()).toContain('true');
+          });
+
+          it('should be invalid if empty', function() {
+            input.clear();
+            input.sendKeys('');
+
+            expect(text.getText()).toEqual('text =');
+            expect(valid.getText()).toContain('false');
+          });
+
+          it('should be invalid if not url', function() {
+            input.clear();
+            input.sendKeys('box');
+
+            expect(valid.getText()).toContain('false');
+          });
+        </file>
+      </example>
+   */
+  'url': urlInputType,
+
+
+  /**
+   * @ngdoc input
+   * @name input[email]
+   *
+   * @description
+   * Text input with email validation. Sets the `email` validation error key if not a valid email
+   * address.
+   *
+   * <div class="alert alert-warning">
+   * **Note:** `input[email]` uses a regex to validate email addresses that is derived from the regex
+   * used in Chromium. If you need stricter validation (e.g. requiring a top-level domain), you can
+   * use `ng-pattern` or modify the built-in validators (see the {@link guide/forms Forms guide})
+   * </div>
+   *
+   * @param {string} ngModel Assignable angular expression to data-bind to.
+   * @param {string=} name Property name of the form under which the control is published.
+   * @param {string=} required Sets `required` validation error key if the value is not entered.
+   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+   *    `required` when you want to data-bind to the `required` attribute.
+   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
+   *    minlength.
+   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
+   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
+   *    any length.
+   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
+   *    that contains the regular expression body that will be converted to a regular expression
+   *    as in the ngPattern directive.
+   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
+   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
+   *    If the expression evaluates to a RegExp object, then this is used directly.
+   *    If the expression evaluates to a string, then it will be converted to a RegExp
+   *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
+   *    `new RegExp('^abc$')`.<br />
+   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
+   *    start at the index of the last search's match, thus not taking the whole input value into
+   *    account.
+   * @param {string=} ngChange Angular expression to be executed when input changes due to user
+   *    interaction with the input element.
+   *
+   * @example
+      <example name="email-input-directive" module="emailExample">
+        <file name="index.html">
+         <script>
+           angular.module('emailExample', [])
+             .controller('ExampleController', ['$scope', function($scope) {
+               $scope.email = {
+                 text: 'me@example.com'
+               };
+             }]);
+         </script>
+           <form name="myForm" ng-controller="ExampleController">
+             <label>Email:
+               <input type="email" name="input" ng-model="email.text" required>
+             </label>
+             <div role="alert">
+               <span class="error" ng-show="myForm.input.$error.required">
+                 Required!</span>
+               <span class="error" ng-show="myForm.input.$error.email">
+                 Not valid email!</span>
+             </div>
+             <tt>text = {{email.text}}</tt><br/>
+             <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
+             <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
+             <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+             <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+             <tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>
+           </form>
+         </file>
+        <file name="protractor.js" type="protractor">
+          var text = element(by.binding('email.text'));
+          var valid = element(by.binding('myForm.input.$valid'));
+          var input = element(by.model('email.text'));
+
+          it('should initialize to model', function() {
+            expect(text.getText()).toContain('me@example.com');
+            expect(valid.getText()).toContain('true');
+          });
+
+          it('should be invalid if empty', function() {
+            input.clear();
+            input.sendKeys('');
+            expect(text.getText()).toEqual('text =');
+            expect(valid.getText()).toContain('false');
+          });
+
+          it('should be invalid if not email', function() {
+            input.clear();
+            input.sendKeys('xxx');
+
+            expect(valid.getText()).toContain('false');
+          });
+        </file>
+      </example>
+   */
+  'email': emailInputType,
+
+
+  /**
+   * @ngdoc input
+   * @name input[radio]
+   *
+   * @description
+   * HTML radio button.
+   *
+   * @param {string} ngModel Assignable angular expression to data-bind to.
+   * @param {string} value The value to which the `ngModel` expression should be set when selected.
+   *    Note that `value` only supports `string` values, i.e. the scope model needs to be a string,
+   *    too. Use `ngValue` if you need complex models (`number`, `object`, ...).
+   * @param {string=} name Property name of the form under which the control is published.
+   * @param {string=} ngChange Angular expression to be executed when input changes due to user
+   *    interaction with the input element.
+   * @param {string} ngValue Angular expression to which `ngModel` will be be set when the radio
+   *    is selected. Should be used instead of the `value` attribute if you need
+   *    a non-string `ngModel` (`boolean`, `array`, ...).
+   *
+   * @example
+      <example name="radio-input-directive" module="radioExample">
+        <file name="index.html">
+         <script>
+           angular.module('radioExample', [])
+             .controller('ExampleController', ['$scope', function($scope) {
+               $scope.color = {
+                 name: 'blue'
+               };
+               $scope.specialValue = {
+                 "id": "12345",
+                 "value": "green"
+               };
+             }]);
+         </script>
+         <form name="myForm" ng-controller="ExampleController">
+           <label>
+             <input type="radio" ng-model="color.name" value="red">
+             Red
+           </label><br/>
+           <label>
+             <input type="radio" ng-model="color.name" ng-value="specialValue">
+             Green
+           </label><br/>
+           <label>
+             <input type="radio" ng-model="color.name" value="blue">
+             Blue
+           </label><br/>
+           <tt>color = {{color.name | json}}</tt><br/>
+          </form>
+          Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
+        </file>
+        <file name="protractor.js" type="protractor">
+          it('should change state', function() {
+            var inputs = element.all(by.model('color.name'));
+            var color = element(by.binding('color.name'));
+
+            expect(color.getText()).toContain('blue');
+
+            inputs.get(0).click();
+            expect(color.getText()).toContain('red');
+
+            inputs.get(1).click();
+            expect(color.getText()).toContain('green');
+          });
+        </file>
+      </example>
+   */
+  'radio': radioInputType,
+
+  /**
+   * @ngdoc input
+   * @name input[range]
+   *
+   * @description
+   * Native range input with validation and transformation.
+   *
+   * The model for the range input must always be a `Number`.
+   *
+   * IE9 and other browsers that do not support the `range` type fall back
+   * to a text input without any default values for `min`, `max` and `step`. Model binding,
+   * validation and number parsing are nevertheless supported.
+   *
+   * Browsers that support range (latest Chrome, Safari, Firefox, Edge) treat `input[range]`
+   * in a way that never allows the input to hold an invalid value. That means:
+   * - any non-numerical value is set to `(max + min) / 2`.
+   * - any numerical value that is less than the current min val, or greater than the current max val
+   * is set to the min / max val respectively.
+   * - additionally, the current `step` is respected, so the nearest value that satisfies a step
+   * is used.
+   *
+   * See the [HTML Spec on input[type=range]](https://www.w3.org/TR/html5/forms.html#range-state-(type=range))
+   * for more info.
+   *
+   * This has the following consequences for Angular:
+   *
+   * Since the element value should always reflect the current model value, a range input
+   * will set the bound ngModel expression to the value that the browser has set for the
+   * input element. For example, in the following input `<input type="range" ng-model="model.value">`,
+   * if the application sets `model.value = null`, the browser will set the input to `'50'`.
+   * Angular will then set the model to `50`, to prevent input and model value being out of sync.
+   *
+   * That means the model for range will immediately be set to `50` after `ngModel` has been
+   * initialized. It also means a range input can never have the required error.
+   *
+   * This does not only affect changes to the model value, but also to the values of the `min`,
+   * `max`, and `step` attributes. When these change in a way that will cause the browser to modify
+   * the input value, Angular will also update the model value.
+   *
+   * Automatic value adjustment also means that a range input element can never have the `required`,
+   * `min`, or `max` errors.
+   *
+   * However, `step` is currently only fully implemented by Firefox. Other browsers have problems
+   * when the step value changes dynamically - they do not adjust the element value correctly, but
+   * instead may set the `stepMismatch` error. If that's the case, the Angular will set the `step`
+   * error on the input, and set the model to `undefined`.
+   *
+   * Note that `input[range]` is not compatible with`ngMax`, `ngMin`, and `ngStep`, because they do
+   * not set the `min` and `max` attributes, which means that the browser won't automatically adjust
+   * the input value based on their values, and will always assume min = 0, max = 100, and step = 1.
+   *
+   * @param {string}  ngModel Assignable angular expression to data-bind to.
+   * @param {string=} name Property name of the form under which the control is published.
+   * @param {string=} min Sets the `min` validation to ensure that the value entered is greater
+   *                  than `min`. Can be interpolated.
+   * @param {string=} max Sets the `max` validation to ensure that the value entered is less than `max`.
+   *                  Can be interpolated.
+   * @param {string=} step Sets the `step` validation to ensure that the value entered matches the `step`
+   *                  Can be interpolated.
+   * @param {string=} ngChange Angular expression to be executed when the ngModel value changes due
+   *                  to user interaction with the input element.
+   * @param {expression=} ngChecked If the expression is truthy, then the `checked` attribute will be set on the
+   *                      element. **Note** : `ngChecked` should not be used alongside `ngModel`.
+   *                      Checkout {@link ng.directive:ngChecked ngChecked} for usage.
+   *
+   * @example
+      <example name="range-input-directive" module="rangeExample">
+        <file name="index.html">
+          <script>
+            angular.module('rangeExample', [])
+              .controller('ExampleController', ['$scope', function($scope) {
+                $scope.value = 75;
+                $scope.min = 10;
+                $scope.max = 90;
+              }]);
+          </script>
+          <form name="myForm" ng-controller="ExampleController">
+
+            Model as range: <input type="range" name="range" ng-model="value" min="{{min}}"  max="{{max}}">
+            <hr>
+            Model as number: <input type="number" ng-model="value"><br>
+            Min: <input type="number" ng-model="min"><br>
+            Max: <input type="number" ng-model="max"><br>
+            value = <code>{{value}}</code><br/>
+            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>
+            myForm.range.$error = <code>{{myForm.range.$error}}</code>
+          </form>
+        </file>
+      </example>
+
+   * ## Range Input with ngMin & ngMax attributes
+
+   * @example
+      <example name="range-input-directive-ng" module="rangeExample">
+        <file name="index.html">
+          <script>
+            angular.module('rangeExample', [])
+              .controller('ExampleController', ['$scope', function($scope) {
+                $scope.value = 75;
+                $scope.min = 10;
+                $scope.max = 90;
+              }]);
+          </script>
+          <form name="myForm" ng-controller="ExampleController">
+            Model as range: <input type="range" name="range" ng-model="value" ng-min="min" ng-max="max">
+            <hr>
+            Model as number: <input type="number" ng-model="value"><br>
+            Min: <input type="number" ng-model="min"><br>
+            Max: <input type="number" ng-model="max"><br>
+            value = <code>{{value}}</code><br/>
+            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>
+            myForm.range.$error = <code>{{myForm.range.$error}}</code>
+          </form>
+        </file>
+      </example>
+
+   */
+  'range': rangeInputType,
+
+  /**
+   * @ngdoc input
+   * @name input[checkbox]
+   *
+   * @description
+   * HTML checkbox.
+   *
+   * @param {string} ngModel Assignable angular expression to data-bind to.
+   * @param {string=} name Property name of the form under which the control is published.
+   * @param {expression=} ngTrueValue The value to which the expression should be set when selected.
+   * @param {expression=} ngFalseValue The value to which the expression should be set when not selected.
+   * @param {string=} ngChange Angular expression to be executed when input changes due to user
+   *    interaction with the input element.
+   *
+   * @example
+      <example name="checkbox-input-directive" module="checkboxExample">
+        <file name="index.html">
+         <script>
+           angular.module('checkboxExample', [])
+             .controller('ExampleController', ['$scope', function($scope) {
+               $scope.checkboxModel = {
+                value1 : true,
+                value2 : 'YES'
+              };
+             }]);
+         </script>
+         <form name="myForm" ng-controller="ExampleController">
+           <label>Value1:
+             <input type="checkbox" ng-model="checkboxModel.value1">
+           </label><br/>
+           <label>Value2:
+             <input type="checkbox" ng-model="checkboxModel.value2"
+                    ng-true-value="'YES'" ng-false-value="'NO'">
+            </label><br/>
+           <tt>value1 = {{checkboxModel.value1}}</tt><br/>
+           <tt>value2 = {{checkboxModel.value2}}</tt><br/>
+          </form>
+        </file>
+        <file name="protractor.js" type="protractor">
+          it('should change state', function() {
+            var value1 = element(by.binding('checkboxModel.value1'));
+            var value2 = element(by.binding('checkboxModel.value2'));
+
+            expect(value1.getText()).toContain('true');
+            expect(value2.getText()).toContain('YES');
+
+            element(by.model('checkboxModel.value1')).click();
+            element(by.model('checkboxModel.value2')).click();
+
+            expect(value1.getText()).toContain('false');
+            expect(value2.getText()).toContain('NO');
+          });
+        </file>
+      </example>
+   */
+  'checkbox': checkboxInputType,
+
+  'hidden': noop,
+  'button': noop,
+  'submit': noop,
+  'reset': noop,
+  'file': noop
+};
+
+function stringBasedInputType(ctrl) {
+  ctrl.$formatters.push(function(value) {
+    return ctrl.$isEmpty(value) ? value : value.toString();
+  });
+}
+
+function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
+  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
+  stringBasedInputType(ctrl);
+}
+
+function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
+  var type = lowercase(element[0].type);
+
+  // In composition mode, users are still inputting intermediate text buffer,
+  // hold the listener until composition is done.
+  // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
+  if (!$sniffer.android) {
+    var composing = false;
+
+    element.on('compositionstart', function() {
+      composing = true;
+    });
+
+    element.on('compositionend', function() {
+      composing = false;
+      listener();
+    });
+  }
+
+  var timeout;
+
+  var listener = function(ev) {
+    if (timeout) {
+      $browser.defer.cancel(timeout);
+      timeout = null;
+    }
+    if (composing) return;
+    var value = element.val(),
+        event = ev && ev.type;
+
+    // By default we will trim the value
+    // If the attribute ng-trim exists we will avoid trimming
+    // If input type is 'password', the value is never trimmed
+    if (type !== 'password' && (!attr.ngTrim || attr.ngTrim !== 'false')) {
+      value = trim(value);
+    }
+
+    // If a control is suffering from bad input (due to native validators), browsers discard its
+    // value, so it may be necessary to revalidate (by calling $setViewValue again) even if the
+    // control's value is the same empty value twice in a row.
+    if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) {
+      ctrl.$setViewValue(value, event);
+    }
+  };
+
+  // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the
+  // input event on backspace, delete or cut
+  if ($sniffer.hasEvent('input')) {
+    element.on('input', listener);
+  } else {
+    var deferListener = function(ev, input, origValue) {
+      if (!timeout) {
+        timeout = $browser.defer(function() {
+          timeout = null;
+          if (!input || input.value !== origValue) {
+            listener(ev);
+          }
+        });
+      }
+    };
+
+    element.on('keydown', /** @this */ function(event) {
+      var key = event.keyCode;
+
+      // ignore
+      //    command            modifiers                   arrows
+      if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
+
+      deferListener(event, this, this.value);
+    });
+
+    // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
+    if ($sniffer.hasEvent('paste')) {
+      element.on('paste cut', deferListener);
+    }
+  }
+
+  // if user paste into input using mouse on older browser
+  // or form autocomplete on newer browser, we need "change" event to catch it
+  element.on('change', listener);
+
+  // Some native input types (date-family) have the ability to change validity without
+  // firing any input/change events.
+  // For these event types, when native validators are present and the browser supports the type,
+  // check for validity changes on various DOM events.
+  if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) {
+    element.on(PARTIAL_VALIDATION_EVENTS, /** @this */ function(ev) {
+      if (!timeout) {
+        var validity = this[VALIDITY_STATE_PROPERTY];
+        var origBadInput = validity.badInput;
+        var origTypeMismatch = validity.typeMismatch;
+        timeout = $browser.defer(function() {
+          timeout = null;
+          if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) {
+            listener(ev);
+          }
+        });
+      }
+    });
+  }
+
+  ctrl.$render = function() {
+    // Workaround for Firefox validation #12102.
+    var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue;
+    if (element.val() !== value) {
+      element.val(value);
+    }
+  };
+}
+
+function weekParser(isoWeek, existingDate) {
+  if (isDate(isoWeek)) {
+    return isoWeek;
+  }
+
+  if (isString(isoWeek)) {
+    WEEK_REGEXP.lastIndex = 0;
+    var parts = WEEK_REGEXP.exec(isoWeek);
+    if (parts) {
+      var year = +parts[1],
+          week = +parts[2],
+          hours = 0,
+          minutes = 0,
+          seconds = 0,
+          milliseconds = 0,
+          firstThurs = getFirstThursdayOfYear(year),
+          addDays = (week - 1) * 7;
+
+      if (existingDate) {
+        hours = existingDate.getHours();
+        minutes = existingDate.getMinutes();
+        seconds = existingDate.getSeconds();
+        milliseconds = existingDate.getMilliseconds();
+      }
+
+      return new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds);
+    }
+  }
+
+  return NaN;
+}
+
+function createDateParser(regexp, mapping) {
+  return function(iso, date) {
+    var parts, map;
+
+    if (isDate(iso)) {
+      return iso;
+    }
+
+    if (isString(iso)) {
+      // When a date is JSON'ified to wraps itself inside of an extra
+      // set of double quotes. This makes the date parsing code unable
+      // to match the date string and parse it as a date.
+      if (iso.charAt(0) === '"' && iso.charAt(iso.length - 1) === '"') {
+        iso = iso.substring(1, iso.length - 1);
+      }
+      if (ISO_DATE_REGEXP.test(iso)) {
+        return new Date(iso);
+      }
+      regexp.lastIndex = 0;
+      parts = regexp.exec(iso);
+
+      if (parts) {
+        parts.shift();
+        if (date) {
+          map = {
+            yyyy: date.getFullYear(),
+            MM: date.getMonth() + 1,
+            dd: date.getDate(),
+            HH: date.getHours(),
+            mm: date.getMinutes(),
+            ss: date.getSeconds(),
+            sss: date.getMilliseconds() / 1000
+          };
+        } else {
+          map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 };
+        }
+
+        forEach(parts, function(part, index) {
+          if (index < mapping.length) {
+            map[mapping[index]] = +part;
+          }
+        });
+        return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss * 1000 || 0);
+      }
+    }
+
+    return NaN;
+  };
+}
+
+function createDateInputType(type, regexp, parseDate, format) {
+  return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
+    badInputChecker(scope, element, attr, ctrl);
+    baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
+    var timezone = ctrl && ctrl.$options.getOption('timezone');
+    var previousDate;
+
+    ctrl.$$parserName = type;
+    ctrl.$parsers.push(function(value) {
+      if (ctrl.$isEmpty(value)) return null;
+      if (regexp.test(value)) {
+        // Note: We cannot read ctrl.$modelValue, as there might be a different
+        // parser/formatter in the processing chain so that the model
+        // contains some different data format!
+        var parsedDate = parseDate(value, previousDate);
+        if (timezone) {
+          parsedDate = convertTimezoneToLocal(parsedDate, timezone);
+        }
+        return parsedDate;
+      }
+      return undefined;
+    });
+
+    ctrl.$formatters.push(function(value) {
+      if (value && !isDate(value)) {
+        throw ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);
+      }
+      if (isValidDate(value)) {
+        previousDate = value;
+        if (previousDate && timezone) {
+          previousDate = convertTimezoneToLocal(previousDate, timezone, true);
+        }
+        return $filter('date')(value, format, timezone);
+      } else {
+        previousDate = null;
+        return '';
+      }
+    });
+
+    if (isDefined(attr.min) || attr.ngMin) {
+      var minVal;
+      ctrl.$validators.min = function(value) {
+        return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal;
+      };
+      attr.$observe('min', function(val) {
+        minVal = parseObservedDateValue(val);
+        ctrl.$validate();
+      });
+    }
+
+    if (isDefined(attr.max) || attr.ngMax) {
+      var maxVal;
+      ctrl.$validators.max = function(value) {
+        return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal;
+      };
+      attr.$observe('max', function(val) {
+        maxVal = parseObservedDateValue(val);
+        ctrl.$validate();
+      });
+    }
+
+    function isValidDate(value) {
+      // Invalid Date: getTime() returns NaN
+      return value && !(value.getTime && value.getTime() !== value.getTime());
+    }
+
+    function parseObservedDateValue(val) {
+      return isDefined(val) && !isDate(val) ? parseDate(val) || undefined : val;
+    }
+  };
+}
+
+function badInputChecker(scope, element, attr, ctrl) {
+  var node = element[0];
+  var nativeValidation = ctrl.$$hasNativeValidators = isObject(node.validity);
+  if (nativeValidation) {
+    ctrl.$parsers.push(function(value) {
+      var validity = element.prop(VALIDITY_STATE_PROPERTY) || {};
+      return validity.badInput || validity.typeMismatch ? undefined : value;
+    });
+  }
+}
+
+function numberFormatterParser(ctrl) {
+  ctrl.$$parserName = 'number';
+  ctrl.$parsers.push(function(value) {
+    if (ctrl.$isEmpty(value))      return null;
+    if (NUMBER_REGEXP.test(value)) return parseFloat(value);
+    return undefined;
+  });
+
+  ctrl.$formatters.push(function(value) {
+    if (!ctrl.$isEmpty(value)) {
+      if (!isNumber(value)) {
+        throw ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value);
+      }
+      value = value.toString();
+    }
+    return value;
+  });
+}
+
+function parseNumberAttrVal(val) {
+  if (isDefined(val) && !isNumber(val)) {
+    val = parseFloat(val);
+  }
+  return !isNumberNaN(val) ? val : undefined;
+}
+
+function isNumberInteger(num) {
+  // See http://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript#14794066
+  // (minus the assumption that `num` is a number)
+
+  // eslint-disable-next-line no-bitwise
+  return (num | 0) === num;
+}
+
+function countDecimals(num) {
+  var numString = num.toString();
+  var decimalSymbolIndex = numString.indexOf('.');
+
+  if (decimalSymbolIndex === -1) {
+    if (-1 < num && num < 1) {
+      // It may be in the exponential notation format (`1e-X`)
+      var match = /e-(\d+)$/.exec(numString);
+
+      if (match) {
+        return Number(match[1]);
+      }
+    }
+
+    return 0;
+  }
+
+  return numString.length - decimalSymbolIndex - 1;
+}
+
+function isValidForStep(viewValue, stepBase, step) {
+  // At this point `stepBase` and `step` are expected to be non-NaN values
+  // and `viewValue` is expected to be a valid stringified number.
+  var value = Number(viewValue);
+
+  var isNonIntegerValue = !isNumberInteger(value);
+  var isNonIntegerStepBase = !isNumberInteger(stepBase);
+  var isNonIntegerStep = !isNumberInteger(step);
+
+  // Due to limitations in Floating Point Arithmetic (e.g. `0.3 - 0.2 !== 0.1` or
+  // `0.5 % 0.1 !== 0`), we need to convert all numbers to integers.
+  if (isNonIntegerValue || isNonIntegerStepBase || isNonIntegerStep) {
+    var valueDecimals = isNonIntegerValue ? countDecimals(value) : 0;
+    var stepBaseDecimals = isNonIntegerStepBase ? countDecimals(stepBase) : 0;
+    var stepDecimals = isNonIntegerStep ? countDecimals(step) : 0;
+
+    var decimalCount = Math.max(valueDecimals, stepBaseDecimals, stepDecimals);
+    var multiplier = Math.pow(10, decimalCount);
+
+    value = value * multiplier;
+    stepBase = stepBase * multiplier;
+    step = step * multiplier;
+
+    if (isNonIntegerValue) value = Math.round(value);
+    if (isNonIntegerStepBase) stepBase = Math.round(stepBase);
+    if (isNonIntegerStep) step = Math.round(step);
+  }
+
+  return (value - stepBase) % step === 0;
+}
+
+function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
+  badInputChecker(scope, element, attr, ctrl);
+  numberFormatterParser(ctrl);
+  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
+
+  var minVal;
+  var maxVal;
+
+  if (isDefined(attr.min) || attr.ngMin) {
+    ctrl.$validators.min = function(value) {
+      return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
+    };
+
+    attr.$observe('min', function(val) {
+      minVal = parseNumberAttrVal(val);
+      // TODO(matsko): implement validateLater to reduce number of validations
+      ctrl.$validate();
+    });
+  }
+
+  if (isDefined(attr.max) || attr.ngMax) {
+    ctrl.$validators.max = function(value) {
+      return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
+    };
+
+    attr.$observe('max', function(val) {
+      maxVal = parseNumberAttrVal(val);
+      // TODO(matsko): implement validateLater to reduce number of validations
+      ctrl.$validate();
+    });
+  }
+
+  if (isDefined(attr.step) || attr.ngStep) {
+    var stepVal;
+    ctrl.$validators.step = function(modelValue, viewValue) {
+      return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) ||
+             isValidForStep(viewValue, minVal || 0, stepVal);
+    };
+
+    attr.$observe('step', function(val) {
+      stepVal = parseNumberAttrVal(val);
+      // TODO(matsko): implement validateLater to reduce number of validations
+      ctrl.$validate();
+    });
+  }
+}
+
+function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
+  badInputChecker(scope, element, attr, ctrl);
+  numberFormatterParser(ctrl);
+  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
+
+  var supportsRange = ctrl.$$hasNativeValidators && element[0].type === 'range',
+      minVal = supportsRange ? 0 : undefined,
+      maxVal = supportsRange ? 100 : undefined,
+      stepVal = supportsRange ? 1 : undefined,
+      validity = element[0].validity,
+      hasMinAttr = isDefined(attr.min),
+      hasMaxAttr = isDefined(attr.max),
+      hasStepAttr = isDefined(attr.step);
+
+  var originalRender = ctrl.$render;
+
+  ctrl.$render = supportsRange && isDefined(validity.rangeUnderflow) && isDefined(validity.rangeOverflow) ?
+    //Browsers that implement range will set these values automatically, but reading the adjusted values after
+    //$render would cause the min / max validators to be applied with the wrong value
+    function rangeRender() {
+      originalRender();
+      ctrl.$setViewValue(element.val());
+    } :
+    originalRender;
+
+  if (hasMinAttr) {
+    ctrl.$validators.min = supportsRange ?
+      // Since all browsers set the input to a valid value, we don't need to check validity
+      function noopMinValidator() { return true; } :
+      // non-support browsers validate the min val
+      function minValidator(modelValue, viewValue) {
+        return ctrl.$isEmpty(viewValue) || isUndefined(minVal) || viewValue >= minVal;
+      };
+
+    setInitialValueAndObserver('min', minChange);
+  }
+
+  if (hasMaxAttr) {
+    ctrl.$validators.max = supportsRange ?
+      // Since all browsers set the input to a valid value, we don't need to check validity
+      function noopMaxValidator() { return true; } :
+      // non-support browsers validate the max val
+      function maxValidator(modelValue, viewValue) {
+        return ctrl.$isEmpty(viewValue) || isUndefined(maxVal) || viewValue <= maxVal;
+      };
+
+    setInitialValueAndObserver('max', maxChange);
+  }
+
+  if (hasStepAttr) {
+    ctrl.$validators.step = supportsRange ?
+      function nativeStepValidator() {
+        // Currently, only FF implements the spec on step change correctly (i.e. adjusting the
+        // input element value to a valid value). It's possible that other browsers set the stepMismatch
+        // validity error instead, so we can at least report an error in that case.
+        return !validity.stepMismatch;
+      } :
+      // ngStep doesn't set the setp attr, so the browser doesn't adjust the input value as setting step would
+      function stepValidator(modelValue, viewValue) {
+        return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) ||
+               isValidForStep(viewValue, minVal || 0, stepVal);
+      };
+
+    setInitialValueAndObserver('step', stepChange);
+  }
+
+  function setInitialValueAndObserver(htmlAttrName, changeFn) {
+    // interpolated attributes set the attribute value only after a digest, but we need the
+    // attribute value when the input is first rendered, so that the browser can adjust the
+    // input value based on the min/max value
+    element.attr(htmlAttrName, attr[htmlAttrName]);
+    attr.$observe(htmlAttrName, changeFn);
+  }
+
+  function minChange(val) {
+    minVal = parseNumberAttrVal(val);
+    // ignore changes before model is initialized
+    if (isNumberNaN(ctrl.$modelValue)) {
+      return;
+    }
+
+    if (supportsRange) {
+      var elVal = element.val();
+      // IE11 doesn't set the el val correctly if the minVal is greater than the element value
+      if (minVal > elVal) {
+        elVal = minVal;
+        element.val(elVal);
+      }
+      ctrl.$setViewValue(elVal);
+    } else {
+      // TODO(matsko): implement validateLater to reduce number of validations
+      ctrl.$validate();
+    }
+  }
+
+  function maxChange(val) {
+    maxVal = parseNumberAttrVal(val);
+    // ignore changes before model is initialized
+    if (isNumberNaN(ctrl.$modelValue)) {
+      return;
+    }
+
+    if (supportsRange) {
+      var elVal = element.val();
+      // IE11 doesn't set the el val correctly if the maxVal is less than the element value
+      if (maxVal < elVal) {
+        element.val(maxVal);
+        // IE11 and Chrome don't set the value to the minVal when max < min
+        elVal = maxVal < minVal ? minVal : maxVal;
+      }
+      ctrl.$setViewValue(elVal);
+    } else {
+      // TODO(matsko): implement validateLater to reduce number of validations
+      ctrl.$validate();
+    }
+  }
+
+  function stepChange(val) {
+    stepVal = parseNumberAttrVal(val);
+    // ignore changes before model is initialized
+    if (isNumberNaN(ctrl.$modelValue)) {
+      return;
+    }
+
+    // Some browsers don't adjust the input value correctly, but set the stepMismatch error
+    if (supportsRange && ctrl.$viewValue !== element.val()) {
+      ctrl.$setViewValue(element.val());
+    } else {
+      // TODO(matsko): implement validateLater to reduce number of validations
+      ctrl.$validate();
+    }
+  }
+}
+
+function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
+  // Note: no badInputChecker here by purpose as `url` is only a validation
+  // in browsers, i.e. we can always read out input.value even if it is not valid!
+  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
+  stringBasedInputType(ctrl);
+
+  ctrl.$$parserName = 'url';
+  ctrl.$validators.url = function(modelValue, viewValue) {
+    var value = modelValue || viewValue;
+    return ctrl.$isEmpty(value) || URL_REGEXP.test(value);
+  };
+}
+
+function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
+  // Note: no badInputChecker here by purpose as `url` is only a validation
+  // in browsers, i.e. we can always read out input.value even if it is not valid!
+  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
+  stringBasedInputType(ctrl);
+
+  ctrl.$$parserName = 'email';
+  ctrl.$validators.email = function(modelValue, viewValue) {
+    var value = modelValue || viewValue;
+    return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);
+  };
+}
+
+function radioInputType(scope, element, attr, ctrl) {
+  var doTrim = !attr.ngTrim || trim(attr.ngTrim) !== 'false';
+  // make the name unique, if not defined
+  if (isUndefined(attr.name)) {
+    element.attr('name', nextUid());
+  }
+
+  var listener = function(ev) {
+    var value;
+    if (element[0].checked) {
+      value = attr.value;
+      if (doTrim) {
+        value = trim(value);
+      }
+      ctrl.$setViewValue(value, ev && ev.type);
+    }
+  };
+
+  element.on('click', listener);
+
+  ctrl.$render = function() {
+    var value = attr.value;
+    if (doTrim) {
+      value = trim(value);
+    }
+    element[0].checked = (value === ctrl.$viewValue);
+  };
+
+  attr.$observe('value', ctrl.$render);
+}
+
+function parseConstantExpr($parse, context, name, expression, fallback) {
+  var parseFn;
+  if (isDefined(expression)) {
+    parseFn = $parse(expression);
+    if (!parseFn.constant) {
+      throw ngModelMinErr('constexpr', 'Expected constant expression for `{0}`, but saw ' +
+                                   '`{1}`.', name, expression);
+    }
+    return parseFn(context);
+  }
+  return fallback;
+}
+
+function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) {
+  var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true);
+  var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false);
+
+  var listener = function(ev) {
+    ctrl.$setViewValue(element[0].checked, ev && ev.type);
+  };
+
+  element.on('click', listener);
+
+  ctrl.$render = function() {
+    element[0].checked = ctrl.$viewValue;
+  };
+
+  // Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false`
+  // This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert
+  // it to a boolean.
+  ctrl.$isEmpty = function(value) {
+    return value === false;
+  };
+
+  ctrl.$formatters.push(function(value) {
+    return equals(value, trueValue);
+  });
+
+  ctrl.$parsers.push(function(value) {
+    return value ? trueValue : falseValue;
+  });
+}
+
+
+/**
+ * @ngdoc directive
+ * @name textarea
+ * @restrict E
+ *
+ * @description
+ * HTML textarea element control with angular data-binding. The data-binding and validation
+ * properties of this element are exactly the same as those of the
+ * {@link ng.directive:input input element}.
+ *
+ * @param {string} ngModel Assignable angular expression to data-bind to.
+ * @param {string=} name Property name of the form under which the control is published.
+ * @param {string=} required Sets `required` validation error key if the value is not entered.
+ * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+ *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+ *    `required` when you want to data-bind to the `required` attribute.
+ * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
+ *    minlength.
+ * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
+ *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
+ *    length.
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
+ *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.
+ *    If the expression evaluates to a RegExp object, then this is used directly.
+ *    If the expression evaluates to a string, then it will be converted to a RegExp
+ *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
+ *    `new RegExp('^abc$')`.<br />
+ *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
+ *    start at the index of the last search's match, thus not taking the whole input value into
+ *    account.
+ * @param {string=} ngChange Angular expression to be executed when input changes due to user
+ *    interaction with the input element.
+ * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
+ *
+ * @knownIssue
+ *
+ * When specifying the `placeholder` attribute of `<textarea>`, Internet Explorer will temporarily
+ * insert the placeholder value as the textarea's content. If the placeholder value contains
+ * interpolation (`{{ ... }}`), an error will be logged in the console when Angular tries to update
+ * the value of the by-then-removed text node. This doesn't affect the functionality of the
+ * textarea, but can be undesirable.
+ *
+ * You can work around this Internet Explorer issue by using `ng-attr-placeholder` instead of
+ * `placeholder` on textareas, whenever you need interpolation in the placeholder value. You can
+ * find more details on `ngAttr` in the
+ * [Interpolation](guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes) section of the
+ * Developer Guide.
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name input
+ * @restrict E
+ *
+ * @description
+ * HTML input element control. When used together with {@link ngModel `ngModel`}, it provides data-binding,
+ * input state control, and validation.
+ * Input control follows HTML5 input types and polyfills the HTML5 validation behavior for older browsers.
+ *
+ * <div class="alert alert-warning">
+ * **Note:** Not every feature offered is available for all input types.
+ * Specifically, data binding and event handling via `ng-model` is unsupported for `input[file]`.
+ * </div>
+ *
+ * @param {string} ngModel Assignable angular expression to data-bind to.
+ * @param {string=} name Property name of the form under which the control is published.
+ * @param {string=} required Sets `required` validation error key if the value is not entered.
+ * @param {boolean=} ngRequired Sets `required` attribute if set to true
+ * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
+ *    minlength.
+ * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
+ *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
+ *    length.
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
+ *    value does not match a RegExp found by evaluating the Angular expression given in the attribute value.
+ *    If the expression evaluates to a RegExp object, then this is used directly.
+ *    If the expression evaluates to a string, then it will be converted to a RegExp
+ *    after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
+ *    `new RegExp('^abc$')`.<br />
+ *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
+ *    start at the index of the last search's match, thus not taking the whole input value into
+ *    account.
+ * @param {string=} ngChange Angular expression to be executed when input changes due to user
+ *    interaction with the input element.
+ * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
+ *    This parameter is ignored for input[type=password] controls, which will never trim the
+ *    input.
+ *
+ * @example
+    <example name="input-directive" module="inputExample">
+      <file name="index.html">
+       <script>
+          angular.module('inputExample', [])
+            .controller('ExampleController', ['$scope', function($scope) {
+              $scope.user = {name: 'guest', last: 'visitor'};
+            }]);
+       </script>
+       <div ng-controller="ExampleController">
+         <form name="myForm">
+           <label>
+              User name:
+              <input type="text" name="userName" ng-model="user.name" required>
+           </label>
+           <div role="alert">
+             <span class="error" ng-show="myForm.userName.$error.required">
+              Required!</span>
+           </div>
+           <label>
+              Last name:
+              <input type="text" name="lastName" ng-model="user.last"
+              ng-minlength="3" ng-maxlength="10">
+           </label>
+           <div role="alert">
+             <span class="error" ng-show="myForm.lastName.$error.minlength">
+               Too short!</span>
+             <span class="error" ng-show="myForm.lastName.$error.maxlength">
+               Too long!</span>
+           </div>
+         </form>
+         <hr>
+         <tt>user = {{user}}</tt><br/>
+         <tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br/>
+         <tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br/>
+         <tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br/>
+         <tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br/>
+         <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+         <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+         <tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br/>
+         <tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br/>
+       </div>
+      </file>
+      <file name="protractor.js" type="protractor">
+        var user = element(by.exactBinding('user'));
+        var userNameValid = element(by.binding('myForm.userName.$valid'));
+        var lastNameValid = element(by.binding('myForm.lastName.$valid'));
+        var lastNameError = element(by.binding('myForm.lastName.$error'));
+        var formValid = element(by.binding('myForm.$valid'));
+        var userNameInput = element(by.model('user.name'));
+        var userLastInput = element(by.model('user.last'));
+
+        it('should initialize to model', function() {
+          expect(user.getText()).toContain('{"name":"guest","last":"visitor"}');
+          expect(userNameValid.getText()).toContain('true');
+          expect(formValid.getText()).toContain('true');
+        });
+
+        it('should be invalid if empty when required', function() {
+          userNameInput.clear();
+          userNameInput.sendKeys('');
+
+          expect(user.getText()).toContain('{"last":"visitor"}');
+          expect(userNameValid.getText()).toContain('false');
+          expect(formValid.getText()).toContain('false');
+        });
+
+        it('should be valid if empty when min length is set', function() {
+          userLastInput.clear();
+          userLastInput.sendKeys('');
+
+          expect(user.getText()).toContain('{"name":"guest","last":""}');
+          expect(lastNameValid.getText()).toContain('true');
+          expect(formValid.getText()).toContain('true');
+        });
+
+        it('should be invalid if less than required min length', function() {
+          userLastInput.clear();
+          userLastInput.sendKeys('xx');
+
+          expect(user.getText()).toContain('{"name":"guest"}');
+          expect(lastNameValid.getText()).toContain('false');
+          expect(lastNameError.getText()).toContain('minlength');
+          expect(formValid.getText()).toContain('false');
+        });
+
+        it('should be invalid if longer than max length', function() {
+          userLastInput.clear();
+          userLastInput.sendKeys('some ridiculously long name');
+
+          expect(user.getText()).toContain('{"name":"guest"}');
+          expect(lastNameValid.getText()).toContain('false');
+          expect(lastNameError.getText()).toContain('maxlength');
+          expect(formValid.getText()).toContain('false');
+        });
+      </file>
+    </example>
+ */
+var inputDirective = ['$browser', '$sniffer', '$filter', '$parse',
+    function($browser, $sniffer, $filter, $parse) {
+  return {
+    restrict: 'E',
+    require: ['?ngModel'],
+    link: {
+      pre: function(scope, element, attr, ctrls) {
+        if (ctrls[0]) {
+          (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer,
+                                                              $browser, $filter, $parse);
+        }
+      }
+    }
+  };
+}];
+
+
+
+var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
+/**
+ * @ngdoc directive
+ * @name ngValue
+ *
+ * @description
+ * Binds the given expression to the value of the element.
+ *
+ * It is mainly used on {@link input[radio] `input[radio]`} and option elements,
+ * so that when the element is selected, the {@link ngModel `ngModel`} of that element (or its
+ * {@link select `select`} parent element) is set to the bound value. It is especially useful
+ * for dynamically generated lists using {@link ngRepeat `ngRepeat`}, as shown below.
+ *
+ * It can also be used to achieve one-way binding of a given expression to an input element
+ * such as an `input[text]` or a `textarea`, when that element does not use ngModel.
+ *
+ * @element input
+ * @param {string=} ngValue angular expression, whose value will be bound to the `value` attribute
+ * and `value` property of the element.
+ *
+ * @example
+    <example name="ngValue-directive" module="valueExample">
+      <file name="index.html">
+       <script>
+          angular.module('valueExample', [])
+            .controller('ExampleController', ['$scope', function($scope) {
+              $scope.names = ['pizza', 'unicorns', 'robots'];
+              $scope.my = { favorite: 'unicorns' };
+            }]);
+       </script>
+        <form ng-controller="ExampleController">
+          <h2>Which is your favorite?</h2>
+            <label ng-repeat="name in names" for="{{name}}">
+              {{name}}
+              <input type="radio"
+                     ng-model="my.favorite"
+                     ng-value="name"
+                     id="{{name}}"
+                     name="favorite">
+            </label>
+          <div>You chose {{my.favorite}}</div>
+        </form>
+      </file>
+      <file name="protractor.js" type="protractor">
+        var favorite = element(by.binding('my.favorite'));
+
+        it('should initialize to model', function() {
+          expect(favorite.getText()).toContain('unicorns');
+        });
+        it('should bind the values to the inputs', function() {
+          element.all(by.model('my.favorite')).get(0).click();
+          expect(favorite.getText()).toContain('pizza');
+        });
+      </file>
+    </example>
+ */
+var ngValueDirective = function() {
+  /**
+   *  inputs use the value attribute as their default value if the value property is not set.
+   *  Once the value property has been set (by adding input), it will not react to changes to
+   *  the value attribute anymore. Setting both attribute and property fixes this behavior, and
+   *  makes it possible to use ngValue as a sort of one-way bind.
+   */
+  function updateElementValue(element, attr, value) {
+    // Support: IE9 only
+    // In IE9 values are converted to string (e.g. `input.value = null` results in `input.value === 'null'`).
+    var propValue = isDefined(value) ? value : (msie === 9) ? '' : null;
+    element.prop('value', propValue);
+    attr.$set('value', value);
+  }
+
+  return {
+    restrict: 'A',
+    priority: 100,
+    compile: function(tpl, tplAttr) {
+      if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {
+        return function ngValueConstantLink(scope, elm, attr) {
+          var value = scope.$eval(attr.ngValue);
+          updateElementValue(elm, attr, value);
+        };
+      } else {
+        return function ngValueLink(scope, elm, attr) {
+          scope.$watch(attr.ngValue, function valueWatchAction(value) {
+            updateElementValue(elm, attr, value);
+          });
+        };
+      }
+    }
+  };
+};
+
+/**
+ * @ngdoc directive
+ * @name ngBind
+ * @restrict AC
+ *
+ * @description
+ * The `ngBind` attribute tells Angular to replace the text content of the specified HTML element
+ * with the value of a given expression, and to update the text content when the value of that
+ * expression changes.
+ *
+ * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
+ * `{{ expression }}` which is similar but less verbose.
+ *
+ * It is preferable to use `ngBind` instead of `{{ expression }}` if a template is momentarily
+ * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an
+ * element attribute, it makes the bindings invisible to the user while the page is loading.
+ *
+ * An alternative solution to this problem would be using the
+ * {@link ng.directive:ngCloak ngCloak} directive.
+ *
+ *
+ * @element ANY
+ * @param {expression} ngBind {@link guide/expression Expression} to evaluate.
+ *
+ * @example
+ * Enter a name in the Live Preview text box; the greeting below the text box changes instantly.
+   <example module="bindExample" name="ng-bind">
+     <file name="index.html">
+       <script>
+         angular.module('bindExample', [])
+           .controller('ExampleController', ['$scope', function($scope) {
+             $scope.name = 'Whirled';
+           }]);
+       </script>
+       <div ng-controller="ExampleController">
+         <label>Enter name: <input type="text" ng-model="name"></label><br>
+         Hello <span ng-bind="name"></span>!
+       </div>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should check ng-bind', function() {
+         var nameInput = element(by.model('name'));
+
+         expect(element(by.binding('name')).getText()).toBe('Whirled');
+         nameInput.clear();
+         nameInput.sendKeys('world');
+         expect(element(by.binding('name')).getText()).toBe('world');
+       });
+     </file>
+   </example>
+ */
+var ngBindDirective = ['$compile', function($compile) {
+  return {
+    restrict: 'AC',
+    compile: function ngBindCompile(templateElement) {
+      $compile.$$addBindingClass(templateElement);
+      return function ngBindLink(scope, element, attr) {
+        $compile.$$addBindingInfo(element, attr.ngBind);
+        element = element[0];
+        scope.$watch(attr.ngBind, function ngBindWatchAction(value) {
+          element.textContent = stringify(value);
+        });
+      };
+    }
+  };
+}];
+
+
+/**
+ * @ngdoc directive
+ * @name ngBindTemplate
+ *
+ * @description
+ * The `ngBindTemplate` directive specifies that the element
+ * text content should be replaced with the interpolation of the template
+ * in the `ngBindTemplate` attribute.
+ * Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}`
+ * expressions. This directive is needed since some HTML elements
+ * (such as TITLE and OPTION) cannot contain SPAN elements.
+ *
+ * @element ANY
+ * @param {string} ngBindTemplate template of form
+ *   <tt>{{</tt> <tt>expression</tt> <tt>}}</tt> to eval.
+ *
+ * @example
+ * Try it here: enter text in text box and watch the greeting change.
+   <example module="bindExample" name="ng-bind-template">
+     <file name="index.html">
+       <script>
+         angular.module('bindExample', [])
+           .controller('ExampleController', ['$scope', function($scope) {
+             $scope.salutation = 'Hello';
+             $scope.name = 'World';
+           }]);
+       </script>
+       <div ng-controller="ExampleController">
+        <label>Salutation: <input type="text" ng-model="salutation"></label><br>
+        <label>Name: <input type="text" ng-model="name"></label><br>
+        <pre ng-bind-template="{{salutation}} {{name}}!"></pre>
+       </div>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should check ng-bind', function() {
+         var salutationElem = element(by.binding('salutation'));
+         var salutationInput = element(by.model('salutation'));
+         var nameInput = element(by.model('name'));
+
+         expect(salutationElem.getText()).toBe('Hello World!');
+
+         salutationInput.clear();
+         salutationInput.sendKeys('Greetings');
+         nameInput.clear();
+         nameInput.sendKeys('user');
+
+         expect(salutationElem.getText()).toBe('Greetings user!');
+       });
+     </file>
+   </example>
+ */
+var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate, $compile) {
+  return {
+    compile: function ngBindTemplateCompile(templateElement) {
+      $compile.$$addBindingClass(templateElement);
+      return function ngBindTemplateLink(scope, element, attr) {
+        var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate));
+        $compile.$$addBindingInfo(element, interpolateFn.expressions);
+        element = element[0];
+        attr.$observe('ngBindTemplate', function(value) {
+          element.textContent = isUndefined(value) ? '' : value;
+        });
+      };
+    }
+  };
+}];
+
+
+/**
+ * @ngdoc directive
+ * @name ngBindHtml
+ *
+ * @description
+ * Evaluates the expression and inserts the resulting HTML into the element in a secure way. By default,
+ * the resulting HTML content will be sanitized using the {@link ngSanitize.$sanitize $sanitize} service.
+ * To utilize this functionality, ensure that `$sanitize` is available, for example, by including {@link
+ * ngSanitize} in your module's dependencies (not in core Angular). In order to use {@link ngSanitize}
+ * in your module's dependencies, you need to include "angular-sanitize.js" in your application.
+ *
+ * You may also bypass sanitization for values you know are safe. To do so, bind to
+ * an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}.  See the example
+ * under {@link ng.$sce#show-me-an-example-using-sce- Strict Contextual Escaping (SCE)}.
+ *
+ * Note: If a `$sanitize` service is unavailable and the bound value isn't explicitly trusted, you
+ * will have an exception (instead of an exploit.)
+ *
+ * @element ANY
+ * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
+ *
+ * @example
+
+   <example module="bindHtmlExample" deps="angular-sanitize.js" name="ng-bind-html">
+     <file name="index.html">
+       <div ng-controller="ExampleController">
+        <p ng-bind-html="myHTML"></p>
+       </div>
+     </file>
+
+     <file name="script.js">
+       angular.module('bindHtmlExample', ['ngSanitize'])
+         .controller('ExampleController', ['$scope', function($scope) {
+           $scope.myHTML =
+              'I am an <code>HTML</code>string with ' +
+              '<a href="#">links!</a> and other <em>stuff</em>';
+         }]);
+     </file>
+
+     <file name="protractor.js" type="protractor">
+       it('should check ng-bind-html', function() {
+         expect(element(by.binding('myHTML')).getText()).toBe(
+             'I am an HTMLstring with links! and other stuff');
+       });
+     </file>
+   </example>
+ */
+var ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) {
+  return {
+    restrict: 'A',
+    compile: function ngBindHtmlCompile(tElement, tAttrs) {
+      var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml);
+      var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function sceValueOf(val) {
+        // Unwrap the value to compare the actual inner safe value, not the wrapper object.
+        return $sce.valueOf(val);
+      });
+      $compile.$$addBindingClass(tElement);
+
+      return function ngBindHtmlLink(scope, element, attr) {
+        $compile.$$addBindingInfo(element, attr.ngBindHtml);
+
+        scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {
+          // The watched value is the unwrapped value. To avoid re-escaping, use the direct getter.
+          var value = ngBindHtmlGetter(scope);
+          element.html($sce.getTrustedHtml(value) || '');
+        });
+      };
+    }
+  };
+}];
+
+/**
+ * @ngdoc directive
+ * @name ngChange
+ *
+ * @description
+ * Evaluate the given expression when the user changes the input.
+ * The expression is evaluated immediately, unlike the JavaScript onchange event
+ * which only triggers at the end of a change (usually, when the user leaves the
+ * form element or presses the return key).
+ *
+ * The `ngChange` expression is only evaluated when a change in the input value causes
+ * a new value to be committed to the model.
+ *
+ * It will not be evaluated:
+ * * if the value returned from the `$parsers` transformation pipeline has not changed
+ * * if the input has continued to be invalid since the model will stay `null`
+ * * if the model is changed programmatically and not by a change to the input value
+ *
+ *
+ * Note, this directive requires `ngModel` to be present.
+ *
+ * @element input
+ * @param {expression} ngChange {@link guide/expression Expression} to evaluate upon change
+ * in input value.
+ *
+ * @example
+ * <example name="ngChange-directive" module="changeExample">
+ *   <file name="index.html">
+ *     <script>
+ *       angular.module('changeExample', [])
+ *         .controller('ExampleController', ['$scope', function($scope) {
+ *           $scope.counter = 0;
+ *           $scope.change = function() {
+ *             $scope.counter++;
+ *           };
+ *         }]);
+ *     </script>
+ *     <div ng-controller="ExampleController">
+ *       <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
+ *       <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
+ *       <label for="ng-change-example2">Confirmed</label><br />
+ *       <tt>debug = {{confirmed}}</tt><br/>
+ *       <tt>counter = {{counter}}</tt><br/>
+ *     </div>
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+ *     var counter = element(by.binding('counter'));
+ *     var debug = element(by.binding('confirmed'));
+ *
+ *     it('should evaluate the expression if changing from view', function() {
+ *       expect(counter.getText()).toContain('0');
+ *
+ *       element(by.id('ng-change-example1')).click();
+ *
+ *       expect(counter.getText()).toContain('1');
+ *       expect(debug.getText()).toContain('true');
+ *     });
+ *
+ *     it('should not evaluate the expression if changing from model', function() {
+ *       element(by.id('ng-change-example2')).click();
+
+ *       expect(counter.getText()).toContain('0');
+ *       expect(debug.getText()).toContain('true');
+ *     });
+ *   </file>
+ * </example>
+ */
+var ngChangeDirective = valueFn({
+  restrict: 'A',
+  require: 'ngModel',
+  link: function(scope, element, attr, ctrl) {
+    ctrl.$viewChangeListeners.push(function() {
+      scope.$eval(attr.ngChange);
+    });
+  }
+});
+
+/* exported
+  ngClassDirective,
+  ngClassEvenDirective,
+  ngClassOddDirective
+*/
+
+function classDirective(name, selector) {
+  name = 'ngClass' + name;
+  var indexWatchExpression;
+
+  return ['$parse', function($parse) {
+    return {
+      restrict: 'AC',
+      link: function(scope, element, attr) {
+        var expression = attr[name].trim();
+        var isOneTime = (expression.charAt(0) === ':') && (expression.charAt(1) === ':');
+
+        var watchInterceptor = isOneTime ? toFlatValue : toClassString;
+        var watchExpression = $parse(expression, watchInterceptor);
+        var watchAction = isOneTime ? ngClassOneTimeWatchAction : ngClassWatchAction;
+
+        var classCounts = element.data('$classCounts');
+        var oldModulo = true;
+        var oldClassString;
+
+        if (!classCounts) {
+          // Use createMap() to prevent class assumptions involving property
+          // names in Object.prototype
+          classCounts = createMap();
+          element.data('$classCounts', classCounts);
+        }
+
+        if (name !== 'ngClass') {
+          if (!indexWatchExpression) {
+            indexWatchExpression = $parse('$index', function moduloTwo($index) {
+              // eslint-disable-next-line no-bitwise
+              return $index & 1;
+            });
+          }
+
+          scope.$watch(indexWatchExpression, ngClassIndexWatchAction);
+        }
+
+        scope.$watch(watchExpression, watchAction, isOneTime);
+
+        function addClasses(classString) {
+          classString = digestClassCounts(split(classString), 1);
+          attr.$addClass(classString);
+        }
+
+        function removeClasses(classString) {
+          classString = digestClassCounts(split(classString), -1);
+          attr.$removeClass(classString);
+        }
+
+        function updateClasses(oldClassString, newClassString) {
+          var oldClassArray = split(oldClassString);
+          var newClassArray = split(newClassString);
+
+          var toRemoveArray = arrayDifference(oldClassArray, newClassArray);
+          var toAddArray = arrayDifference(newClassArray, oldClassArray);
+
+          var toRemoveString = digestClassCounts(toRemoveArray, -1);
+          var toAddString = digestClassCounts(toAddArray, 1);
+
+          attr.$addClass(toAddString);
+          attr.$removeClass(toRemoveString);
+        }
+
+        function digestClassCounts(classArray, count) {
+          var classesToUpdate = [];
+
+          forEach(classArray, function(className) {
+            if (count > 0 || classCounts[className]) {
+              classCounts[className] = (classCounts[className] || 0) + count;
+              if (classCounts[className] === +(count > 0)) {
+                classesToUpdate.push(className);
+              }
+            }
+          });
+
+          return classesToUpdate.join(' ');
+        }
+
+        function ngClassIndexWatchAction(newModulo) {
+          // This watch-action should run before the `ngClass[OneTime]WatchAction()`, thus it
+          // adds/removes `oldClassString`. If the `ngClass` expression has changed as well, the
+          // `ngClass[OneTime]WatchAction()` will update the classes.
+          if (newModulo === selector) {
+            addClasses(oldClassString);
+          } else {
+            removeClasses(oldClassString);
+          }
+
+          oldModulo = newModulo;
+        }
+
+        function ngClassOneTimeWatchAction(newClassValue) {
+          var newClassString = toClassString(newClassValue);
+
+          if (newClassString !== oldClassString) {
+            ngClassWatchAction(newClassString);
+          }
+        }
+
+        function ngClassWatchAction(newClassString) {
+          if (oldModulo === selector) {
+            updateClasses(oldClassString, newClassString);
+          }
+
+          oldClassString = newClassString;
+        }
+      }
+    };
+  }];
+
+  // Helpers
+  function arrayDifference(tokens1, tokens2) {
+    if (!tokens1 || !tokens1.length) return [];
+    if (!tokens2 || !tokens2.length) return tokens1;
+
+    var values = [];
+
+    outer:
+    for (var i = 0; i < tokens1.length; i++) {
+      var token = tokens1[i];
+      for (var j = 0; j < tokens2.length; j++) {
+        if (token === tokens2[j]) continue outer;
+      }
+      values.push(token);
+    }
+
+    return values;
+  }
+
+  function split(classString) {
+    return classString && classString.split(' ');
+  }
+
+  function toClassString(classValue) {
+    var classString = classValue;
+
+    if (isArray(classValue)) {
+      classString = classValue.map(toClassString).join(' ');
+    } else if (isObject(classValue)) {
+      classString = Object.keys(classValue).
+        filter(function(key) { return classValue[key]; }).
+        join(' ');
+    }
+
+    return classString;
+  }
+
+  function toFlatValue(classValue) {
+    var flatValue = classValue;
+
+    if (isArray(classValue)) {
+      flatValue = classValue.map(toFlatValue);
+    } else if (isObject(classValue)) {
+      var hasUndefined = false;
+
+      flatValue = Object.keys(classValue).filter(function(key) {
+        var value = classValue[key];
+
+        if (!hasUndefined && isUndefined(value)) {
+          hasUndefined = true;
+        }
+
+        return value;
+      });
+
+      if (hasUndefined) {
+        // Prevent the `oneTimeLiteralWatchInterceptor` from unregistering
+        // the watcher, by including at least one `undefined` value.
+        flatValue.push(undefined);
+      }
+    }
+
+    return flatValue;
+  }
+}
+
+/**
+ * @ngdoc directive
+ * @name ngClass
+ * @restrict AC
+ *
+ * @description
+ * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding
+ * an expression that represents all classes to be added.
+ *
+ * The directive operates in three different ways, depending on which of three types the expression
+ * evaluates to:
+ *
+ * 1. If the expression evaluates to a string, the string should be one or more space-delimited class
+ * names.
+ *
+ * 2. If the expression evaluates to an object, then for each key-value pair of the
+ * object with a truthy value the corresponding key is used as a class name.
+ *
+ * 3. If the expression evaluates to an array, each element of the array should either be a string as in
+ * type 1 or an object as in type 2. This means that you can mix strings and objects together in an array
+ * to give you more control over what CSS classes appear. See the code below for an example of this.
+ *
+ *
+ * The directive won't add duplicate classes if a particular class was already set.
+ *
+ * When the expression changes, the previously added classes are removed and only then are the
+ * new classes added.
+ *
+ * @knownIssue
+ * You should not use {@link guide/interpolation interpolation} in the value of the `class`
+ * attribute, when using the `ngClass` directive on the same element.
+ * See {@link guide/interpolation#known-issues here} for more info.
+ *
+ * @animations
+ * | Animation                        | Occurs                              |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#addClass addClass}       | just before the class is applied to the element   |
+ * | {@link ng.$animate#removeClass removeClass} | just before the class is removed from the element |
+ *
+ * @element ANY
+ * @param {expression} ngClass {@link guide/expression Expression} to eval. The result
+ *   of the evaluation can be a string representing space delimited class
+ *   names, an array, or a map of class names to boolean values. In the case of a map, the
+ *   names of the properties whose values are truthy will be added as css classes to the
+ *   element.
+ *
+ * @example Example that demonstrates basic bindings via ngClass directive.
+   <example name="ng-class">
+     <file name="index.html">
+       <p ng-class="{strike: deleted, bold: important, 'has-error': error}">Map Syntax Example</p>
+       <label>
+          <input type="checkbox" ng-model="deleted">
+          deleted (apply "strike" class)
+       </label><br>
+       <label>
+          <input type="checkbox" ng-model="important">
+          important (apply "bold" class)
+       </label><br>
+       <label>
+          <input type="checkbox" ng-model="error">
+          error (apply "has-error" class)
+       </label>
+       <hr>
+       <p ng-class="style">Using String Syntax</p>
+       <input type="text" ng-model="style"
+              placeholder="Type: bold strike red" aria-label="Type: bold strike red">
+       <hr>
+       <p ng-class="[style1, style2, style3]">Using Array Syntax</p>
+       <input ng-model="style1"
+              placeholder="Type: bold, strike or red" aria-label="Type: bold, strike or red"><br>
+       <input ng-model="style2"
+              placeholder="Type: bold, strike or red" aria-label="Type: bold, strike or red 2"><br>
+       <input ng-model="style3"
+              placeholder="Type: bold, strike or red" aria-label="Type: bold, strike or red 3"><br>
+       <hr>
+       <p ng-class="[style4, {orange: warning}]">Using Array and Map Syntax</p>
+       <input ng-model="style4" placeholder="Type: bold, strike" aria-label="Type: bold, strike"><br>
+       <label><input type="checkbox" ng-model="warning"> warning (apply "orange" class)</label>
+     </file>
+     <file name="style.css">
+       .strike {
+           text-decoration: line-through;
+       }
+       .bold {
+           font-weight: bold;
+       }
+       .red {
+           color: red;
+       }
+       .has-error {
+           color: red;
+           background-color: yellow;
+       }
+       .orange {
+           color: orange;
+       }
+     </file>
+     <file name="protractor.js" type="protractor">
+       var ps = element.all(by.css('p'));
+
+       it('should let you toggle the class', function() {
+
+         expect(ps.first().getAttribute('class')).not.toMatch(/bold/);
+         expect(ps.first().getAttribute('class')).not.toMatch(/has-error/);
+
+         element(by.model('important')).click();
+         expect(ps.first().getAttribute('class')).toMatch(/bold/);
+
+         element(by.model('error')).click();
+         expect(ps.first().getAttribute('class')).toMatch(/has-error/);
+       });
+
+       it('should let you toggle string example', function() {
+         expect(ps.get(1).getAttribute('class')).toBe('');
+         element(by.model('style')).clear();
+         element(by.model('style')).sendKeys('red');
+         expect(ps.get(1).getAttribute('class')).toBe('red');
+       });
+
+       it('array example should have 3 classes', function() {
+         expect(ps.get(2).getAttribute('class')).toBe('');
+         element(by.model('style1')).sendKeys('bold');
+         element(by.model('style2')).sendKeys('strike');
+         element(by.model('style3')).sendKeys('red');
+         expect(ps.get(2).getAttribute('class')).toBe('bold strike red');
+       });
+
+       it('array with map example should have 2 classes', function() {
+         expect(ps.last().getAttribute('class')).toBe('');
+         element(by.model('style4')).sendKeys('bold');
+         element(by.model('warning')).click();
+         expect(ps.last().getAttribute('class')).toBe('bold orange');
+       });
+     </file>
+   </example>
+
+   ## Animations
+
+   The example below demonstrates how to perform animations using ngClass.
+
+   <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-class">
+     <file name="index.html">
+      <input id="setbtn" type="button" value="set" ng-click="myVar='my-class'">
+      <input id="clearbtn" type="button" value="clear" ng-click="myVar=''">
+      <br>
+      <span class="base-class" ng-class="myVar">Sample Text</span>
+     </file>
+     <file name="style.css">
+       .base-class {
+         transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
+       }
+
+       .base-class.my-class {
+         color: red;
+         font-size:3em;
+       }
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should check ng-class', function() {
+         expect(element(by.css('.base-class')).getAttribute('class')).not.
+           toMatch(/my-class/);
+
+         element(by.id('setbtn')).click();
+
+         expect(element(by.css('.base-class')).getAttribute('class')).
+           toMatch(/my-class/);
+
+         element(by.id('clearbtn')).click();
+
+         expect(element(by.css('.base-class')).getAttribute('class')).not.
+           toMatch(/my-class/);
+       });
+     </file>
+   </example>
+
+
+   ## ngClass and pre-existing CSS3 Transitions/Animations
+   The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.
+   Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder
+   any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure
+   to view the step by step details of {@link $animate#addClass $animate.addClass} and
+   {@link $animate#removeClass $animate.removeClass}.
+ */
+var ngClassDirective = classDirective('', true);
+
+/**
+ * @ngdoc directive
+ * @name ngClassOdd
+ * @restrict AC
+ *
+ * @description
+ * The `ngClassOdd` and `ngClassEven` directives work exactly as
+ * {@link ng.directive:ngClass ngClass}, except they work in
+ * conjunction with `ngRepeat` and take effect only on odd (even) rows.
+ *
+ * This directive can be applied only within the scope of an
+ * {@link ng.directive:ngRepeat ngRepeat}.
+ *
+ * @element ANY
+ * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result
+ *   of the evaluation can be a string representing space delimited class names or an array.
+ *
+ * @example
+   <example name="ng-class-odd">
+     <file name="index.html">
+        <ol ng-init="names=['John', 'Mary', 'Cate', 'Suz']">
+          <li ng-repeat="name in names">
+           <span ng-class-odd="'odd'" ng-class-even="'even'">
+             {{name}}
+           </span>
+          </li>
+        </ol>
+     </file>
+     <file name="style.css">
+       .odd {
+         color: red;
+       }
+       .even {
+         color: blue;
+       }
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should check ng-class-odd and ng-class-even', function() {
+         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
+           toMatch(/odd/);
+         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
+           toMatch(/even/);
+       });
+     </file>
+   </example>
+ */
+var ngClassOddDirective = classDirective('Odd', 0);
+
+/**
+ * @ngdoc directive
+ * @name ngClassEven
+ * @restrict AC
+ *
+ * @description
+ * The `ngClassOdd` and `ngClassEven` directives work exactly as
+ * {@link ng.directive:ngClass ngClass}, except they work in
+ * conjunction with `ngRepeat` and take effect only on odd (even) rows.
+ *
+ * This directive can be applied only within the scope of an
+ * {@link ng.directive:ngRepeat ngRepeat}.
+ *
+ * @element ANY
+ * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The
+ *   result of the evaluation can be a string representing space delimited class names or an array.
+ *
+ * @example
+   <example name="ng-class-even">
+     <file name="index.html">
+        <ol ng-init="names=['John', 'Mary', 'Cate', 'Suz']">
+          <li ng-repeat="name in names">
+           <span ng-class-odd="'odd'" ng-class-even="'even'">
+             {{name}} &nbsp; &nbsp; &nbsp;
+           </span>
+          </li>
+        </ol>
+     </file>
+     <file name="style.css">
+       .odd {
+         color: red;
+       }
+       .even {
+         color: blue;
+       }
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should check ng-class-odd and ng-class-even', function() {
+         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
+           toMatch(/odd/);
+         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
+           toMatch(/even/);
+       });
+     </file>
+   </example>
+ */
+var ngClassEvenDirective = classDirective('Even', 1);
+
+/**
+ * @ngdoc directive
+ * @name ngCloak
+ * @restrict AC
+ *
+ * @description
+ * The `ngCloak` directive is used to prevent the Angular html template from being briefly
+ * displayed by the browser in its raw (uncompiled) form while your application is loading. Use this
+ * directive to avoid the undesirable flicker effect caused by the html template display.
+ *
+ * The directive can be applied to the `<body>` element, but the preferred usage is to apply
+ * multiple `ngCloak` directives to small portions of the page to permit progressive rendering
+ * of the browser view.
+ *
+ * `ngCloak` works in cooperation with the following css rule embedded within `angular.js` and
+ * `angular.min.js`.
+ * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).
+ *
+ * ```css
+ * [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
+ *   display: none !important;
+ * }
+ * ```
+ *
+ * When this css rule is loaded by the browser, all html elements (including their children) that
+ * are tagged with the `ngCloak` directive are hidden. When Angular encounters this directive
+ * during the compilation of the template it deletes the `ngCloak` element attribute, making
+ * the compiled element visible.
+ *
+ * For the best result, the `angular.js` script must be loaded in the head section of the html
+ * document; alternatively, the css rule above must be included in the external stylesheet of the
+ * application.
+ *
+ * @element ANY
+ *
+ * @example
+   <example name="ng-cloak">
+     <file name="index.html">
+        <div id="template1" ng-cloak>{{ 'hello' }}</div>
+        <div id="template2" class="ng-cloak">{{ 'world' }}</div>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should remove the template directive and css class', function() {
+         expect($('#template1').getAttribute('ng-cloak')).
+           toBeNull();
+         expect($('#template2').getAttribute('ng-cloak')).
+           toBeNull();
+       });
+     </file>
+   </example>
+ *
+ */
+var ngCloakDirective = ngDirective({
+  compile: function(element, attr) {
+    attr.$set('ngCloak', undefined);
+    element.removeClass('ng-cloak');
+  }
+});
+
+/**
+ * @ngdoc directive
+ * @name ngController
+ *
+ * @description
+ * The `ngController` directive attaches a controller class to the view. This is a key aspect of how angular
+ * supports the principles behind the Model-View-Controller design pattern.
+ *
+ * MVC components in angular:
+ *
+ * * Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties
+ *   are accessed through bindings.
+ * * View — The template (HTML with data bindings) that is rendered into the View.
+ * * Controller — The `ngController` directive specifies a Controller class; the class contains business
+ *   logic behind the application to decorate the scope with functions and values
+ *
+ * Note that you can also attach controllers to the DOM by declaring it in a route definition
+ * via the {@link ngRoute.$route $route} service. A common mistake is to declare the controller
+ * again using `ng-controller` in the template itself.  This will cause the controller to be attached
+ * and executed twice.
+ *
+ * @element ANY
+ * @scope
+ * @priority 500
+ * @param {expression} ngController Name of a constructor function registered with the current
+ * {@link ng.$controllerProvider $controllerProvider} or an {@link guide/expression expression}
+ * that on the current scope evaluates to a constructor function.
+ *
+ * The controller instance can be published into a scope property by specifying
+ * `ng-controller="as propertyName"`.
+ *
+ * If the current `$controllerProvider` is configured to use globals (via
+ * {@link ng.$controllerProvider#allowGlobals `$controllerProvider.allowGlobals()` }), this may
+ * also be the name of a globally accessible constructor function (deprecated, not recommended).
+ *
+ * @example
+ * Here is a simple form for editing user contact information. Adding, removing, clearing, and
+ * greeting are methods declared on the controller (see source tab). These methods can
+ * easily be called from the angular markup. Any changes to the data are automatically reflected
+ * in the View without the need for a manual update.
+ *
+ * Two different declaration styles are included below:
+ *
+ * * one binds methods and properties directly onto the controller using `this`:
+ * `ng-controller="SettingsController1 as settings"`
+ * * one injects `$scope` into the controller:
+ * `ng-controller="SettingsController2"`
+ *
+ * The second option is more common in the Angular community, and is generally used in boilerplates
+ * and in this guide. However, there are advantages to binding properties directly to the controller
+ * and avoiding scope.
+ *
+ * * Using `controller as` makes it obvious which controller you are accessing in the template when
+ * multiple controllers apply to an element.
+ * * If you are writing your controllers as classes you have easier access to the properties and
+ * methods, which will appear on the scope, from inside the controller code.
+ * * Since there is always a `.` in the bindings, you don't have to worry about prototypal
+ * inheritance masking primitives.
+ *
+ * This example demonstrates the `controller as` syntax.
+ *
+ * <example name="ngControllerAs" module="controllerAsExample">
+ *   <file name="index.html">
+ *    <div id="ctrl-as-exmpl" ng-controller="SettingsController1 as settings">
+ *      <label>Name: <input type="text" ng-model="settings.name"/></label>
+ *      <button ng-click="settings.greet()">greet</button><br/>
+ *      Contact:
+ *      <ul>
+ *        <li ng-repeat="contact in settings.contacts">
+ *          <select ng-model="contact.type" aria-label="Contact method" id="select_{{$index}}">
+ *             <option>phone</option>
+ *             <option>email</option>
+ *          </select>
+ *          <input type="text" ng-model="contact.value" aria-labelledby="select_{{$index}}" />
+ *          <button ng-click="settings.clearContact(contact)">clear</button>
+ *          <button ng-click="settings.removeContact(contact)" aria-label="Remove">X</button>
+ *        </li>
+ *        <li><button ng-click="settings.addContact()">add</button></li>
+ *     </ul>
+ *    </div>
+ *   </file>
+ *   <file name="app.js">
+ *    angular.module('controllerAsExample', [])
+ *      .controller('SettingsController1', SettingsController1);
+ *
+ *    function SettingsController1() {
+ *      this.name = 'John Smith';
+ *      this.contacts = [
+ *        {type: 'phone', value: '408 555 1212'},
+ *        {type: 'email', value: 'john.smith@example.org'}
+ *      ];
+ *    }
+ *
+ *    SettingsController1.prototype.greet = function() {
+ *      alert(this.name);
+ *    };
+ *
+ *    SettingsController1.prototype.addContact = function() {
+ *      this.contacts.push({type: 'email', value: 'yourname@example.org'});
+ *    };
+ *
+ *    SettingsController1.prototype.removeContact = function(contactToRemove) {
+ *     var index = this.contacts.indexOf(contactToRemove);
+ *      this.contacts.splice(index, 1);
+ *    };
+ *
+ *    SettingsController1.prototype.clearContact = function(contact) {
+ *      contact.type = 'phone';
+ *      contact.value = '';
+ *    };
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+ *     it('should check controller as', function() {
+ *       var container = element(by.id('ctrl-as-exmpl'));
+ *         expect(container.element(by.model('settings.name'))
+ *           .getAttribute('value')).toBe('John Smith');
+ *
+ *       var firstRepeat =
+ *           container.element(by.repeater('contact in settings.contacts').row(0));
+ *       var secondRepeat =
+ *           container.element(by.repeater('contact in settings.contacts').row(1));
+ *
+ *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
+ *           .toBe('408 555 1212');
+ *
+ *       expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
+ *           .toBe('john.smith@example.org');
+ *
+ *       firstRepeat.element(by.buttonText('clear')).click();
+ *
+ *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
+ *           .toBe('');
+ *
+ *       container.element(by.buttonText('add')).click();
+ *
+ *       expect(container.element(by.repeater('contact in settings.contacts').row(2))
+ *           .element(by.model('contact.value'))
+ *           .getAttribute('value'))
+ *           .toBe('yourname@example.org');
+ *     });
+ *   </file>
+ * </example>
+ *
+ * This example demonstrates the "attach to `$scope`" style of controller.
+ *
+ * <example name="ngController" module="controllerExample">
+ *  <file name="index.html">
+ *   <div id="ctrl-exmpl" ng-controller="SettingsController2">
+ *     <label>Name: <input type="text" ng-model="name"/></label>
+ *     <button ng-click="greet()">greet</button><br/>
+ *     Contact:
+ *     <ul>
+ *       <li ng-repeat="contact in contacts">
+ *         <select ng-model="contact.type" id="select_{{$index}}">
+ *            <option>phone</option>
+ *            <option>email</option>
+ *         </select>
+ *         <input type="text" ng-model="contact.value" aria-labelledby="select_{{$index}}" />
+ *         <button ng-click="clearContact(contact)">clear</button>
+ *         <button ng-click="removeContact(contact)">X</button>
+ *       </li>
+ *       <li>[ <button ng-click="addContact()">add</button> ]</li>
+ *    </ul>
+ *   </div>
+ *  </file>
+ *  <file name="app.js">
+ *   angular.module('controllerExample', [])
+ *     .controller('SettingsController2', ['$scope', SettingsController2]);
+ *
+ *   function SettingsController2($scope) {
+ *     $scope.name = 'John Smith';
+ *     $scope.contacts = [
+ *       {type:'phone', value:'408 555 1212'},
+ *       {type:'email', value:'john.smith@example.org'}
+ *     ];
+ *
+ *     $scope.greet = function() {
+ *       alert($scope.name);
+ *     };
+ *
+ *     $scope.addContact = function() {
+ *       $scope.contacts.push({type:'email', value:'yourname@example.org'});
+ *     };
+ *
+ *     $scope.removeContact = function(contactToRemove) {
+ *       var index = $scope.contacts.indexOf(contactToRemove);
+ *       $scope.contacts.splice(index, 1);
+ *     };
+ *
+ *     $scope.clearContact = function(contact) {
+ *       contact.type = 'phone';
+ *       contact.value = '';
+ *     };
+ *   }
+ *  </file>
+ *  <file name="protractor.js" type="protractor">
+ *    it('should check controller', function() {
+ *      var container = element(by.id('ctrl-exmpl'));
+ *
+ *      expect(container.element(by.model('name'))
+ *          .getAttribute('value')).toBe('John Smith');
+ *
+ *      var firstRepeat =
+ *          container.element(by.repeater('contact in contacts').row(0));
+ *      var secondRepeat =
+ *          container.element(by.repeater('contact in contacts').row(1));
+ *
+ *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
+ *          .toBe('408 555 1212');
+ *      expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
+ *          .toBe('john.smith@example.org');
+ *
+ *      firstRepeat.element(by.buttonText('clear')).click();
+ *
+ *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
+ *          .toBe('');
+ *
+ *      container.element(by.buttonText('add')).click();
+ *
+ *      expect(container.element(by.repeater('contact in contacts').row(2))
+ *          .element(by.model('contact.value'))
+ *          .getAttribute('value'))
+ *          .toBe('yourname@example.org');
+ *    });
+ *  </file>
+ *</example>
+
+ */
+var ngControllerDirective = [function() {
+  return {
+    restrict: 'A',
+    scope: true,
+    controller: '@',
+    priority: 500
+  };
+}];
+
+/**
+ * @ngdoc directive
+ * @name ngCsp
+ *
+ * @restrict A
+ * @element ANY
+ * @description
+ *
+ * Angular has some features that can conflict with certain restrictions that are applied when using
+ * [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) rules.
+ *
+ * If you intend to implement CSP with these rules then you must tell Angular not to use these
+ * features.
+ *
+ * This is necessary when developing things like Google Chrome Extensions or Universal Windows Apps.
+ *
+ *
+ * The following default rules in CSP affect Angular:
+ *
+ * * The use of `eval()`, `Function(string)` and similar functions to dynamically create and execute
+ * code from strings is forbidden. Angular makes use of this in the {@link $parse} service to
+ * provide a 30% increase in the speed of evaluating Angular expressions. (This CSP rule can be
+ * disabled with the CSP keyword `unsafe-eval`, but it is generally not recommended as it would
+ * weaken the protections offered by CSP.)
+ *
+ * * The use of inline resources, such as inline `<script>` and `<style>` elements, are forbidden.
+ * This prevents apps from injecting custom styles directly into the document. Angular makes use of
+ * this to include some CSS rules (e.g. {@link ngCloak} and {@link ngHide}). To make these
+ * directives work when a CSP rule is blocking inline styles, you must link to the `angular-csp.css`
+ * in your HTML manually. (This CSP rule can be disabled with the CSP keyword `unsafe-inline`, but
+ * it is generally not recommended as it would weaken the protections offered by CSP.)
+ *
+ * If you do not provide `ngCsp` then Angular tries to autodetect if CSP is blocking dynamic code
+ * creation from strings (e.g., `unsafe-eval` not specified in CSP header) and automatically
+ * deactivates this feature in the {@link $parse} service. This autodetection, however, triggers a
+ * CSP error to be logged in the console:
+ *
+ * ```
+ * Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of
+ * script in the following Content Security Policy directive: "default-src 'self'". Note that
+ * 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
+ * ```
+ *
+ * This error is harmless but annoying. To prevent the error from showing up, put the `ngCsp`
+ * directive on an element of the HTML document that appears before the `<script>` tag that loads
+ * the `angular.js` file.
+ *
+ * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.*
+ *
+ * You can specify which of the CSP related Angular features should be deactivated by providing
+ * a value for the `ng-csp` attribute. The options are as follows:
+ *
+ * * no-inline-style: this stops Angular from injecting CSS styles into the DOM
+ *
+ * * no-unsafe-eval: this stops Angular from optimizing $parse with unsafe eval of strings
+ *
+ * You can use these values in the following combinations:
+ *
+ *
+ * * No declaration means that Angular will assume that you can do inline styles, but it will do
+ * a runtime check for unsafe-eval. E.g. `<body>`. This is backwardly compatible with previous
+ * versions of Angular.
+ *
+ * * A simple `ng-csp` (or `data-ng-csp`) attribute will tell Angular to deactivate both inline
+ * styles and unsafe eval. E.g. `<body ng-csp>`. This is backwardly compatible with previous
+ * versions of Angular.
+ *
+ * * Specifying only `no-unsafe-eval` tells Angular that we must not use eval, but that we can
+ * inject inline styles. E.g. `<body ng-csp="no-unsafe-eval">`.
+ *
+ * * Specifying only `no-inline-style` tells Angular that we must not inject styles, but that we can
+ * run eval - no automatic check for unsafe eval will occur. E.g. `<body ng-csp="no-inline-style">`
+ *
+ * * Specifying both `no-unsafe-eval` and `no-inline-style` tells Angular that we must not inject
+ * styles nor use eval, which is the same as an empty: ng-csp.
+ * E.g.`<body ng-csp="no-inline-style;no-unsafe-eval">`
+ *
+ * @example
+ * This example shows how to apply the `ngCsp` directive to the `html` tag.
+   ```html
+     <!doctype html>
+     <html ng-app ng-csp>
+     ...
+     ...
+     </html>
+   ```
+  * @example
+      <!-- Note: the `.csp` suffix in the example name triggers CSP mode in our http server! -->
+      <example name="example.csp" module="cspExample" ng-csp="true">
+        <file name="index.html">
+          <div ng-controller="MainController as ctrl">
+            <div>
+              <button ng-click="ctrl.inc()" id="inc">Increment</button>
+              <span id="counter">
+                {{ctrl.counter}}
+              </span>
+            </div>
+
+            <div>
+              <button ng-click="ctrl.evil()" id="evil">Evil</button>
+              <span id="evilError">
+                {{ctrl.evilError}}
+              </span>
+            </div>
+          </div>
+        </file>
+        <file name="script.js">
+           angular.module('cspExample', [])
+             .controller('MainController', function MainController() {
+                this.counter = 0;
+                this.inc = function() {
+                  this.counter++;
+                };
+                this.evil = function() {
+                  try {
+                    eval('1+2'); // eslint-disable-line no-eval
+                  } catch (e) {
+                    this.evilError = e.message;
+                  }
+                };
+              });
+        </file>
+        <file name="protractor.js" type="protractor">
+          var util, webdriver;
+
+          var incBtn = element(by.id('inc'));
+          var counter = element(by.id('counter'));
+          var evilBtn = element(by.id('evil'));
+          var evilError = element(by.id('evilError'));
+
+          function getAndClearSevereErrors() {
+            return browser.manage().logs().get('browser').then(function(browserLog) {
+              return browserLog.filter(function(logEntry) {
+                return logEntry.level.value > webdriver.logging.Level.WARNING.value;
+              });
+            });
+          }
+
+          function clearErrors() {
+            getAndClearSevereErrors();
+          }
+
+          function expectNoErrors() {
+            getAndClearSevereErrors().then(function(filteredLog) {
+              expect(filteredLog.length).toEqual(0);
+              if (filteredLog.length) {
+                console.log('browser console errors: ' + util.inspect(filteredLog));
+              }
+            });
+          }
+
+          function expectError(regex) {
+            getAndClearSevereErrors().then(function(filteredLog) {
+              var found = false;
+              filteredLog.forEach(function(log) {
+                if (log.message.match(regex)) {
+                  found = true;
+                }
+              });
+              if (!found) {
+                throw new Error('expected an error that matches ' + regex);
+              }
+            });
+          }
+
+          beforeEach(function() {
+            util = require('util');
+            webdriver = require('selenium-webdriver');
+          });
+
+          // For now, we only test on Chrome,
+          // as Safari does not load the page with Protractor's injected scripts,
+          // and Firefox webdriver always disables content security policy (#6358)
+          if (browser.params.browser !== 'chrome') {
+            return;
+          }
+
+          it('should not report errors when the page is loaded', function() {
+            // clear errors so we are not dependent on previous tests
+            clearErrors();
+            // Need to reload the page as the page is already loaded when
+            // we come here
+            browser.driver.getCurrentUrl().then(function(url) {
+              browser.get(url);
+            });
+            expectNoErrors();
+          });
+
+          it('should evaluate expressions', function() {
+            expect(counter.getText()).toEqual('0');
+            incBtn.click();
+            expect(counter.getText()).toEqual('1');
+            expectNoErrors();
+          });
+
+          it('should throw and report an error when using "eval"', function() {
+            evilBtn.click();
+            expect(evilError.getText()).toMatch(/Content Security Policy/);
+            expectError(/Content Security Policy/);
+          });
+        </file>
+      </example>
+  */
+
+// `ngCsp` is not implemented as a proper directive any more, because we need it be processed while
+// we bootstrap the app (before `$parse` is instantiated). For this reason, we just have the `csp()`
+// fn that looks for the `ng-csp` attribute anywhere in the current doc.
+
+/**
+ * @ngdoc directive
+ * @name ngClick
+ *
+ * @description
+ * The ngClick directive allows you to specify custom behavior when
+ * an element is clicked.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngClick {@link guide/expression Expression} to evaluate upon
+ * click. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-click">
+     <file name="index.html">
+      <button ng-click="count = count + 1" ng-init="count=0">
+        Increment
+      </button>
+      <span>
+        count: {{count}}
+      </span>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should check ng-click', function() {
+         expect(element(by.binding('count')).getText()).toMatch('0');
+         element(by.css('button')).click();
+         expect(element(by.binding('count')).getText()).toMatch('1');
+       });
+     </file>
+   </example>
+ */
+/*
+ * A collection of directives that allows creation of custom event handlers that are defined as
+ * angular expressions and are compiled and executed within the current scope.
+ */
+var ngEventDirectives = {};
+
+// For events that might fire synchronously during DOM manipulation
+// we need to execute their event handlers asynchronously using $evalAsync,
+// so that they are not executed in an inconsistent state.
+var forceAsyncEvents = {
+  'blur': true,
+  'focus': true
+};
+forEach(
+  'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
+  function(eventName) {
+    var directiveName = directiveNormalize('ng-' + eventName);
+    ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {
+      return {
+        restrict: 'A',
+        compile: function($element, attr) {
+          // NOTE:
+          // We expose the powerful `$event` object on the scope that provides access to the Window,
+          // etc. This is OK, because expressions are not sandboxed any more (and the expression
+          // sandbox was never meant to be a security feature anyway).
+          var fn = $parse(attr[directiveName]);
+          return function ngEventHandler(scope, element) {
+            element.on(eventName, function(event) {
+              var callback = function() {
+                fn(scope, {$event: event});
+              };
+              if (forceAsyncEvents[eventName] && $rootScope.$$phase) {
+                scope.$evalAsync(callback);
+              } else {
+                scope.$apply(callback);
+              }
+            });
+          };
+        }
+      };
+    }];
+  }
+);
+
+/**
+ * @ngdoc directive
+ * @name ngDblclick
+ *
+ * @description
+ * The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon
+ * a dblclick. (The Event object is available as `$event`)
+ *
+ * @example
+   <example name="ng-dblclick">
+     <file name="index.html">
+      <button ng-dblclick="count = count + 1" ng-init="count=0">
+        Increment (on double click)
+      </button>
+      count: {{count}}
+     </file>
+   </example>
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngMousedown
+ *
+ * @description
+ * The ngMousedown directive allows you to specify custom behavior on mousedown event.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon
+ * mousedown. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-mousedown">
+     <file name="index.html">
+      <button ng-mousedown="count = count + 1" ng-init="count=0">
+        Increment (on mouse down)
+      </button>
+      count: {{count}}
+     </file>
+   </example>
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngMouseup
+ *
+ * @description
+ * Specify custom behavior on mouseup event.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon
+ * mouseup. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-mouseup">
+     <file name="index.html">
+      <button ng-mouseup="count = count + 1" ng-init="count=0">
+        Increment (on mouse up)
+      </button>
+      count: {{count}}
+     </file>
+   </example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngMouseover
+ *
+ * @description
+ * Specify custom behavior on mouseover event.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon
+ * mouseover. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-mouseover">
+     <file name="index.html">
+      <button ng-mouseover="count = count + 1" ng-init="count=0">
+        Increment (when mouse is over)
+      </button>
+      count: {{count}}
+     </file>
+   </example>
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngMouseenter
+ *
+ * @description
+ * Specify custom behavior on mouseenter event.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon
+ * mouseenter. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-mouseenter">
+     <file name="index.html">
+      <button ng-mouseenter="count = count + 1" ng-init="count=0">
+        Increment (when mouse enters)
+      </button>
+      count: {{count}}
+     </file>
+   </example>
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngMouseleave
+ *
+ * @description
+ * Specify custom behavior on mouseleave event.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon
+ * mouseleave. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-mouseleave">
+     <file name="index.html">
+      <button ng-mouseleave="count = count + 1" ng-init="count=0">
+        Increment (when mouse leaves)
+      </button>
+      count: {{count}}
+     </file>
+   </example>
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngMousemove
+ *
+ * @description
+ * Specify custom behavior on mousemove event.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon
+ * mousemove. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-mousemove">
+     <file name="index.html">
+      <button ng-mousemove="count = count + 1" ng-init="count=0">
+        Increment (when mouse moves)
+      </button>
+      count: {{count}}
+     </file>
+   </example>
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngKeydown
+ *
+ * @description
+ * Specify custom behavior on keydown event.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
+ * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
+ *
+ * @example
+   <example name="ng-keydown">
+     <file name="index.html">
+      <input ng-keydown="count = count + 1" ng-init="count=0">
+      key down count: {{count}}
+     </file>
+   </example>
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngKeyup
+ *
+ * @description
+ * Specify custom behavior on keyup event.
+ *
+ * @element ANY
+ * @priority 0
+ * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
+ * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
+ *
+ * @example
+   <example name="ng-keyup">
+     <file name="index.html">
+       <p>Typing in the input box below updates the key count</p>
+       <input ng-keyup="count = count + 1" ng-init="count=0"> key up count: {{count}}
+
+       <p>Typing in the input box below updates the keycode</p>
+       <input ng-keyup="event=$event">
+       <p>event keyCode: {{ event.keyCode }}</p>
+       <p>event altKey: {{ event.altKey }}</p>
+     </file>
+   </example>
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngKeypress
+ *
+ * @description
+ * Specify custom behavior on keypress event.
+ *
+ * @element ANY
+ * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon
+ * keypress. ({@link guide/expression#-event- Event object is available as `$event`}
+ * and can be interrogated for keyCode, altKey, etc.)
+ *
+ * @example
+   <example name="ng-keypress">
+     <file name="index.html">
+      <input ng-keypress="count = count + 1" ng-init="count=0">
+      key press count: {{count}}
+     </file>
+   </example>
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name ngSubmit
+ *
+ * @description
+ * Enables binding angular expressions to onsubmit events.
+ *
+ * Additionally it prevents the default action (which for form means sending the request to the
+ * server and reloading the current page), but only if the form does not contain `action`,
+ * `data-action`, or `x-action` attributes.
+ *
+ * <div class="alert alert-warning">
+ * **Warning:** Be careful not to cause "double-submission" by using both the `ngClick` and
+ * `ngSubmit` handlers together. See the
+ * {@link form#submitting-a-form-and-preventing-the-default-action `form` directive documentation}
+ * for a detailed discussion of when `ngSubmit` may be triggered.
+ * </div>
+ *
+ * @element form
+ * @priority 0
+ * @param {expression} ngSubmit {@link guide/expression Expression} to eval.
+ * ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example module="submitExample" name="ng-submit">
+     <file name="index.html">
+      <script>
+        angular.module('submitExample', [])
+          .controller('ExampleController', ['$scope', function($scope) {
+            $scope.list = [];
+            $scope.text = 'hello';
+            $scope.submit = function() {
+              if ($scope.text) {
+                $scope.list.push(this.text);
+                $scope.text = '';
+              }
+            };
+          }]);
+      </script>
+      <form ng-submit="submit()" ng-controller="ExampleController">
+        Enter text and hit enter:
+        <input type="text" ng-model="text" name="text" />
+        <input type="submit" id="submit" value="Submit" />
+        <pre>list={{list}}</pre>
+      </form>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should check ng-submit', function() {
+         expect(element(by.binding('list')).getText()).toBe('list=[]');
+         element(by.css('#submit')).click();
+         expect(element(by.binding('list')).getText()).toContain('hello');
+         expect(element(by.model('text')).getAttribute('value')).toBe('');
+       });
+       it('should ignore empty strings', function() {
+         expect(element(by.binding('list')).getText()).toBe('list=[]');
+         element(by.css('#submit')).click();
+         element(by.css('#submit')).click();
+         expect(element(by.binding('list')).getText()).toContain('hello');
+        });
+     </file>
+   </example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngFocus
+ *
+ * @description
+ * Specify custom behavior on focus event.
+ *
+ * Note: As the `focus` event is executed synchronously when calling `input.focus()`
+ * AngularJS executes the expression using `scope.$evalAsync` if the event is fired
+ * during an `$apply` to ensure a consistent state.
+ *
+ * @element window, input, select, textarea, a
+ * @priority 0
+ * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon
+ * focus. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+ * See {@link ng.directive:ngClick ngClick}
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngBlur
+ *
+ * @description
+ * Specify custom behavior on blur event.
+ *
+ * A [blur event](https://developer.mozilla.org/en-US/docs/Web/Events/blur) fires when
+ * an element has lost focus.
+ *
+ * Note: As the `blur` event is executed synchronously also during DOM manipulations
+ * (e.g. removing a focussed input),
+ * AngularJS executes the expression using `scope.$evalAsync` if the event is fired
+ * during an `$apply` to ensure a consistent state.
+ *
+ * @element window, input, select, textarea, a
+ * @priority 0
+ * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon
+ * blur. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+ * See {@link ng.directive:ngClick ngClick}
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngCopy
+ *
+ * @description
+ * Specify custom behavior on copy event.
+ *
+ * @element window, input, select, textarea, a
+ * @priority 0
+ * @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon
+ * copy. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-copy">
+     <file name="index.html">
+      <input ng-copy="copied=true" ng-init="copied=false; value='copy me'" ng-model="value">
+      copied: {{copied}}
+     </file>
+   </example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngCut
+ *
+ * @description
+ * Specify custom behavior on cut event.
+ *
+ * @element window, input, select, textarea, a
+ * @priority 0
+ * @param {expression} ngCut {@link guide/expression Expression} to evaluate upon
+ * cut. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-cut">
+     <file name="index.html">
+      <input ng-cut="cut=true" ng-init="cut=false; value='cut me'" ng-model="value">
+      cut: {{cut}}
+     </file>
+   </example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngPaste
+ *
+ * @description
+ * Specify custom behavior on paste event.
+ *
+ * @element window, input, select, textarea, a
+ * @priority 0
+ * @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon
+ * paste. ({@link guide/expression#-event- Event object is available as `$event`})
+ *
+ * @example
+   <example name="ng-paste">
+     <file name="index.html">
+      <input ng-paste="paste=true" ng-init="paste=false" placeholder='paste here'>
+      pasted: {{paste}}
+     </file>
+   </example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngIf
+ * @restrict A
+ * @multiElement
+ *
+ * @description
+ * The `ngIf` directive removes or recreates a portion of the DOM tree based on an
+ * {expression}. If the expression assigned to `ngIf` evaluates to a false
+ * value then the element is removed from the DOM, otherwise a clone of the
+ * element is reinserted into the DOM.
+ *
+ * `ngIf` differs from `ngShow` and `ngHide` in that `ngIf` completely removes and recreates the
+ * element in the DOM rather than changing its visibility via the `display` css property.  A common
+ * case when this difference is significant is when using css selectors that rely on an element's
+ * position within the DOM, such as the `:first-child` or `:last-child` pseudo-classes.
+ *
+ * Note that when an element is removed using `ngIf` its scope is destroyed and a new scope
+ * is created when the element is restored.  The scope created within `ngIf` inherits from
+ * its parent scope using
+ * [prototypal inheritance](https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance).
+ * An important implication of this is if `ngModel` is used within `ngIf` to bind to
+ * a javascript primitive defined in the parent scope. In this case any modifications made to the
+ * variable within the child scope will override (hide) the value in the parent scope.
+ *
+ * Also, `ngIf` recreates elements using their compiled state. An example of this behavior
+ * is if an element's class attribute is directly modified after it's compiled, using something like
+ * jQuery's `.addClass()` method, and the element is later removed. When `ngIf` recreates the element
+ * the added class will be lost because the original compiled state is used to regenerate the element.
+ *
+ * Additionally, you can provide animations via the `ngAnimate` module to animate the `enter`
+ * and `leave` effects.
+ *
+ * @animations
+ * | Animation                        | Occurs                               |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#enter enter}  | just after the `ngIf` contents change and a new DOM element is created and injected into the `ngIf` container |
+ * | {@link ng.$animate#leave leave}  | just before the `ngIf` contents are removed from the DOM |
+ *
+ * @element ANY
+ * @scope
+ * @priority 600
+ * @param {expression} ngIf If the {@link guide/expression expression} is falsy then
+ *     the element is removed from the DOM tree. If it is truthy a copy of the compiled
+ *     element is added to the DOM tree.
+ *
+ * @example
+  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-if">
+    <file name="index.html">
+      <label>Click me: <input type="checkbox" ng-model="checked" ng-init="checked=true" /></label><br/>
+      Show when checked:
+      <span ng-if="checked" class="animate-if">
+        This is removed when the checkbox is unchecked.
+      </span>
+    </file>
+    <file name="animations.css">
+      .animate-if {
+        background:white;
+        border:1px solid black;
+        padding:10px;
+      }
+
+      .animate-if.ng-enter, .animate-if.ng-leave {
+        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
+      }
+
+      .animate-if.ng-enter,
+      .animate-if.ng-leave.ng-leave-active {
+        opacity:0;
+      }
+
+      .animate-if.ng-leave,
+      .animate-if.ng-enter.ng-enter-active {
+        opacity:1;
+      }
+    </file>
+  </example>
+ */
+var ngIfDirective = ['$animate', '$compile', function($animate, $compile) {
+  return {
+    multiElement: true,
+    transclude: 'element',
+    priority: 600,
+    terminal: true,
+    restrict: 'A',
+    $$tlb: true,
+    link: function($scope, $element, $attr, ctrl, $transclude) {
+        var block, childScope, previousElements;
+        $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {
+
+          if (value) {
+            if (!childScope) {
+              $transclude(function(clone, newScope) {
+                childScope = newScope;
+                clone[clone.length++] = $compile.$$createComment('end ngIf', $attr.ngIf);
+                // Note: We only need the first/last node of the cloned nodes.
+                // However, we need to keep the reference to the jqlite wrapper as it might be changed later
+                // by a directive with templateUrl when its template arrives.
+                block = {
+                  clone: clone
+                };
+                $animate.enter(clone, $element.parent(), $element);
+              });
+            }
+          } else {
+            if (previousElements) {
+              previousElements.remove();
+              previousElements = null;
+            }
+            if (childScope) {
+              childScope.$destroy();
+              childScope = null;
+            }
+            if (block) {
+              previousElements = getBlockNodes(block.clone);
+              $animate.leave(previousElements).done(function(response) {
+                if (response !== false) previousElements = null;
+              });
+              block = null;
+            }
+          }
+        });
+    }
+  };
+}];
+
+/**
+ * @ngdoc directive
+ * @name ngInclude
+ * @restrict ECA
+ *
+ * @description
+ * Fetches, compiles and includes an external HTML fragment.
+ *
+ * By default, the template URL is restricted to the same domain and protocol as the
+ * application document. This is done by calling {@link $sce#getTrustedResourceUrl
+ * $sce.getTrustedResourceUrl} on it. To load templates from other domains or protocols
+ * you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist them} or
+ * {@link $sce#trustAsResourceUrl wrap them} as trusted values. Refer to Angular's {@link
+ * ng.$sce Strict Contextual Escaping}.
+ *
+ * In addition, the browser's
+ * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)
+ * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)
+ * policy may further restrict whether the template is successfully loaded.
+ * For example, `ngInclude` won't work for cross-domain requests on all browsers and for `file://`
+ * access on some browsers.
+ *
+ * @animations
+ * | Animation                        | Occurs                              |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#enter enter}  | when the expression changes, on the new include |
+ * | {@link ng.$animate#leave leave}  | when the expression changes, on the old include |
+ *
+ * The enter and leave animation occur concurrently.
+ *
+ * @scope
+ * @priority 400
+ *
+ * @param {string} ngInclude|src angular expression evaluating to URL. If the source is a string constant,
+ *                 make sure you wrap it in **single** quotes, e.g. `src="'myPartialTemplate.html'"`.
+ * @param {string=} onload Expression to evaluate when a new partial is loaded.
+ *                  <div class="alert alert-warning">
+ *                  **Note:** When using onload on SVG elements in IE11, the browser will try to call
+ *                  a function with the name on the window element, which will usually throw a
+ *                  "function is undefined" error. To fix this, you can instead use `data-onload` or a
+ *                  different form that {@link guide/directive#normalization matches} `onload`.
+ *                  </div>
+   *
+ * @param {string=} autoscroll Whether `ngInclude` should call {@link ng.$anchorScroll
+ *                  $anchorScroll} to scroll the viewport after the content is loaded.
+ *
+ *                  - If the attribute is not set, disable scrolling.
+ *                  - If the attribute is set without value, enable scrolling.
+ *                  - Otherwise enable scrolling only if the expression evaluates to truthy value.
+ *
+ * @example
+  <example module="includeExample" deps="angular-animate.js" animations="true" name="ng-include">
+    <file name="index.html">
+     <div ng-controller="ExampleController">
+       <select ng-model="template" ng-options="t.name for t in templates">
+        <option value="">(blank)</option>
+       </select>
+       url of the template: <code>{{template.url}}</code>
+       <hr/>
+       <div class="slide-animate-container">
+         <div class="slide-animate" ng-include="template.url"></div>
+       </div>
+     </div>
+    </file>
+    <file name="script.js">
+      angular.module('includeExample', ['ngAnimate'])
+        .controller('ExampleController', ['$scope', function($scope) {
+          $scope.templates =
+            [{ name: 'template1.html', url: 'template1.html'},
+             { name: 'template2.html', url: 'template2.html'}];
+          $scope.template = $scope.templates[0];
+        }]);
+     </file>
+    <file name="template1.html">
+      Content of template1.html
+    </file>
+    <file name="template2.html">
+      Content of template2.html
+    </file>
+    <file name="animations.css">
+      .slide-animate-container {
+        position:relative;
+        background:white;
+        border:1px solid black;
+        height:40px;
+        overflow:hidden;
+      }
+
+      .slide-animate {
+        padding:10px;
+      }
+
+      .slide-animate.ng-enter, .slide-animate.ng-leave {
+        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
+
+        position:absolute;
+        top:0;
+        left:0;
+        right:0;
+        bottom:0;
+        display:block;
+        padding:10px;
+      }
+
+      .slide-animate.ng-enter {
+        top:-50px;
+      }
+      .slide-animate.ng-enter.ng-enter-active {
+        top:0;
+      }
+
+      .slide-animate.ng-leave {
+        top:0;
+      }
+      .slide-animate.ng-leave.ng-leave-active {
+        top:50px;
+      }
+    </file>
+    <file name="protractor.js" type="protractor">
+      var templateSelect = element(by.model('template'));
+      var includeElem = element(by.css('[ng-include]'));
+
+      it('should load template1.html', function() {
+        expect(includeElem.getText()).toMatch(/Content of template1.html/);
+      });
+
+      it('should load template2.html', function() {
+        if (browser.params.browser === 'firefox') {
+          // Firefox can't handle using selects
+          // See https://github.com/angular/protractor/issues/480
+          return;
+        }
+        templateSelect.click();
+        templateSelect.all(by.css('option')).get(2).click();
+        expect(includeElem.getText()).toMatch(/Content of template2.html/);
+      });
+
+      it('should change to blank', function() {
+        if (browser.params.browser === 'firefox') {
+          // Firefox can't handle using selects
+          return;
+        }
+        templateSelect.click();
+        templateSelect.all(by.css('option')).get(0).click();
+        expect(includeElem.isPresent()).toBe(false);
+      });
+    </file>
+  </example>
+ */
+
+
+/**
+ * @ngdoc event
+ * @name ngInclude#$includeContentRequested
+ * @eventType emit on the scope ngInclude was declared in
+ * @description
+ * Emitted every time the ngInclude content is requested.
+ *
+ * @param {Object} angularEvent Synthetic event object.
+ * @param {String} src URL of content to load.
+ */
+
+
+/**
+ * @ngdoc event
+ * @name ngInclude#$includeContentLoaded
+ * @eventType emit on the current ngInclude scope
+ * @description
+ * Emitted every time the ngInclude content is reloaded.
+ *
+ * @param {Object} angularEvent Synthetic event object.
+ * @param {String} src URL of content to load.
+ */
+
+
+/**
+ * @ngdoc event
+ * @name ngInclude#$includeContentError
+ * @eventType emit on the scope ngInclude was declared in
+ * @description
+ * Emitted when a template HTTP request yields an erroneous response (status < 200 || status > 299)
+ *
+ * @param {Object} angularEvent Synthetic event object.
+ * @param {String} src URL of content to load.
+ */
+var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate',
+                  function($templateRequest,   $anchorScroll,   $animate) {
+  return {
+    restrict: 'ECA',
+    priority: 400,
+    terminal: true,
+    transclude: 'element',
+    controller: angular.noop,
+    compile: function(element, attr) {
+      var srcExp = attr.ngInclude || attr.src,
+          onloadExp = attr.onload || '',
+          autoScrollExp = attr.autoscroll;
+
+      return function(scope, $element, $attr, ctrl, $transclude) {
+        var changeCounter = 0,
+            currentScope,
+            previousElement,
+            currentElement;
+
+        var cleanupLastIncludeContent = function() {
+          if (previousElement) {
+            previousElement.remove();
+            previousElement = null;
+          }
+          if (currentScope) {
+            currentScope.$destroy();
+            currentScope = null;
+          }
+          if (currentElement) {
+            $animate.leave(currentElement).done(function(response) {
+              if (response !== false) previousElement = null;
+            });
+            previousElement = currentElement;
+            currentElement = null;
+          }
+        };
+
+        scope.$watch(srcExp, function ngIncludeWatchAction(src) {
+          var afterAnimation = function(response) {
+            if (response !== false && isDefined(autoScrollExp) &&
+              (!autoScrollExp || scope.$eval(autoScrollExp))) {
+                $anchorScroll();
+            }
+          };
+          var thisChangeId = ++changeCounter;
+
+          if (src) {
+            //set the 2nd param to true to ignore the template request error so that the inner
+            //contents and scope can be cleaned up.
+            $templateRequest(src, true).then(function(response) {
+              if (scope.$$destroyed) return;
+
+              if (thisChangeId !== changeCounter) return;
+              var newScope = scope.$new();
+              ctrl.template = response;
+
+              // Note: This will also link all children of ng-include that were contained in the original
+              // html. If that content contains controllers, ... they could pollute/change the scope.
+              // However, using ng-include on an element with additional content does not make sense...
+              // Note: We can't remove them in the cloneAttchFn of $transclude as that
+              // function is called before linking the content, which would apply child
+              // directives to non existing elements.
+              var clone = $transclude(newScope, function(clone) {
+                cleanupLastIncludeContent();
+                $animate.enter(clone, null, $element).done(afterAnimation);
+              });
+
+              currentScope = newScope;
+              currentElement = clone;
+
+              currentScope.$emit('$includeContentLoaded', src);
+              scope.$eval(onloadExp);
+            }, function() {
+              if (scope.$$destroyed) return;
+
+              if (thisChangeId === changeCounter) {
+                cleanupLastIncludeContent();
+                scope.$emit('$includeContentError', src);
+              }
+            });
+            scope.$emit('$includeContentRequested', src);
+          } else {
+            cleanupLastIncludeContent();
+            ctrl.template = null;
+          }
+        });
+      };
+    }
+  };
+}];
+
+// This directive is called during the $transclude call of the first `ngInclude` directive.
+// It will replace and compile the content of the element with the loaded template.
+// We need this directive so that the element content is already filled when
+// the link function of another directive on the same element as ngInclude
+// is called.
+var ngIncludeFillContentDirective = ['$compile',
+  function($compile) {
+    return {
+      restrict: 'ECA',
+      priority: -400,
+      require: 'ngInclude',
+      link: function(scope, $element, $attr, ctrl) {
+        if (toString.call($element[0]).match(/SVG/)) {
+          // WebKit: https://bugs.webkit.org/show_bug.cgi?id=135698 --- SVG elements do not
+          // support innerHTML, so detect this here and try to generate the contents
+          // specially.
+          $element.empty();
+          $compile(jqLiteBuildFragment(ctrl.template, window.document).childNodes)(scope,
+              function namespaceAdaptedClone(clone) {
+            $element.append(clone);
+          }, {futureParentElement: $element});
+          return;
+        }
+
+        $element.html(ctrl.template);
+        $compile($element.contents())(scope);
+      }
+    };
+  }];
+
+/**
+ * @ngdoc directive
+ * @name ngInit
+ * @restrict AC
+ *
+ * @description
+ * The `ngInit` directive allows you to evaluate an expression in the
+ * current scope.
+ *
+ * <div class="alert alert-danger">
+ * This directive can be abused to add unnecessary amounts of logic into your templates.
+ * There are only a few appropriate uses of `ngInit`, such as for aliasing special properties of
+ * {@link ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below; and for injecting data via
+ * server side scripting. Besides these few cases, you should use {@link guide/controller controllers}
+ * rather than `ngInit` to initialize values on a scope.
+ * </div>
+ *
+ * <div class="alert alert-warning">
+ * **Note**: If you have assignment in `ngInit` along with a {@link ng.$filter `filter`}, make
+ * sure you have parentheses to ensure correct operator precedence:
+ * <pre class="prettyprint">
+ * `<div ng-init="test1 = ($index | toString)"></div>`
+ * </pre>
+ * </div>
+ *
+ * @priority 450
+ *
+ * @element ANY
+ * @param {expression} ngInit {@link guide/expression Expression} to eval.
+ *
+ * @example
+   <example module="initExample" name="ng-init">
+     <file name="index.html">
+   <script>
+     angular.module('initExample', [])
+       .controller('ExampleController', ['$scope', function($scope) {
+         $scope.list = [['a', 'b'], ['c', 'd']];
+       }]);
+   </script>
+   <div ng-controller="ExampleController">
+     <div ng-repeat="innerList in list" ng-init="outerIndex = $index">
+       <div ng-repeat="value in innerList" ng-init="innerIndex = $index">
+          <span class="example-init">list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}};</span>
+       </div>
+     </div>
+   </div>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should alias index positions', function() {
+         var elements = element.all(by.css('.example-init'));
+         expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;');
+         expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;');
+         expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;');
+         expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;');
+       });
+     </file>
+   </example>
+ */
+var ngInitDirective = ngDirective({
+  priority: 450,
+  compile: function() {
+    return {
+      pre: function(scope, element, attrs) {
+        scope.$eval(attrs.ngInit);
+      }
+    };
+  }
+});
+
+/**
+ * @ngdoc directive
+ * @name ngList
+ *
+ * @description
+ * Text input that converts between a delimited string and an array of strings. The default
+ * delimiter is a comma followed by a space - equivalent to `ng-list=", "`. You can specify a custom
+ * delimiter as the value of the `ngList` attribute - for example, `ng-list=" | "`.
+ *
+ * The behaviour of the directive is affected by the use of the `ngTrim` attribute.
+ * * If `ngTrim` is set to `"false"` then whitespace around both the separator and each
+ *   list item is respected. This implies that the user of the directive is responsible for
+ *   dealing with whitespace but also allows you to use whitespace as a delimiter, such as a
+ *   tab or newline character.
+ * * Otherwise whitespace around the delimiter is ignored when splitting (although it is respected
+ *   when joining the list items back together) and whitespace around each list item is stripped
+ *   before it is added to the model.
+ *
+ * ### Example with Validation
+ *
+ * <example name="ngList-directive" module="listExample">
+ *   <file name="app.js">
+ *      angular.module('listExample', [])
+ *        .controller('ExampleController', ['$scope', function($scope) {
+ *          $scope.names = ['morpheus', 'neo', 'trinity'];
+ *        }]);
+ *   </file>
+ *   <file name="index.html">
+ *    <form name="myForm" ng-controller="ExampleController">
+ *      <label>List: <input name="namesInput" ng-model="names" ng-list required></label>
+ *      <span role="alert">
+ *        <span class="error" ng-show="myForm.namesInput.$error.required">
+ *        Required!</span>
+ *      </span>
+ *      <br>
+ *      <tt>names = {{names}}</tt><br/>
+ *      <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
+ *      <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
+ *      <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
+ *      <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
+ *     </form>
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+ *     var listInput = element(by.model('names'));
+ *     var names = element(by.exactBinding('names'));
+ *     var valid = element(by.binding('myForm.namesInput.$valid'));
+ *     var error = element(by.css('span.error'));
+ *
+ *     it('should initialize to model', function() {
+ *       expect(names.getText()).toContain('["morpheus","neo","trinity"]');
+ *       expect(valid.getText()).toContain('true');
+ *       expect(error.getCssValue('display')).toBe('none');
+ *     });
+ *
+ *     it('should be invalid if empty', function() {
+ *       listInput.clear();
+ *       listInput.sendKeys('');
+ *
+ *       expect(names.getText()).toContain('');
+ *       expect(valid.getText()).toContain('false');
+ *       expect(error.getCssValue('display')).not.toBe('none');
+ *     });
+ *   </file>
+ * </example>
+ *
+ * ### Example - splitting on newline
+ * <example name="ngList-directive-newlines">
+ *   <file name="index.html">
+ *    <textarea ng-model="list" ng-list="&#10;" ng-trim="false"></textarea>
+ *    <pre>{{ list | json }}</pre>
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+ *     it("should split the text by newlines", function() {
+ *       var listInput = element(by.model('list'));
+ *       var output = element(by.binding('list | json'));
+ *       listInput.sendKeys('abc\ndef\nghi');
+ *       expect(output.getText()).toContain('[\n  "abc",\n  "def",\n  "ghi"\n]');
+ *     });
+ *   </file>
+ * </example>
+ *
+ * @element input
+ * @param {string=} ngList optional delimiter that should be used to split the value.
+ */
+var ngListDirective = function() {
+  return {
+    restrict: 'A',
+    priority: 100,
+    require: 'ngModel',
+    link: function(scope, element, attr, ctrl) {
+      var ngList = attr.ngList || ', ';
+      var trimValues = attr.ngTrim !== 'false';
+      var separator = trimValues ? trim(ngList) : ngList;
+
+      var parse = function(viewValue) {
+        // If the viewValue is invalid (say required but empty) it will be `undefined`
+        if (isUndefined(viewValue)) return;
+
+        var list = [];
+
+        if (viewValue) {
+          forEach(viewValue.split(separator), function(value) {
+            if (value) list.push(trimValues ? trim(value) : value);
+          });
+        }
+
+        return list;
+      };
+
+      ctrl.$parsers.push(parse);
+      ctrl.$formatters.push(function(value) {
+        if (isArray(value)) {
+          return value.join(ngList);
+        }
+
+        return undefined;
+      });
+
+      // Override the standard $isEmpty because an empty array means the input is empty.
+      ctrl.$isEmpty = function(value) {
+        return !value || !value.length;
+      };
+    }
+  };
+};
+
+/* global VALID_CLASS: true,
+  INVALID_CLASS: true,
+  PRISTINE_CLASS: true,
+  DIRTY_CLASS: true,
+  UNTOUCHED_CLASS: true,
+  TOUCHED_CLASS: true,
+  PENDING_CLASS: true,
+  addSetValidityMethod: true,
+  setupValidity: true,
+  defaultModelOptions: false
+*/
+
+
+var VALID_CLASS = 'ng-valid',
+    INVALID_CLASS = 'ng-invalid',
+    PRISTINE_CLASS = 'ng-pristine',
+    DIRTY_CLASS = 'ng-dirty',
+    UNTOUCHED_CLASS = 'ng-untouched',
+    TOUCHED_CLASS = 'ng-touched',
+    EMPTY_CLASS = 'ng-empty',
+    NOT_EMPTY_CLASS = 'ng-not-empty';
+
+var ngModelMinErr = minErr('ngModel');
+
+/**
+ * @ngdoc type
+ * @name ngModel.NgModelController
+ *
+ * @property {*} $viewValue The actual value from the control's view. For `input` elements, this is a
+ * String. See {@link ngModel.NgModelController#$setViewValue} for information about when the $viewValue
+ * is set.
+ *
+ * @property {*} $modelValue The value in the model that the control is bound to.
+ *
+ * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
+ *  the control updates the ngModelController with a new {@link ngModel.NgModelController#$viewValue
+    `$viewValue`} from the DOM, usually via user input.
+    See {@link ngModel.NgModelController#$setViewValue `$setViewValue()`} for a detailed lifecycle explanation.
+    Note that the `$parsers` are not called when the bound ngModel expression changes programmatically.
+
+  The functions are called in array order, each passing
+    its return value through to the next. The last return value is forwarded to the
+    {@link ngModel.NgModelController#$validators `$validators`} collection.
+
+  Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue
+    `$viewValue`}.
+
+  Returning `undefined` from a parser means a parse error occurred. In that case,
+    no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel`
+    will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`}
+    is set to `true`. The parse error is stored in `ngModel.$error.parse`.
+
+  This simple example shows a parser that would convert text input value to lowercase:
+ * ```js
+ * function parse(value) {
+ *   if (value) {
+ *     return value.toLowerCase();
+ *   }
+ * }
+ * ngModelController.$parsers.push(parse);
+ * ```
+
+ *
+ * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
+    the bound ngModel expression changes programmatically. The `$formatters` are not called when the
+    value of the control is changed by user interaction.
+
+  Formatters are used to format / convert the {@link ngModel.NgModelController#$modelValue
+    `$modelValue`} for display in the control.
+
+  The functions are called in reverse array order, each passing the value through to the
+    next. The last return value is used as the actual DOM value.
+
+  This simple example shows a formatter that would convert the model value to uppercase:
+
+ * ```js
+ * function format(value) {
+ *   if (value) {
+ *     return value.toUpperCase();
+ *   }
+ * }
+ * ngModel.$formatters.push(format);
+ * ```
+ *
+ * @property {Object.<string, function>} $validators A collection of validators that are applied
+ *      whenever the model value changes. The key value within the object refers to the name of the
+ *      validator while the function refers to the validation operation. The validation operation is
+ *      provided with the model value as an argument and must return a true or false value depending
+ *      on the response of that validation.
+ *
+ * ```js
+ * ngModel.$validators.validCharacters = function(modelValue, viewValue) {
+ *   var value = modelValue || viewValue;
+ *   return /[0-9]+/.test(value) &&
+ *          /[a-z]+/.test(value) &&
+ *          /[A-Z]+/.test(value) &&
+ *          /\W+/.test(value);
+ * };
+ * ```
+ *
+ * @property {Object.<string, function>} $asyncValidators A collection of validations that are expected to
+ *      perform an asynchronous validation (e.g. a HTTP request). The validation function that is provided
+ *      is expected to return a promise when it is run during the model validation process. Once the promise
+ *      is delivered then the validation status will be set to true when fulfilled and false when rejected.
+ *      When the asynchronous validators are triggered, each of the validators will run in parallel and the model
+ *      value will only be updated once all validators have been fulfilled. As long as an asynchronous validator
+ *      is unfulfilled, its key will be added to the controllers `$pending` property. Also, all asynchronous validators
+ *      will only run once all synchronous validators have passed.
+ *
+ * Please note that if $http is used then it is important that the server returns a success HTTP response code
+ * in order to fulfill the validation and a status level of `4xx` in order to reject the validation.
+ *
+ * ```js
+ * ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
+ *   var value = modelValue || viewValue;
+ *
+ *   // Lookup user by username
+ *   return $http.get('/api/users/' + value).
+ *      then(function resolved() {
+ *        //username exists, this means validation fails
+ *        return $q.reject('exists');
+ *      }, function rejected() {
+ *        //username does not exist, therefore this validation passes
+ *        return true;
+ *      });
+ * };
+ * ```
+ *
+ * @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever the
+ *     view value has changed. It is called with no arguments, and its return value is ignored.
+ *     This can be used in place of additional $watches against the model value.
+ *
+ * @property {Object} $error An object hash with all failing validator ids as keys.
+ * @property {Object} $pending An object hash with all pending validator ids as keys.
+ *
+ * @property {boolean} $untouched True if control has not lost focus yet.
+ * @property {boolean} $touched True if control has lost focus.
+ * @property {boolean} $pristine True if user has not interacted with the control yet.
+ * @property {boolean} $dirty True if user has already interacted with the control.
+ * @property {boolean} $valid True if there is no error.
+ * @property {boolean} $invalid True if at least one error on the control.
+ * @property {string} $name The name attribute of the control.
+ *
+ * @description
+ *
+ * `NgModelController` provides API for the {@link ngModel `ngModel`} directive.
+ * The controller contains services for data-binding, validation, CSS updates, and value formatting
+ * and parsing. It purposefully does not contain any logic which deals with DOM rendering or
+ * listening to DOM events.
+ * Such DOM related logic should be provided by other directives which make use of
+ * `NgModelController` for data-binding to control elements.
+ * Angular provides this DOM logic for most {@link input `input`} elements.
+ * At the end of this page you can find a {@link ngModel.NgModelController#custom-control-example
+ * custom control example} that uses `ngModelController` to bind to `contenteditable` elements.
+ *
+ * @example
+ * ### Custom Control Example
+ * This example shows how to use `NgModelController` with a custom control to achieve
+ * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
+ * collaborate together to achieve the desired result.
+ *
+ * `contenteditable` is an HTML5 attribute, which tells the browser to let the element
+ * contents be edited in place by the user.
+ *
+ * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize}
+ * module to automatically remove "bad" content like inline event listener (e.g. `<span onclick="...">`).
+ * However, as we are using `$sce` the model can still decide to provide unsafe content if it marks
+ * that content using the `$sce` service.
+ *
+ * <example name="NgModelController" module="customControl" deps="angular-sanitize.js">
+    <file name="style.css">
+      [contenteditable] {
+        border: 1px solid black;
+        background-color: white;
+        min-height: 20px;
+      }
+
+      .ng-invalid {
+        border: 1px solid red;
+      }
+
+    </file>
+    <file name="script.js">
+      angular.module('customControl', ['ngSanitize']).
+        directive('contenteditable', ['$sce', function($sce) {
+          return {
+            restrict: 'A', // only activate on element attribute
+            require: '?ngModel', // get a hold of NgModelController
+            link: function(scope, element, attrs, ngModel) {
+              if (!ngModel) return; // do nothing if no ng-model
+
+              // Specify how UI should be updated
+              ngModel.$render = function() {
+                element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
+              };
+
+              // Listen for change events to enable binding
+              element.on('blur keyup change', function() {
+                scope.$evalAsync(read);
+              });
+              read(); // initialize
+
+              // Write data to the model
+              function read() {
+                var html = element.html();
+                // When we clear the content editable the browser leaves a <br> behind
+                // If strip-br attribute is provided then we strip this out
+                if (attrs.stripBr && html === '<br>') {
+                  html = '';
+                }
+                ngModel.$setViewValue(html);
+              }
+            }
+          };
+        }]);
+    </file>
+    <file name="index.html">
+      <form name="myForm">
+       <div contenteditable
+            name="myWidget" ng-model="userContent"
+            strip-br="true"
+            required>Change me!</div>
+        <span ng-show="myForm.myWidget.$error.required">Required!</span>
+       <hr>
+       <textarea ng-model="userContent" aria-label="Dynamic textarea"></textarea>
+      </form>
+    </file>
+    <file name="protractor.js" type="protractor">
+    it('should data-bind and become invalid', function() {
+      if (browser.params.browser === 'safari' || browser.params.browser === 'firefox') {
+        // SafariDriver can't handle contenteditable
+        // and Firefox driver can't clear contenteditables very well
+        return;
+      }
+      var contentEditable = element(by.css('[contenteditable]'));
+      var content = 'Change me!';
+
+      expect(contentEditable.getText()).toEqual(content);
+
+      contentEditable.clear();
+      contentEditable.sendKeys(protractor.Key.BACK_SPACE);
+      expect(contentEditable.getText()).toEqual('');
+      expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/);
+    });
+    </file>
+ * </example>
+ *
+ *
+ */
+NgModelController.$inject = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$q', '$interpolate'];
+function NgModelController($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $q, $interpolate) {
+  this.$viewValue = Number.NaN;
+  this.$modelValue = Number.NaN;
+  this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.
+  this.$validators = {};
+  this.$asyncValidators = {};
+  this.$parsers = [];
+  this.$formatters = [];
+  this.$viewChangeListeners = [];
+  this.$untouched = true;
+  this.$touched = false;
+  this.$pristine = true;
+  this.$dirty = false;
+  this.$valid = true;
+  this.$invalid = false;
+  this.$error = {}; // keep invalid keys here
+  this.$$success = {}; // keep valid keys here
+  this.$pending = undefined; // keep pending keys here
+  this.$name = $interpolate($attr.name || '', false)($scope);
+  this.$$parentForm = nullFormCtrl;
+  this.$options = defaultModelOptions;
+
+  this.$$parsedNgModel = $parse($attr.ngModel);
+  this.$$parsedNgModelAssign = this.$$parsedNgModel.assign;
+  this.$$ngModelGet = this.$$parsedNgModel;
+  this.$$ngModelSet = this.$$parsedNgModelAssign;
+  this.$$pendingDebounce = null;
+  this.$$parserValid = undefined;
+
+  this.$$currentValidationRunId = 0;
+
+  this.$$scope = $scope;
+  this.$$attr = $attr;
+  this.$$element = $element;
+  this.$$animate = $animate;
+  this.$$timeout = $timeout;
+  this.$$parse = $parse;
+  this.$$q = $q;
+  this.$$exceptionHandler = $exceptionHandler;
+
+  setupValidity(this);
+  setupModelWatcher(this);
+}
+
+NgModelController.prototype = {
+  $$initGetterSetters: function() {
+    if (this.$options.getOption('getterSetter')) {
+      var invokeModelGetter = this.$$parse(this.$$attr.ngModel + '()'),
+          invokeModelSetter = this.$$parse(this.$$attr.ngModel + '($$$p)');
+
+      this.$$ngModelGet = function($scope) {
+        var modelValue = this.$$parsedNgModel($scope);
+        if (isFunction(modelValue)) {
+          modelValue = invokeModelGetter($scope);
+        }
+        return modelValue;
+      };
+      this.$$ngModelSet = function($scope, newValue) {
+        if (isFunction(this.$$parsedNgModel($scope))) {
+          invokeModelSetter($scope, {$$$p: newValue});
+        } else {
+          this.$$parsedNgModelAssign($scope, newValue);
+        }
+      };
+    } else if (!this.$$parsedNgModel.assign) {
+      throw ngModelMinErr('nonassign', 'Expression \'{0}\' is non-assignable. Element: {1}',
+          this.$$attr.ngModel, startingTag(this.$$element));
+    }
+  },
+
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$render
+   *
+   * @description
+   * Called when the view needs to be updated. It is expected that the user of the ng-model
+   * directive will implement this method.
+   *
+   * The `$render()` method is invoked in the following situations:
+   *
+   * * `$rollbackViewValue()` is called.  If we are rolling back the view value to the last
+   *   committed value then `$render()` is called to update the input control.
+   * * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and
+   *   the `$viewValue` are different from last time.
+   *
+   * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of
+   * `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue`
+   * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be
+   * invoked if you only change a property on the objects.
+   */
+  $render: noop,
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$isEmpty
+   *
+   * @description
+   * This is called when we need to determine if the value of an input is empty.
+   *
+   * For instance, the required directive does this to work out if the input has data or not.
+   *
+   * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`.
+   *
+   * You can override this for input directives whose concept of being empty is different from the
+   * default. The `checkboxInputType` directive does this because in its case a value of `false`
+   * implies empty.
+   *
+   * @param {*} value The value of the input to check for emptiness.
+   * @returns {boolean} True if `value` is "empty".
+   */
+  $isEmpty: function(value) {
+    // eslint-disable-next-line no-self-compare
+    return isUndefined(value) || value === '' || value === null || value !== value;
+  },
+
+  $$updateEmptyClasses: function(value) {
+    if (this.$isEmpty(value)) {
+      this.$$animate.removeClass(this.$$element, NOT_EMPTY_CLASS);
+      this.$$animate.addClass(this.$$element, EMPTY_CLASS);
+    } else {
+      this.$$animate.removeClass(this.$$element, EMPTY_CLASS);
+      this.$$animate.addClass(this.$$element, NOT_EMPTY_CLASS);
+    }
+  },
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$setPristine
+   *
+   * @description
+   * Sets the control to its pristine state.
+   *
+   * This method can be called to remove the `ng-dirty` class and set the control to its pristine
+   * state (`ng-pristine` class). A model is considered to be pristine when the control
+   * has not been changed from when first compiled.
+   */
+  $setPristine: function() {
+    this.$dirty = false;
+    this.$pristine = true;
+    this.$$animate.removeClass(this.$$element, DIRTY_CLASS);
+    this.$$animate.addClass(this.$$element, PRISTINE_CLASS);
+  },
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$setDirty
+   *
+   * @description
+   * Sets the control to its dirty state.
+   *
+   * This method can be called to remove the `ng-pristine` class and set the control to its dirty
+   * state (`ng-dirty` class). A model is considered to be dirty when the control has been changed
+   * from when first compiled.
+   */
+  $setDirty: function() {
+    this.$dirty = true;
+    this.$pristine = false;
+    this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);
+    this.$$animate.addClass(this.$$element, DIRTY_CLASS);
+    this.$$parentForm.$setDirty();
+  },
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$setUntouched
+   *
+   * @description
+   * Sets the control to its untouched state.
+   *
+   * This method can be called to remove the `ng-touched` class and set the control to its
+   * untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched
+   * by default, however this function can be used to restore that state if the model has
+   * already been touched by the user.
+   */
+  $setUntouched: function() {
+    this.$touched = false;
+    this.$untouched = true;
+    this.$$animate.setClass(this.$$element, UNTOUCHED_CLASS, TOUCHED_CLASS);
+  },
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$setTouched
+   *
+   * @description
+   * Sets the control to its touched state.
+   *
+   * This method can be called to remove the `ng-untouched` class and set the control to its
+   * touched state (`ng-touched` class). A model is considered to be touched when the user has
+   * first focused the control element and then shifted focus away from the control (blur event).
+   */
+  $setTouched: function() {
+    this.$touched = true;
+    this.$untouched = false;
+    this.$$animate.setClass(this.$$element, TOUCHED_CLASS, UNTOUCHED_CLASS);
+  },
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$rollbackViewValue
+   *
+   * @description
+   * Cancel an update and reset the input element's value to prevent an update to the `$modelValue`,
+   * which may be caused by a pending debounced event or because the input is waiting for some
+   * future event.
+   *
+   * If you have an input that uses `ng-model-options` to set up debounced updates or updates that
+   * depend on special events such as `blur`, there can be a period when the `$viewValue` is out of
+   * sync with the ngModel's `$modelValue`.
+   *
+   * In this case, you can use `$rollbackViewValue()` to manually cancel the debounced / future update
+   * and reset the input to the last committed view value.
+   *
+   * It is also possible that you run into difficulties if you try to update the ngModel's `$modelValue`
+   * programmatically before these debounced/future events have resolved/occurred, because Angular's
+   * dirty checking mechanism is not able to tell whether the model has actually changed or not.
+   *
+   * The `$rollbackViewValue()` method should be called before programmatically changing the model of an
+   * input which may have such events pending. This is important in order to make sure that the
+   * input field will be updated with the new model value and any pending operations are cancelled.
+   *
+   * <example name="ng-model-cancel-update" module="cancel-update-example">
+   *   <file name="app.js">
+   *     angular.module('cancel-update-example', [])
+   *
+   *     .controller('CancelUpdateController', ['$scope', function($scope) {
+   *       $scope.model = {value1: '', value2: ''};
+   *
+   *       $scope.setEmpty = function(e, value, rollback) {
+   *         if (e.keyCode === 27) {
+   *           e.preventDefault();
+   *           if (rollback) {
+   *             $scope.myForm[value].$rollbackViewValue();
+   *           }
+   *           $scope.model[value] = '';
+   *         }
+   *       };
+   *     }]);
+   *   </file>
+   *   <file name="index.html">
+   *     <div ng-controller="CancelUpdateController">
+   *       <p>Both of these inputs are only updated if they are blurred. Hitting escape should
+   *       empty them. Follow these steps and observe the difference:</p>
+   *       <ol>
+   *         <li>Type something in the input. You will see that the model is not yet updated</li>
+   *         <li>Press the Escape key.
+   *           <ol>
+   *             <li> In the first example, nothing happens, because the model is already '', and no
+   *             update is detected. If you blur the input, the model will be set to the current view.
+   *             </li>
+   *             <li> In the second example, the pending update is cancelled, and the input is set back
+   *             to the last committed view value (''). Blurring the input does nothing.
+   *             </li>
+   *           </ol>
+   *         </li>
+   *       </ol>
+   *
+   *       <form name="myForm" ng-model-options="{ updateOn: 'blur' }">
+   *         <div>
+   *           <p id="inputDescription1">Without $rollbackViewValue():</p>
+   *           <input name="value1" aria-describedby="inputDescription1" ng-model="model.value1"
+   *                  ng-keydown="setEmpty($event, 'value1')">
+   *           value1: "{{ model.value1 }}"
+   *         </div>
+   *
+   *         <div>
+   *           <p id="inputDescription2">With $rollbackViewValue():</p>
+   *           <input name="value2" aria-describedby="inputDescription2" ng-model="model.value2"
+   *                  ng-keydown="setEmpty($event, 'value2', true)">
+   *           value2: "{{ model.value2 }}"
+   *         </div>
+   *       </form>
+   *     </div>
+   *   </file>
+       <file name="style.css">
+          div {
+            display: table-cell;
+          }
+          div:nth-child(1) {
+            padding-right: 30px;
+          }
+
+        </file>
+   * </example>
+   */
+  $rollbackViewValue: function() {
+    this.$$timeout.cancel(this.$$pendingDebounce);
+    this.$viewValue = this.$$lastCommittedViewValue;
+    this.$render();
+  },
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$validate
+   *
+   * @description
+   * Runs each of the registered validators (first synchronous validators and then
+   * asynchronous validators).
+   * If the validity changes to invalid, the model will be set to `undefined`,
+   * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`.
+   * If the validity changes to valid, it will set the model to the last available valid
+   * `$modelValue`, i.e. either the last parsed value or the last value set from the scope.
+   */
+  $validate: function() {
+    // ignore $validate before model is initialized
+    if (isNumberNaN(this.$modelValue)) {
+      return;
+    }
+
+    var viewValue = this.$$lastCommittedViewValue;
+    // Note: we use the $$rawModelValue as $modelValue might have been
+    // set to undefined during a view -> model update that found validation
+    // errors. We can't parse the view here, since that could change
+    // the model although neither viewValue nor the model on the scope changed
+    var modelValue = this.$$rawModelValue;
+
+    var prevValid = this.$valid;
+    var prevModelValue = this.$modelValue;
+
+    var allowInvalid = this.$options.getOption('allowInvalid');
+
+    var that = this;
+    this.$$runValidators(modelValue, viewValue, function(allValid) {
+      // If there was no change in validity, don't update the model
+      // This prevents changing an invalid modelValue to undefined
+      if (!allowInvalid && prevValid !== allValid) {
+        // Note: Don't check this.$valid here, as we could have
+        // external validators (e.g. calculated on the server),
+        // that just call $setValidity and need the model value
+        // to calculate their validity.
+        that.$modelValue = allValid ? modelValue : undefined;
+
+        if (that.$modelValue !== prevModelValue) {
+          that.$$writeModelToScope();
+        }
+      }
+    });
+  },
+
+  $$runValidators: function(modelValue, viewValue, doneCallback) {
+    this.$$currentValidationRunId++;
+    var localValidationRunId = this.$$currentValidationRunId;
+    var that = this;
+
+    // check parser error
+    if (!processParseErrors()) {
+      validationDone(false);
+      return;
+    }
+    if (!processSyncValidators()) {
+      validationDone(false);
+      return;
+    }
+    processAsyncValidators();
+
+    function processParseErrors() {
+      var errorKey = that.$$parserName || 'parse';
+      if (isUndefined(that.$$parserValid)) {
+        setValidity(errorKey, null);
+      } else {
+        if (!that.$$parserValid) {
+          forEach(that.$validators, function(v, name) {
+            setValidity(name, null);
+          });
+          forEach(that.$asyncValidators, function(v, name) {
+            setValidity(name, null);
+          });
+        }
+        // Set the parse error last, to prevent unsetting it, should a $validators key == parserName
+        setValidity(errorKey, that.$$parserValid);
+        return that.$$parserValid;
+      }
+      return true;
+    }
+
+    function processSyncValidators() {
+      var syncValidatorsValid = true;
+      forEach(that.$validators, function(validator, name) {
+        var result = Boolean(validator(modelValue, viewValue));
+        syncValidatorsValid = syncValidatorsValid && result;
+        setValidity(name, result);
+      });
+      if (!syncValidatorsValid) {
+        forEach(that.$asyncValidators, function(v, name) {
+          setValidity(name, null);
+        });
+        return false;
+      }
+      return true;
+    }
+
+    function processAsyncValidators() {
+      var validatorPromises = [];
+      var allValid = true;
+      forEach(that.$asyncValidators, function(validator, name) {
+        var promise = validator(modelValue, viewValue);
+        if (!isPromiseLike(promise)) {
+          throw ngModelMinErr('nopromise',
+            'Expected asynchronous validator to return a promise but got \'{0}\' instead.', promise);
+        }
+        setValidity(name, undefined);
+        validatorPromises.push(promise.then(function() {
+          setValidity(name, true);
+        }, function() {
+          allValid = false;
+          setValidity(name, false);
+        }));
+      });
+      if (!validatorPromises.length) {
+        validationDone(true);
+      } else {
+        that.$$q.all(validatorPromises).then(function() {
+          validationDone(allValid);
+        }, noop);
+      }
+    }
+
+    function setValidity(name, isValid) {
+      if (localValidationRunId === that.$$currentValidationRunId) {
+        that.$setValidity(name, isValid);
+      }
+    }
+
+    function validationDone(allValid) {
+      if (localValidationRunId === that.$$currentValidationRunId) {
+
+        doneCallback(allValid);
+      }
+    }
+  },
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$commitViewValue
+   *
+   * @description
+   * Commit a pending update to the `$modelValue`.
+   *
+   * Updates may be pending by a debounced event or because the input is waiting for a some future
+   * event defined in `ng-model-options`. this method is rarely needed as `NgModelController`
+   * usually handles calling this in response to input events.
+   */
+  $commitViewValue: function() {
+    var viewValue = this.$viewValue;
+
+    this.$$timeout.cancel(this.$$pendingDebounce);
+
+    // If the view value has not changed then we should just exit, except in the case where there is
+    // a native validator on the element. In this case the validation state may have changed even though
+    // the viewValue has stayed empty.
+    if (this.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !this.$$hasNativeValidators)) {
+      return;
+    }
+    this.$$updateEmptyClasses(viewValue);
+    this.$$lastCommittedViewValue = viewValue;
+
+    // change to dirty
+    if (this.$pristine) {
+      this.$setDirty();
+    }
+    this.$$parseAndValidate();
+  },
+
+  $$parseAndValidate: function() {
+    var viewValue = this.$$lastCommittedViewValue;
+    var modelValue = viewValue;
+    var that = this;
+
+    this.$$parserValid = isUndefined(modelValue) ? undefined : true;
+
+    if (this.$$parserValid) {
+      for (var i = 0; i < this.$parsers.length; i++) {
+        modelValue = this.$parsers[i](modelValue);
+        if (isUndefined(modelValue)) {
+          this.$$parserValid = false;
+          break;
+        }
+      }
+    }
+    if (isNumberNaN(this.$modelValue)) {
+      // this.$modelValue has not been touched yet...
+      this.$modelValue = this.$$ngModelGet(this.$$scope);
+    }
+    var prevModelValue = this.$modelValue;
+    var allowInvalid = this.$options.getOption('allowInvalid');
+    this.$$rawModelValue = modelValue;
+
+    if (allowInvalid) {
+      this.$modelValue = modelValue;
+      writeToModelIfNeeded();
+    }
+
+    // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.
+    // This can happen if e.g. $setViewValue is called from inside a parser
+    this.$$runValidators(modelValue, this.$$lastCommittedViewValue, function(allValid) {
+      if (!allowInvalid) {
+        // Note: Don't check this.$valid here, as we could have
+        // external validators (e.g. calculated on the server),
+        // that just call $setValidity and need the model value
+        // to calculate their validity.
+        that.$modelValue = allValid ? modelValue : undefined;
+        writeToModelIfNeeded();
+      }
+    });
+
+    function writeToModelIfNeeded() {
+      if (that.$modelValue !== prevModelValue) {
+        that.$$writeModelToScope();
+      }
+    }
+  },
+
+  $$writeModelToScope: function() {
+    this.$$ngModelSet(this.$$scope, this.$modelValue);
+    forEach(this.$viewChangeListeners, function(listener) {
+      try {
+        listener();
+      } catch (e) {
+        // eslint-disable-next-line no-invalid-this
+        this.$$exceptionHandler(e);
+      }
+    }, this);
+  },
+
+  /**
+   * @ngdoc method
+   * @name ngModel.NgModelController#$setViewValue
+   *
+   * @description
+   * Update the view value.
+   *
+   * This method should be called when a control wants to change the view value; typically,
+   * this is done from within a DOM event handler. For example, the {@link ng.directive:input input}
+   * directive calls it when the value of the input changes and {@link ng.directive:select select}
+   * calls it when an option is selected.
+   *
+   * When `$setViewValue` is called, the new `value` will be staged for committing through the `$parsers`
+   * and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged
+   * value is sent directly for processing through the `$parsers` pipeline. After this, the `$validators` and
+   * `$asyncValidators` are called and the value is applied to `$modelValue`.
+   * Finally, the value is set to the **expression** specified in the `ng-model` attribute and
+   * all the registered change listeners, in the `$viewChangeListeners` list are called.
+   *
+   * In case the {@link ng.directive:ngModelOptions ngModelOptions} directive is used with `updateOn`
+   * and the `default` trigger is not listed, all those actions will remain pending until one of the
+   * `updateOn` events is triggered on the DOM element.
+   * All these actions will be debounced if the {@link ng.directive:ngModelOptions ngModelOptions}
+   * directive is used with a custom debounce for this particular event.
+   * Note that a `$digest` is only triggered once the `updateOn` events are fired, or if `debounce`
+   * is specified, once the timer runs out.
+   *
+   * When used with standard inputs, the view value will always be a string (which is in some cases
+   * parsed into another type, such as a `Date` object for `input[date]`.)
+   * However, custom controls might also pass objects to this method. In this case, we should make
+   * a copy of the object before passing it to `$setViewValue`. This is because `ngModel` does not
+   * perform a deep watch of objects, it only looks for a change of identity. If you only change
+   * the property of the object then ngModel will not realize that the object has changed and
+   * will not invoke the `$parsers` and `$validators` pipelines. For this reason, you should
+   * not change properties of the copy once it has been passed to `$setViewValue`.
+   * Otherwise you may cause the model value on the scope to change incorrectly.
+   *
+   * <div class="alert alert-info">
+   * In any case, the value passed to the method should always reflect the current value
+   * of the control. For example, if you are calling `$setViewValue` for an input element,
+   * you should pass the input DOM value. Otherwise, the control and the scope model become
+   * out of sync. It's also important to note that `$setViewValue` does not call `$render` or change
+   * the control's DOM value in any way. If we want to change the control's DOM value
+   * programmatically, we should update the `ngModel` scope expression. Its new value will be
+   * picked up by the model controller, which will run it through the `$formatters`, `$render` it
+   * to update the DOM, and finally call `$validate` on it.
+   * </div>
+   *
+   * @param {*} value value from the view.
+   * @param {string} trigger Event that triggered the update.
+   */
+  $setViewValue: function(value, trigger) {
+    this.$viewValue = value;
+    if (this.$options.getOption('updateOnDefault')) {
+      this.$$debounceViewValueCommit(trigger);
+    }
+  },
+
+  $$debounceViewValueCommit: function(trigger) {
+    var debounceDelay = this.$options.getOption('debounce');
+
+    if (isNumber(debounceDelay[trigger])) {
+      debounceDelay = debounceDelay[trigger];
+    } else if (isNumber(debounceDelay['default'])) {
+      debounceDelay = debounceDelay['default'];
+    }
+
+    this.$$timeout.cancel(this.$$pendingDebounce);
+    var that = this;
+    if (debounceDelay > 0) { // this fails if debounceDelay is an object
+      this.$$pendingDebounce = this.$$timeout(function() {
+        that.$commitViewValue();
+      }, debounceDelay);
+    } else if (this.$$scope.$root.$$phase) {
+      this.$commitViewValue();
+    } else {
+      this.$$scope.$apply(function() {
+        that.$commitViewValue();
+      });
+    }
+  },
+
+  /**
+   * @ngdoc method
+   *
+   * @name ngModel.NgModelController#$overrideModelOptions
+   *
+   * @description
+   *
+   * Override the current model options settings programmatically.
+   *
+   * The previous `ModelOptions` value will not be modified. Instead, a
+   * new `ModelOptions` object will inherit from the previous one overriding
+   * or inheriting settings that are defined in the given parameter.
+   *
+   * See {@link ngModelOptions} for information about what options can be specified
+   * and how model option inheritance works.
+   *
+   * @param {Object} options a hash of settings to override the previous options
+   *
+   */
+  $overrideModelOptions: function(options) {
+    this.$options = this.$options.createChild(options);
+  }
+};
+
+function setupModelWatcher(ctrl) {
+  // model -> value
+  // Note: we cannot use a normal scope.$watch as we want to detect the following:
+  // 1. scope value is 'a'
+  // 2. user enters 'b'
+  // 3. ng-change kicks in and reverts scope value to 'a'
+  //    -> scope value did not change since the last digest as
+  //       ng-change executes in apply phase
+  // 4. view should be changed back to 'a'
+  ctrl.$$scope.$watch(function ngModelWatch() {
+    var modelValue = ctrl.$$ngModelGet(ctrl.$$scope);
+
+    // if scope model value and ngModel value are out of sync
+    // TODO(perf): why not move this to the action fn?
+    if (modelValue !== ctrl.$modelValue &&
+       // checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator
+        // eslint-disable-next-line no-self-compare
+       (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue)
+    ) {
+      ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
+      ctrl.$$parserValid = undefined;
+
+      var formatters = ctrl.$formatters,
+          idx = formatters.length;
+
+      var viewValue = modelValue;
+      while (idx--) {
+        viewValue = formatters[idx](viewValue);
+      }
+      if (ctrl.$viewValue !== viewValue) {
+        ctrl.$$updateEmptyClasses(viewValue);
+        ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
+        ctrl.$render();
+
+        // It is possible that model and view value have been updated during render
+        ctrl.$$runValidators(ctrl.$modelValue, ctrl.$viewValue, noop);
+      }
+    }
+
+    return modelValue;
+  });
+}
+
+/**
+ * @ngdoc method
+ * @name ngModel.NgModelController#$setValidity
+ *
+ * @description
+ * Change the validity state, and notify the form.
+ *
+ * This method can be called within $parsers/$formatters or a custom validation implementation.
+ * However, in most cases it should be sufficient to use the `ngModel.$validators` and
+ * `ngModel.$asyncValidators` collections which will call `$setValidity` automatically.
+ *
+ * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be assigned
+ *        to either `$error[validationErrorKey]` or `$pending[validationErrorKey]`
+ *        (for unfulfilled `$asyncValidators`), so that it is available for data-binding.
+ *        The `validationErrorKey` should be in camelCase and will get converted into dash-case
+ *        for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error`
+ *        class and can be bound to as  `{{someForm.someControl.$error.myError}}` .
+ * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending (undefined),
+ *                          or skipped (null). Pending is used for unfulfilled `$asyncValidators`.
+ *                          Skipped is used by Angular when validators do not run because of parse errors and
+ *                          when `$asyncValidators` do not run because any of the `$validators` failed.
+ */
+addSetValidityMethod({
+  clazz: NgModelController,
+  set: function(object, property) {
+    object[property] = true;
+  },
+  unset: function(object, property) {
+    delete object[property];
+  }
+});
+
+
+/**
+ * @ngdoc directive
+ * @name ngModel
+ *
+ * @element input
+ * @priority 1
+ *
+ * @description
+ * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a
+ * property on the scope using {@link ngModel.NgModelController NgModelController},
+ * which is created and exposed by this directive.
+ *
+ * `ngModel` is responsible for:
+ *
+ * - Binding the view into the model, which other directives such as `input`, `textarea` or `select`
+ *   require.
+ * - Providing validation behavior (i.e. required, number, email, url).
+ * - Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors).
+ * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`, `ng-touched`,
+ *   `ng-untouched`, `ng-empty`, `ng-not-empty`) including animations.
+ * - Registering the control with its parent {@link ng.directive:form form}.
+ *
+ * Note: `ngModel` will try to bind to the property given by evaluating the expression on the
+ * current scope. If the property doesn't already exist on this scope, it will be created
+ * implicitly and added to the scope.
+ *
+ * For best practices on using `ngModel`, see:
+ *
+ *  - [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes)
+ *
+ * For basic examples, how to use `ngModel`, see:
+ *
+ *  - {@link ng.directive:input input}
+ *    - {@link input[text] text}
+ *    - {@link input[checkbox] checkbox}
+ *    - {@link input[radio] radio}
+ *    - {@link input[number] number}
+ *    - {@link input[email] email}
+ *    - {@link input[url] url}
+ *    - {@link input[date] date}
+ *    - {@link input[datetime-local] datetime-local}
+ *    - {@link input[time] time}
+ *    - {@link input[month] month}
+ *    - {@link input[week] week}
+ *  - {@link ng.directive:select select}
+ *  - {@link ng.directive:textarea textarea}
+ *
+ * # Complex Models (objects or collections)
+ *
+ * By default, `ngModel` watches the model by reference, not value. This is important to know when
+ * binding inputs to models that are objects (e.g. `Date`) or collections (e.g. arrays). If only properties of the
+ * object or collection change, `ngModel` will not be notified and so the input will not be  re-rendered.
+ *
+ * The model must be assigned an entirely new object or collection before a re-rendering will occur.
+ *
+ * Some directives have options that will cause them to use a custom `$watchCollection` on the model expression
+ * - for example, `ngOptions` will do so when a `track by` clause is included in the comprehension expression or
+ * if the select is given the `multiple` attribute.
+ *
+ * The `$watchCollection()` method only does a shallow comparison, meaning that changing properties deeper than the
+ * first level of the object (or only changing the properties of an item in the collection if it's an array) will still
+ * not trigger a re-rendering of the model.
+ *
+ * # CSS classes
+ * The following CSS classes are added and removed on the associated input/select/textarea element
+ * depending on the validity of the model.
+ *
+ *  - `ng-valid`: the model is valid
+ *  - `ng-invalid`: the model is invalid
+ *  - `ng-valid-[key]`: for each valid key added by `$setValidity`
+ *  - `ng-invalid-[key]`: for each invalid key added by `$setValidity`
+ *  - `ng-pristine`: the control hasn't been interacted with yet
+ *  - `ng-dirty`: the control has been interacted with
+ *  - `ng-touched`: the control has been blurred
+ *  - `ng-untouched`: the control hasn't been blurred
+ *  - `ng-pending`: any `$asyncValidators` are unfulfilled
+ *  - `ng-empty`: the view does not contain a value or the value is deemed "empty", as defined
+ *     by the {@link ngModel.NgModelController#$isEmpty} method
+ *  - `ng-not-empty`: the view contains a non-empty value
+ *
+ * Keep in mind that ngAnimate can detect each of these classes when added and removed.
+ *
+ * ## Animation Hooks
+ *
+ * Animations within models are triggered when any of the associated CSS classes are added and removed
+ * on the input element which is attached to the model. These classes include: `.ng-pristine`, `.ng-dirty`,
+ * `.ng-invalid` and `.ng-valid` as well as any other validations that are performed on the model itself.
+ * The animations that are triggered within ngModel are similar to how they work in ngClass and
+ * animations can be hooked into using CSS transitions, keyframes as well as JS animations.
+ *
+ * The following example shows a simple way to utilize CSS transitions to style an input element
+ * that has been rendered as invalid after it has been validated:
+ *
+ * <pre>
+ * //be sure to include ngAnimate as a module to hook into more
+ * //advanced animations
+ * .my-input {
+ *   transition:0.5s linear all;
+ *   background: white;
+ * }
+ * .my-input.ng-invalid {
+ *   background: red;
+ *   color:white;
+ * }
+ * </pre>
+ *
+ * @example
+ * <example deps="angular-animate.js" animations="true" fixBase="true" module="inputExample" name="ng-model">
+     <file name="index.html">
+       <script>
+        angular.module('inputExample', [])
+          .controller('ExampleController', ['$scope', function($scope) {
+            $scope.val = '1';
+          }]);
+       </script>
+       <style>
+         .my-input {
+           transition:all linear 0.5s;
+           background: transparent;
+         }
+         .my-input.ng-invalid {
+           color:white;
+           background: red;
+         }
+       </style>
+       <p id="inputDescription">
+        Update input to see transitions when valid/invalid.
+        Integer is a valid value.
+       </p>
+       <form name="testForm" ng-controller="ExampleController">
+         <input ng-model="val" ng-pattern="/^\d+$/" name="anim" class="my-input"
+                aria-describedby="inputDescription" />
+       </form>
+     </file>
+ * </example>
+ *
+ * ## Binding to a getter/setter
+ *
+ * Sometimes it's helpful to bind `ngModel` to a getter/setter function.  A getter/setter is a
+ * function that returns a representation of the model when called with zero arguments, and sets
+ * the internal state of a model when called with an argument. It's sometimes useful to use this
+ * for models that have an internal representation that's different from what the model exposes
+ * to the view.
+ *
+ * <div class="alert alert-success">
+ * **Best Practice:** It's best to keep getters fast because Angular is likely to call them more
+ * frequently than other parts of your code.
+ * </div>
+ *
+ * You use this behavior by adding `ng-model-options="{ getterSetter: true }"` to an element that
+ * has `ng-model` attached to it. You can also add `ng-model-options="{ getterSetter: true }"` to
+ * a `<form>`, which will enable this behavior for all `<input>`s within it. See
+ * {@link ng.directive:ngModelOptions `ngModelOptions`} for more.
+ *
+ * The following example shows how to use `ngModel` with a getter/setter:
+ *
+ * @example
+ * <example name="ngModel-getter-setter" module="getterSetterExample">
+     <file name="index.html">
+       <div ng-controller="ExampleController">
+         <form name="userForm">
+           <label>Name:
+             <input type="text" name="userName"
+                    ng-model="user.name"
+                    ng-model-options="{ getterSetter: true }" />
+           </label>
+         </form>
+         <pre>user.name = <span ng-bind="user.name()"></span></pre>
+       </div>
+     </file>
+     <file name="app.js">
+       angular.module('getterSetterExample', [])
+         .controller('ExampleController', ['$scope', function($scope) {
+           var _name = 'Brian';
+           $scope.user = {
+             name: function(newName) {
+              // Note that newName can be undefined for two reasons:
+              // 1. Because it is called as a getter and thus called with no arguments
+              // 2. Because the property should actually be set to undefined. This happens e.g. if the
+              //    input is invalid
+              return arguments.length ? (_name = newName) : _name;
+             }
+           };
+         }]);
+     </file>
+ * </example>
+ */
+var ngModelDirective = ['$rootScope', function($rootScope) {
+  return {
+    restrict: 'A',
+    require: ['ngModel', '^?form', '^?ngModelOptions'],
+    controller: NgModelController,
+    // Prelink needs to run before any input directive
+    // so that we can set the NgModelOptions in NgModelController
+    // before anyone else uses it.
+    priority: 1,
+    compile: function ngModelCompile(element) {
+      // Setup initial state of the control
+      element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS);
+
+      return {
+        pre: function ngModelPreLink(scope, element, attr, ctrls) {
+          var modelCtrl = ctrls[0],
+              formCtrl = ctrls[1] || modelCtrl.$$parentForm,
+              optionsCtrl = ctrls[2];
+
+          if (optionsCtrl) {
+            modelCtrl.$options = optionsCtrl.$options;
+          }
+
+          modelCtrl.$$initGetterSetters();
+
+          // notify others, especially parent forms
+          formCtrl.$addControl(modelCtrl);
+
+          attr.$observe('name', function(newValue) {
+            if (modelCtrl.$name !== newValue) {
+              modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue);
+            }
+          });
+
+          scope.$on('$destroy', function() {
+            modelCtrl.$$parentForm.$removeControl(modelCtrl);
+          });
+        },
+        post: function ngModelPostLink(scope, element, attr, ctrls) {
+          var modelCtrl = ctrls[0];
+          if (modelCtrl.$options.getOption('updateOn')) {
+            element.on(modelCtrl.$options.getOption('updateOn'), function(ev) {
+              modelCtrl.$$debounceViewValueCommit(ev && ev.type);
+            });
+          }
+
+          function setTouched() {
+            modelCtrl.$setTouched();
+          }
+
+          element.on('blur', function() {
+            if (modelCtrl.$touched) return;
+
+            if ($rootScope.$$phase) {
+              scope.$evalAsync(setTouched);
+            } else {
+              scope.$apply(setTouched);
+            }
+          });
+        }
+      };
+    }
+  };
+}];
+
+/* exported defaultModelOptions */
+var defaultModelOptions;
+var DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/;
+
+/**
+ * @ngdoc type
+ * @name ModelOptions
+ * @description
+ * A container for the options set by the {@link ngModelOptions} directive
+ */
+function ModelOptions(options) {
+  this.$$options = options;
+}
+
+ModelOptions.prototype = {
+
+  /**
+   * @ngdoc method
+   * @name ModelOptions#getOption
+   * @param {string} name the name of the option to retrieve
+   * @returns {*} the value of the option
+   * @description
+   * Returns the value of the given option
+   */
+  getOption: function(name) {
+    return this.$$options[name];
+  },
+
+  /**
+   * @ngdoc method
+   * @name ModelOptions#createChild
+   * @param {Object} options a hash of options for the new child that will override the parent's options
+   * @return {ModelOptions} a new `ModelOptions` object initialized with the given options.
+   */
+  createChild: function(options) {
+    var inheritAll = false;
+
+    // make a shallow copy
+    options = extend({}, options);
+
+    // Inherit options from the parent if specified by the value `"$inherit"`
+    forEach(options, /* @this */ function(option, key) {
+      if (option === '$inherit') {
+        if (key === '*') {
+          inheritAll = true;
+        } else {
+          options[key] = this.$$options[key];
+          // `updateOn` is special so we must also inherit the `updateOnDefault` option
+          if (key === 'updateOn') {
+            options.updateOnDefault = this.$$options.updateOnDefault;
+          }
+        }
+      } else {
+        if (key === 'updateOn') {
+          // If the `updateOn` property contains the `default` event then we have to remove
+          // it from the event list and set the `updateOnDefault` flag.
+          options.updateOnDefault = false;
+          options[key] = trim(option.replace(DEFAULT_REGEXP, function() {
+            options.updateOnDefault = true;
+            return ' ';
+          }));
+        }
+      }
+    }, this);
+
+    if (inheritAll) {
+      // We have a property of the form: `"*": "$inherit"`
+      delete options['*'];
+      defaults(options, this.$$options);
+    }
+
+    // Finally add in any missing defaults
+    defaults(options, defaultModelOptions.$$options);
+
+    return new ModelOptions(options);
+  }
+};
+
+
+defaultModelOptions = new ModelOptions({
+  updateOn: '',
+  updateOnDefault: true,
+  debounce: 0,
+  getterSetter: false,
+  allowInvalid: false,
+  timezone: null
+});
+
+
+/**
+ * @ngdoc directive
+ * @name ngModelOptions
+ *
+ * @description
+ * This directive allows you to modify the behaviour of {@link ngModel} directives within your
+ * application. You can specify an `ngModelOptions` directive on any element. All {@link ngModel}
+ * directives will use the options of their nearest `ngModelOptions` ancestor.
+ *
+ * The `ngModelOptions` settings are found by evaluating the value of the attribute directive as
+ * an Angular expression. This expression should evaluate to an object, whose properties contain
+ * the settings. For example: `<div "ng-model-options"="{ debounce: 100 }"`.
+ *
+ * ## Inheriting Options
+ *
+ * You can specify that an `ngModelOptions` setting should be inherited from a parent `ngModelOptions`
+ * directive by giving it the value of `"$inherit"`.
+ * Then it will inherit that setting from the first `ngModelOptions` directive found by traversing up the
+ * DOM tree. If there is no ancestor element containing an `ngModelOptions` directive then default settings
+ * will be used.
+ *
+ * For example given the following fragment of HTML
+ *
+ *
+ * ```html
+ * <div ng-model-options="{ allowInvalid: true, debounce: 200 }">
+ *   <form ng-model-options="{ updateOn: 'blur', allowInvalid: '$inherit' }">
+ *     <input ng-model-options="{ updateOn: 'default', allowInvalid: '$inherit' }" />
+ *   </form>
+ * </div>
+ * ```
+ *
+ * the `input` element will have the following settings
+ *
+ * ```js
+ * { allowInvalid: true, updateOn: 'default', debounce: 0 }
+ * ```
+ *
+ * Notice that the `debounce` setting was not inherited and used the default value instead.
+ *
+ * You can specify that all undefined settings are automatically inherited from an ancestor by
+ * including a property with key of `"*"` and value of `"$inherit"`.
+ *
+ * For example given the following fragment of HTML
+ *
+ *
+ * ```html
+ * <div ng-model-options="{ allowInvalid: true, debounce: 200 }">
+ *   <form ng-model-options="{ updateOn: 'blur', "*": '$inherit' }">
+ *     <input ng-model-options="{ updateOn: 'default', "*": '$inherit' }" />
+ *   </form>
+ * </div>
+ * ```
+ *
+ * the `input` element will have the following settings
+ *
+ * ```js
+ * { allowInvalid: true, updateOn: 'default', debounce: 200 }
+ * ```
+ *
+ * Notice that the `debounce` setting now inherits the value from the outer `<div>` element.
+ *
+ * If you are creating a reusable component then you should be careful when using `"*": "$inherit"`
+ * since you may inadvertently inherit a setting in the future that changes the behavior of your component.
+ *
+ *
+ * ## Triggering and debouncing model updates
+ *
+ * The `updateOn` and `debounce` properties allow you to specify a custom list of events that will
+ * trigger a model update and/or a debouncing delay so that the actual update only takes place when
+ * a timer expires; this timer will be reset after another change takes place.
+ *
+ * Given the nature of `ngModelOptions`, the value displayed inside input fields in the view might
+ * be different from the value in the actual model. This means that if you update the model you
+ * should also invoke {@link ngModel.NgModelController#$rollbackViewValue} on the relevant input field in
+ * order to make sure it is synchronized with the model and that any debounced action is canceled.
+ *
+ * The easiest way to reference the control's {@link ngModel.NgModelController#$rollbackViewValue}
+ * method is by making sure the input is placed inside a form that has a `name` attribute. This is
+ * important because `form` controllers are published to the related scope under the name in their
+ * `name` attribute.
+ *
+ * Any pending changes will take place immediately when an enclosing form is submitted via the
+ * `submit` event. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`
+ * to have access to the updated model.
+ *
+ * The following example shows how to override immediate updates. Changes on the inputs within the
+ * form will update the model only when the control loses focus (blur event). If `escape` key is
+ * pressed while the input field is focused, the value is reset to the value in the current model.
+ *
+ * <example name="ngModelOptions-directive-blur" module="optionsExample">
+ *   <file name="index.html">
+ *     <div ng-controller="ExampleController">
+ *       <form name="userForm">
+ *         <label>
+ *           Name:
+ *           <input type="text" name="userName"
+ *                  ng-model="user.name"
+ *                  ng-model-options="{ updateOn: 'blur' }"
+ *                  ng-keyup="cancel($event)" />
+ *         </label><br />
+ *         <label>
+ *           Other data:
+ *           <input type="text" ng-model="user.data" />
+ *         </label><br />
+ *       </form>
+ *       <pre>user.name = <span ng-bind="user.name"></span></pre>
+ *     </div>
+ *   </file>
+ *   <file name="app.js">
+ *     angular.module('optionsExample', [])
+ *       .controller('ExampleController', ['$scope', function($scope) {
+ *         $scope.user = { name: 'say', data: '' };
+ *
+ *         $scope.cancel = function(e) {
+ *           if (e.keyCode === 27) {
+ *             $scope.userForm.userName.$rollbackViewValue();
+ *           }
+ *         };
+ *       }]);
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+ *     var model = element(by.binding('user.name'));
+ *     var input = element(by.model('user.name'));
+ *     var other = element(by.model('user.data'));
+ *
+ *     it('should allow custom events', function() {
+ *       input.sendKeys(' hello');
+ *       input.click();
+ *       expect(model.getText()).toEqual('say');
+ *       other.click();
+ *       expect(model.getText()).toEqual('say hello');
+ *     });
+ *
+ *     it('should $rollbackViewValue when model changes', function() {
+ *       input.sendKeys(' hello');
+ *       expect(input.getAttribute('value')).toEqual('say hello');
+ *       input.sendKeys(protractor.Key.ESCAPE);
+ *       expect(input.getAttribute('value')).toEqual('say');
+ *       other.click();
+ *       expect(model.getText()).toEqual('say');
+ *     });
+ *   </file>
+ * </example>
+ *
+ * The next example shows how to debounce model changes. Model will be updated only 1 sec after last change.
+ * If the `Clear` button is pressed, any debounced action is canceled and the value becomes empty.
+ *
+ * <example name="ngModelOptions-directive-debounce" module="optionsExample">
+ *   <file name="index.html">
+ *     <div ng-controller="ExampleController">
+ *       <form name="userForm">
+ *         Name:
+ *         <input type="text" name="userName"
+ *                ng-model="user.name"
+ *                ng-model-options="{ debounce: 1000 }" />
+ *         <button ng-click="userForm.userName.$rollbackViewValue(); user.name=''">Clear</button><br />
+ *       </form>
+ *       <pre>user.name = <span ng-bind="user.name"></span></pre>
+ *     </div>
+ *   </file>
+ *   <file name="app.js">
+ *     angular.module('optionsExample', [])
+ *       .controller('ExampleController', ['$scope', function($scope) {
+ *         $scope.user = { name: 'say' };
+ *       }]);
+ *   </file>
+ * </example>
+ *
+ * ## Model updates and validation
+ *
+ * The default behaviour in `ngModel` is that the model value is set to `undefined` when the
+ * validation determines that the value is invalid. By setting the `allowInvalid` property to true,
+ * the model will still be updated even if the value is invalid.
+ *
+ *
+ * ## Connecting to the scope
+ *
+ * By setting the `getterSetter` property to true you are telling ngModel that the `ngModel` expression
+ * on the scope refers to a "getter/setter" function rather than the value itself.
+ *
+ * The following example shows how to bind to getter/setters:
+ *
+ * <example name="ngModelOptions-directive-getter-setter" module="getterSetterExample">
+ *   <file name="index.html">
+ *     <div ng-controller="ExampleController">
+ *       <form name="userForm">
+ *         <label>
+ *           Name:
+ *           <input type="text" name="userName"
+ *                  ng-model="user.name"
+ *                  ng-model-options="{ getterSetter: true }" />
+ *         </label>
+ *       </form>
+ *       <pre>user.name = <span ng-bind="user.name()"></span></pre>
+ *     </div>
+ *   </file>
+ *   <file name="app.js">
+ *     angular.module('getterSetterExample', [])
+ *       .controller('ExampleController', ['$scope', function($scope) {
+ *         var _name = 'Brian';
+ *         $scope.user = {
+ *           name: function(newName) {
+ *             return angular.isDefined(newName) ? (_name = newName) : _name;
+ *           }
+ *         };
+ *       }]);
+ *   </file>
+ * </example>
+ *
+ *
+ * ## Specifying timezones
+ *
+ * You can specify the timezone that date/time input directives expect by providing its name in the
+ * `timezone` property.
+ *
+ * @param {Object} ngModelOptions options to apply to {@link ngModel} directives on this element and
+ *   and its descendents. Valid keys are:
+ *   - `updateOn`: string specifying which event should the input be bound to. You can set several
+ *     events using an space delimited list. There is a special event called `default` that
+ *     matches the default events belonging to the control.
+ *   - `debounce`: integer value which contains the debounce model update value in milliseconds. A
+ *     value of 0 triggers an immediate update. If an object is supplied instead, you can specify a
+ *     custom value for each event. For example:
+ *     ```
+ *     ng-model-options="{
+ *       updateOn: 'default blur',
+ *       debounce: { 'default': 500, 'blur': 0 }
+ *     }"
+ *     ```
+ *   - `allowInvalid`: boolean value which indicates that the model can be set with values that did
+ *     not validate correctly instead of the default behavior of setting the model to undefined.
+ *   - `getterSetter`: boolean value which determines whether or not to treat functions bound to
+ *     `ngModel` as getters/setters.
+ *   - `timezone`: Defines the timezone to be used to read/write the `Date` instance in the model for
+ *     `<input type="date" />`, `<input type="time" />`, ... . It understands UTC/GMT and the
+ *     continental US time zone abbreviations, but for general use, use a time zone offset, for
+ *     example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)
+ *     If not specified, the timezone of the browser will be used.
+ *
+ */
+var ngModelOptionsDirective = function() {
+  NgModelOptionsController.$inject = ['$attrs', '$scope'];
+  function NgModelOptionsController($attrs, $scope) {
+    this.$$attrs = $attrs;
+    this.$$scope = $scope;
+  }
+  NgModelOptionsController.prototype = {
+    $onInit: function() {
+      var parentOptions = this.parentCtrl ? this.parentCtrl.$options : defaultModelOptions;
+      var modelOptionsDefinition = this.$$scope.$eval(this.$$attrs.ngModelOptions);
+
+      this.$options = parentOptions.createChild(modelOptionsDefinition);
+    }
+  };
+
+  return {
+    restrict: 'A',
+    // ngModelOptions needs to run before ngModel and input directives
+    priority: 10,
+    require: {parentCtrl: '?^^ngModelOptions'},
+    bindToController: true,
+    controller: NgModelOptionsController
+  };
+};
+
+
+// shallow copy over values from `src` that are not already specified on `dst`
+function defaults(dst, src) {
+  forEach(src, function(value, key) {
+    if (!isDefined(dst[key])) {
+      dst[key] = value;
+    }
+  });
+}
+
+/**
+ * @ngdoc directive
+ * @name ngNonBindable
+ * @restrict AC
+ * @priority 1000
+ *
+ * @description
+ * The `ngNonBindable` directive tells Angular not to compile or bind the contents of the current
+ * DOM element. This is useful if the element contains what appears to be Angular directives and
+ * bindings but which should be ignored by Angular. This could be the case if you have a site that
+ * displays snippets of code, for instance.
+ *
+ * @element ANY
+ *
+ * @example
+ * In this example there are two locations where a simple interpolation binding (`{{}}`) is present,
+ * but the one wrapped in `ngNonBindable` is left alone.
+ *
+ * @example
+    <example name="ng-non-bindable">
+      <file name="index.html">
+        <div>Normal: {{1 + 2}}</div>
+        <div ng-non-bindable>Ignored: {{1 + 2}}</div>
+      </file>
+      <file name="protractor.js" type="protractor">
+       it('should check ng-non-bindable', function() {
+         expect(element(by.binding('1 + 2')).getText()).toContain('3');
+         expect(element.all(by.css('div')).last().getText()).toMatch(/1 \+ 2/);
+       });
+      </file>
+    </example>
+ */
+var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
+
+/* exported ngOptionsDirective */
+
+/* global jqLiteRemove */
+
+var ngOptionsMinErr = minErr('ngOptions');
+
+/**
+ * @ngdoc directive
+ * @name ngOptions
+ * @restrict A
+ *
+ * @description
+ *
+ * The `ngOptions` attribute can be used to dynamically generate a list of `<option>`
+ * elements for the `<select>` element using the array or object obtained by evaluating the
+ * `ngOptions` comprehension expression.
+ *
+ * In many cases, {@link ng.directive:ngRepeat ngRepeat} can be used on `<option>` elements instead of
+ * `ngOptions` to achieve a similar result. However, `ngOptions` provides some benefits:
+ * - more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the
+ * comprehension expression
+ * - reduced memory consumption by not creating a new scope for each repeated instance
+ * - increased render speed by creating the options in a documentFragment instead of individually
+ *
+ * When an item in the `<select>` menu is selected, the array element or object property
+ * represented by the selected option will be bound to the model identified by the `ngModel`
+ * directive.
+ *
+ * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
+ * be nested into the `<select>` element. This element will then represent the `null` or "not selected"
+ * option. See example below for demonstration.
+ *
+ * ## Complex Models (objects or collections)
+ *
+ * By default, `ngModel` watches the model by reference, not value. This is important to know when
+ * binding the select to a model that is an object or a collection.
+ *
+ * One issue occurs if you want to preselect an option. For example, if you set
+ * the model to an object that is equal to an object in your collection, `ngOptions` won't be able to set the selection,
+ * because the objects are not identical. So by default, you should always reference the item in your collection
+ * for preselections, e.g.: `$scope.selected = $scope.collection[3]`.
+ *
+ * Another solution is to use a `track by` clause, because then `ngOptions` will track the identity
+ * of the item not by reference, but by the result of the `track by` expression. For example, if your
+ * collection items have an id property, you would `track by item.id`.
+ *
+ * A different issue with objects or collections is that ngModel won't detect if an object property or
+ * a collection item changes. For that reason, `ngOptions` additionally watches the model using
+ * `$watchCollection`, when the expression contains a `track by` clause or the the select has the `multiple` attribute.
+ * This allows ngOptions to trigger a re-rendering of the options even if the actual object/collection
+ * has not changed identity, but only a property on the object or an item in the collection changes.
+ *
+ * Note that `$watchCollection` does a shallow comparison of the properties of the object (or the items in the collection
+ * if the model is an array). This means that changing a property deeper than the first level inside the
+ * object/collection will not trigger a re-rendering.
+ *
+ * ## `select` **`as`**
+ *
+ * Using `select` **`as`** will bind the result of the `select` expression to the model, but
+ * the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)
+ * or property name (for object data sources) of the value within the collection. If a **`track by`** expression
+ * is used, the result of that expression will be set as the value of the `option` and `select` elements.
+ *
+ *
+ * ### `select` **`as`** and **`track by`**
+ *
+ * <div class="alert alert-warning">
+ * Be careful when using `select` **`as`** and **`track by`** in the same expression.
+ * </div>
+ *
+ * Given this array of items on the $scope:
+ *
+ * ```js
+ * $scope.items = [{
+ *   id: 1,
+ *   label: 'aLabel',
+ *   subItem: { name: 'aSubItem' }
+ * }, {
+ *   id: 2,
+ *   label: 'bLabel',
+ *   subItem: { name: 'bSubItem' }
+ * }];
+ * ```
+ *
+ * This will work:
+ *
+ * ```html
+ * <select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
+ * ```
+ * ```js
+ * $scope.selected = $scope.items[0];
+ * ```
+ *
+ * but this will not work:
+ *
+ * ```html
+ * <select ng-options="item.subItem as item.label for item in items track by item.id" ng-model="selected"></select>
+ * ```
+ * ```js
+ * $scope.selected = $scope.items[0].subItem;
+ * ```
+ *
+ * In both examples, the **`track by`** expression is applied successfully to each `item` in the
+ * `items` array. Because the selected option has been set programmatically in the controller, the
+ * **`track by`** expression is also applied to the `ngModel` value. In the first example, the
+ * `ngModel` value is `items[0]` and the **`track by`** expression evaluates to `items[0].id` with
+ * no issue. In the second example, the `ngModel` value is `items[0].subItem` and the **`track by`**
+ * expression evaluates to `items[0].subItem.id` (which is undefined). As a result, the model value
+ * is not matched against any `<option>` and the `<select>` appears as having no selected value.
+ *
+ *
+ * @param {string} ngModel Assignable AngularJS expression to data-bind to.
+ * @param {comprehension_expression} ngOptions in one of the following forms:
+ *
+ *   * for array data sources:
+ *     * `label` **`for`** `value` **`in`** `array`
+ *     * `select` **`as`** `label` **`for`** `value` **`in`** `array`
+ *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array`
+ *     * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array`
+ *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
+ *     * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
+ *     * `label` **`for`** `value` **`in`** `array` | orderBy:`orderexpr` **`track by`** `trackexpr`
+ *        (for including a filter with `track by`)
+ *   * for object data sources:
+ *     * `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
+ *     * `select` **`as`** `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
+ *     * `label` **`group by`** `group` **`for (`**`key`**`,`** `value`**`) in`** `object`
+ *     * `label` **`disable when`** `disable` **`for (`**`key`**`,`** `value`**`) in`** `object`
+ *     * `select` **`as`** `label` **`group by`** `group`
+ *         **`for` `(`**`key`**`,`** `value`**`) in`** `object`
+ *     * `select` **`as`** `label` **`disable when`** `disable`
+ *         **`for` `(`**`key`**`,`** `value`**`) in`** `object`
+ *
+ * Where:
+ *
+ *   * `array` / `object`: an expression which evaluates to an array / object to iterate over.
+ *   * `value`: local variable which will refer to each item in the `array` or each property value
+ *      of `object` during iteration.
+ *   * `key`: local variable which will refer to a property name in `object` during iteration.
+ *   * `label`: The result of this expression will be the label for `<option>` element. The
+ *     `expression` will most likely refer to the `value` variable (e.g. `value.propertyName`).
+ *   * `select`: The result of this expression will be bound to the model of the parent `<select>`
+ *      element. If not specified, `select` expression will default to `value`.
+ *   * `group`: The result of this expression will be used to group options using the `<optgroup>`
+ *      DOM element.
+ *   * `disable`: The result of this expression will be used to disable the rendered `<option>`
+ *      element. Return `true` to disable.
+ *   * `trackexpr`: Used when working with an array of objects. The result of this expression will be
+ *      used to identify the objects in the array. The `trackexpr` will most likely refer to the
+ *     `value` variable (e.g. `value.propertyName`). With this the selection is preserved
+ *      even when the options are recreated (e.g. reloaded from the server).
+ * @param {string=} name Property name of the form under which the control is published.
+ * @param {string=} required The control is considered valid only if value is entered.
+ * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
+ *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
+ *    `required` when you want to data-bind to the `required` attribute.
+ * @param {string=} ngAttrSize sets the size of the select element dynamically. Uses the
+ * {@link guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes ngAttr} directive.
+ *
+ * @example
+    <example module="selectExample" name="select">
+      <file name="index.html">
+        <script>
+        angular.module('selectExample', [])
+          .controller('ExampleController', ['$scope', function($scope) {
+            $scope.colors = [
+              {name:'black', shade:'dark'},
+              {name:'white', shade:'light', notAnOption: true},
+              {name:'red', shade:'dark'},
+              {name:'blue', shade:'dark', notAnOption: true},
+              {name:'yellow', shade:'light', notAnOption: false}
+            ];
+            $scope.myColor = $scope.colors[2]; // red
+          }]);
+        </script>
+        <div ng-controller="ExampleController">
+          <ul>
+            <li ng-repeat="color in colors">
+              <label>Name: <input ng-model="color.name"></label>
+              <label><input type="checkbox" ng-model="color.notAnOption"> Disabled?</label>
+              <button ng-click="colors.splice($index, 1)" aria-label="Remove">X</button>
+            </li>
+            <li>
+              <button ng-click="colors.push({})">add</button>
+            </li>
+          </ul>
+          <hr/>
+          <label>Color (null not allowed):
+            <select ng-model="myColor" ng-options="color.name for color in colors"></select>
+          </label><br/>
+          <label>Color (null allowed):
+          <span  class="nullable">
+            <select ng-model="myColor" ng-options="color.name for color in colors">
+              <option value="">-- choose color --</option>
+            </select>
+          </span></label><br/>
+
+          <label>Color grouped by shade:
+            <select ng-model="myColor" ng-options="color.name group by color.shade for color in colors">
+            </select>
+          </label><br/>
+
+          <label>Color grouped by shade, with some disabled:
+            <select ng-model="myColor"
+                  ng-options="color.name group by color.shade disable when color.notAnOption for color in colors">
+            </select>
+          </label><br/>
+
+
+
+          Select <button ng-click="myColor = { name:'not in list', shade: 'other' }">bogus</button>.
+          <br/>
+          <hr/>
+          Currently selected: {{ {selected_color:myColor} }}
+          <div style="border:solid 1px black; height:20px"
+               ng-style="{'background-color':myColor.name}">
+          </div>
+        </div>
+      </file>
+      <file name="protractor.js" type="protractor">
+         it('should check ng-options', function() {
+           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red');
+           element.all(by.model('myColor')).first().click();
+           element.all(by.css('select[ng-model="myColor"] option')).first().click();
+           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black');
+           element(by.css('.nullable select[ng-model="myColor"]')).click();
+           element.all(by.css('.nullable select[ng-model="myColor"] option')).first().click();
+           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('null');
+         });
+      </file>
+    </example>
+ */
+
+/* eslint-disable max-len */
+//                     //00001111111111000000000002222222222000000000000000000000333333333300000000000000000000000004444444444400000000000005555555555555000000000666666666666600000007777777777777000000000000000888888888800000000000000000009999999999
+var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+disable\s+when\s+([\s\S]+?))?\s+for\s+(?:([$\w][$\w]*)|(?:\(\s*([$\w][$\w]*)\s*,\s*([$\w][$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
+                        // 1: value expression (valueFn)
+                        // 2: label expression (displayFn)
+                        // 3: group by expression (groupByFn)
+                        // 4: disable when expression (disableWhenFn)
+                        // 5: array item variable name
+                        // 6: object item key variable name
+                        // 7: object item value variable name
+                        // 8: collection expression
+                        // 9: track by expression
+/* eslint-enable */
+
+
+var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile, $document, $parse) {
+
+  function parseOptionsExpression(optionsExp, selectElement, scope) {
+
+    var match = optionsExp.match(NG_OPTIONS_REGEXP);
+    if (!(match)) {
+      throw ngOptionsMinErr('iexp',
+        'Expected expression in form of ' +
+        '\'_select_ (as _label_)? for (_key_,)?_value_ in _collection_\'' +
+        ' but got \'{0}\'. Element: {1}',
+        optionsExp, startingTag(selectElement));
+    }
+
+    // Extract the parts from the ngOptions expression
+
+    // The variable name for the value of the item in the collection
+    var valueName = match[5] || match[7];
+    // The variable name for the key of the item in the collection
+    var keyName = match[6];
+
+    // An expression that generates the viewValue for an option if there is a label expression
+    var selectAs = / as /.test(match[0]) && match[1];
+    // An expression that is used to track the id of each object in the options collection
+    var trackBy = match[9];
+    // An expression that generates the viewValue for an option if there is no label expression
+    var valueFn = $parse(match[2] ? match[1] : valueName);
+    var selectAsFn = selectAs && $parse(selectAs);
+    var viewValueFn = selectAsFn || valueFn;
+    var trackByFn = trackBy && $parse(trackBy);
+
+    // Get the value by which we are going to track the option
+    // if we have a trackFn then use that (passing scope and locals)
+    // otherwise just hash the given viewValue
+    var getTrackByValueFn = trackBy ?
+                              function(value, locals) { return trackByFn(scope, locals); } :
+                              function getHashOfValue(value) { return hashKey(value); };
+    var getTrackByValue = function(value, key) {
+      return getTrackByValueFn(value, getLocals(value, key));
+    };
+
+    var displayFn = $parse(match[2] || match[1]);
+    var groupByFn = $parse(match[3] || '');
+    var disableWhenFn = $parse(match[4] || '');
+    var valuesFn = $parse(match[8]);
+
+    var locals = {};
+    var getLocals = keyName ? function(value, key) {
+      locals[keyName] = key;
+      locals[valueName] = value;
+      return locals;
+    } : function(value) {
+      locals[valueName] = value;
+      return locals;
+    };
+
+
+    function Option(selectValue, viewValue, label, group, disabled) {
+      this.selectValue = selectValue;
+      this.viewValue = viewValue;
+      this.label = label;
+      this.group = group;
+      this.disabled = disabled;
+    }
+
+    function getOptionValuesKeys(optionValues) {
+      var optionValuesKeys;
+
+      if (!keyName && isArrayLike(optionValues)) {
+        optionValuesKeys = optionValues;
+      } else {
+        // if object, extract keys, in enumeration order, unsorted
+        optionValuesKeys = [];
+        for (var itemKey in optionValues) {
+          if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') {
+            optionValuesKeys.push(itemKey);
+          }
+        }
+      }
+      return optionValuesKeys;
+    }
+
+    return {
+      trackBy: trackBy,
+      getTrackByValue: getTrackByValue,
+      getWatchables: $parse(valuesFn, function(optionValues) {
+        // Create a collection of things that we would like to watch (watchedArray)
+        // so that they can all be watched using a single $watchCollection
+        // that only runs the handler once if anything changes
+        var watchedArray = [];
+        optionValues = optionValues || [];
+
+        var optionValuesKeys = getOptionValuesKeys(optionValues);
+        var optionValuesLength = optionValuesKeys.length;
+        for (var index = 0; index < optionValuesLength; index++) {
+          var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];
+          var value = optionValues[key];
+
+          var locals = getLocals(value, key);
+          var selectValue = getTrackByValueFn(value, locals);
+          watchedArray.push(selectValue);
+
+          // Only need to watch the displayFn if there is a specific label expression
+          if (match[2] || match[1]) {
+            var label = displayFn(scope, locals);
+            watchedArray.push(label);
+          }
+
+          // Only need to watch the disableWhenFn if there is a specific disable expression
+          if (match[4]) {
+            var disableWhen = disableWhenFn(scope, locals);
+            watchedArray.push(disableWhen);
+          }
+        }
+        return watchedArray;
+      }),
+
+      getOptions: function() {
+
+        var optionItems = [];
+        var selectValueMap = {};
+
+        // The option values were already computed in the `getWatchables` fn,
+        // which must have been called to trigger `getOptions`
+        var optionValues = valuesFn(scope) || [];
+        var optionValuesKeys = getOptionValuesKeys(optionValues);
+        var optionValuesLength = optionValuesKeys.length;
+
+        for (var index = 0; index < optionValuesLength; index++) {
+          var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];
+          var value = optionValues[key];
+          var locals = getLocals(value, key);
+          var viewValue = viewValueFn(scope, locals);
+          var selectValue = getTrackByValueFn(viewValue, locals);
+          var label = displayFn(scope, locals);
+          var group = groupByFn(scope, locals);
+          var disabled = disableWhenFn(scope, locals);
+          var optionItem = new Option(selectValue, viewValue, label, group, disabled);
+
+          optionItems.push(optionItem);
+          selectValueMap[selectValue] = optionItem;
+        }
+
+        return {
+          items: optionItems,
+          selectValueMap: selectValueMap,
+          getOptionFromViewValue: function(value) {
+            return selectValueMap[getTrackByValue(value)];
+          },
+          getViewValueFromOption: function(option) {
+            // If the viewValue could be an object that may be mutated by the application,
+            // we need to make a copy and not return the reference to the value on the option.
+            return trackBy ? copy(option.viewValue) : option.viewValue;
+          }
+        };
+      }
+    };
+  }
+
+
+  // we can't just jqLite('<option>') since jqLite is not smart enough
+  // to create it in <select> and IE barfs otherwise.
+  var optionTemplate = window.document.createElement('option'),
+      optGroupTemplate = window.document.createElement('optgroup');
+
+    function ngOptionsPostLink(scope, selectElement, attr, ctrls) {
+
+      var selectCtrl = ctrls[0];
+      var ngModelCtrl = ctrls[1];
+      var multiple = attr.multiple;
+
+      // The emptyOption allows the application developer to provide their own custom "empty"
+      // option when the viewValue does not match any of the option values.
+      for (var i = 0, children = selectElement.children(), ii = children.length; i < ii; i++) {
+        if (children[i].value === '') {
+          selectCtrl.hasEmptyOption = true;
+          selectCtrl.emptyOption = children.eq(i);
+          break;
+        }
+      }
+
+      var providedEmptyOption = !!selectCtrl.emptyOption;
+
+      var unknownOption = jqLite(optionTemplate.cloneNode(false));
+      unknownOption.val('?');
+
+      var options;
+      var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope);
+      // This stores the newly created options before they are appended to the select.
+      // Since the contents are removed from the fragment when it is appended,
+      // we only need to create it once.
+      var listFragment = $document[0].createDocumentFragment();
+
+      // Overwrite the implementation. ngOptions doesn't use hashes
+      selectCtrl.generateUnknownOptionValue = function(val) {
+        return '?';
+      };
+
+      // Update the controller methods for multiple selectable options
+      if (!multiple) {
+
+        selectCtrl.writeValue = function writeNgOptionsValue(value) {
+          var selectedOption = options.selectValueMap[selectElement.val()];
+          var option = options.getOptionFromViewValue(value);
+
+          // Make sure to remove the selected attribute from the previously selected option
+          // Otherwise, screen readers might get confused
+          if (selectedOption) selectedOption.element.removeAttribute('selected');
+
+          if (option) {
+            // Don't update the option when it is already selected.
+            // For example, the browser will select the first option by default. In that case,
+            // most properties are set automatically - except the `selected` attribute, which we
+            // set always
+
+            if (selectElement[0].value !== option.selectValue) {
+              selectCtrl.removeUnknownOption();
+              selectCtrl.unselectEmptyOption();
+
+              selectElement[0].value = option.selectValue;
+              option.element.selected = true;
+            }
+
+            option.element.setAttribute('selected', 'selected');
+          } else {
+
+            if (providedEmptyOption) {
+              selectCtrl.selectEmptyOption();
+            } else if (selectCtrl.unknownOption.parent().length) {
+              selectCtrl.updateUnknownOption(value);
+            } else {
+              selectCtrl.renderUnknownOption(value);
+            }
+          }
+        };
+
+        selectCtrl.readValue = function readNgOptionsValue() {
+
+          var selectedOption = options.selectValueMap[selectElement.val()];
+
+          if (selectedOption && !selectedOption.disabled) {
+            selectCtrl.unselectEmptyOption();
+            selectCtrl.removeUnknownOption();
+            return options.getViewValueFromOption(selectedOption);
+          }
+          return null;
+        };
+
+        // If we are using `track by` then we must watch the tracked value on the model
+        // since ngModel only watches for object identity change
+        // FIXME: When a user selects an option, this watch will fire needlessly
+        if (ngOptions.trackBy) {
+          scope.$watch(
+            function() { return ngOptions.getTrackByValue(ngModelCtrl.$viewValue); },
+            function() { ngModelCtrl.$render(); }
+          );
+        }
+
+      } else {
+
+        selectCtrl.writeValue = function writeNgOptionsMultiple(values) {
+          // Only set `<option>.selected` if necessary, in order to prevent some browsers from
+          // scrolling to `<option>` elements that are outside the `<select>` element's viewport.
+
+          var selectedOptions = values && values.map(getAndUpdateSelectedOption) || [];
+
+          options.items.forEach(function(option) {
+            if (option.element.selected && !includes(selectedOptions, option)) {
+              option.element.selected = false;
+            }
+          });
+        };
+
+
+        selectCtrl.readValue = function readNgOptionsMultiple() {
+          var selectedValues = selectElement.val() || [],
+              selections = [];
+
+          forEach(selectedValues, function(value) {
+            var option = options.selectValueMap[value];
+            if (option && !option.disabled) selections.push(options.getViewValueFromOption(option));
+          });
+
+          return selections;
+        };
+
+        // If we are using `track by` then we must watch these tracked values on the model
+        // since ngModel only watches for object identity change
+        if (ngOptions.trackBy) {
+
+          scope.$watchCollection(function() {
+            if (isArray(ngModelCtrl.$viewValue)) {
+              return ngModelCtrl.$viewValue.map(function(value) {
+                return ngOptions.getTrackByValue(value);
+              });
+            }
+          }, function() {
+            ngModelCtrl.$render();
+          });
+
+        }
+      }
+
+      if (providedEmptyOption) {
+
+        // we need to remove it before calling selectElement.empty() because otherwise IE will
+        // remove the label from the element. wtf?
+        selectCtrl.emptyOption.remove();
+
+        // compile the element since there might be bindings in it
+        $compile(selectCtrl.emptyOption)(scope);
+
+        if (selectCtrl.emptyOption[0].nodeType === NODE_TYPE_COMMENT) {
+          // This means the empty option has currently no actual DOM node, probably because
+          // it has been modified by a transclusion directive.
+          selectCtrl.hasEmptyOption = false;
+
+          // Redefine the registerOption function, which will catch
+          // options that are added by ngIf etc. (rendering of the node is async because of
+          // lazy transclusion)
+          selectCtrl.registerOption = function(optionScope, optionEl) {
+            if (optionEl.val() === '') {
+              selectCtrl.hasEmptyOption = true;
+              selectCtrl.emptyOption = optionEl;
+              selectCtrl.emptyOption.removeClass('ng-scope');
+              // This ensures the new empty option is selected if previously no option was selected
+              ngModelCtrl.$render();
+
+              optionEl.on('$destroy', function() {
+                selectCtrl.hasEmptyOption = false;
+                selectCtrl.emptyOption = undefined;
+              });
+            }
+          };
+
+        } else {
+          // remove the class, which is added automatically because we recompile the element and it
+          // becomes the compilation root
+          selectCtrl.emptyOption.removeClass('ng-scope');
+        }
+
+      }
+
+      selectElement.empty();
+
+      // We need to do this here to ensure that the options object is defined
+      // when we first hit it in writeNgOptionsValue
+      updateOptions();
+
+      // We will re-render the option elements if the option values or labels change
+      scope.$watchCollection(ngOptions.getWatchables, updateOptions);
+
+      // ------------------------------------------------------------------ //
+
+      function addOptionElement(option, parent) {
+        var optionElement = optionTemplate.cloneNode(false);
+        parent.appendChild(optionElement);
+        updateOptionElement(option, optionElement);
+      }
+
+      function getAndUpdateSelectedOption(viewValue) {
+        var option = options.getOptionFromViewValue(viewValue);
+        var element = option && option.element;
+
+        if (element && !element.selected) element.selected = true;
+
+        return option;
+      }
+
+      function updateOptionElement(option, element) {
+        option.element = element;
+        element.disabled = option.disabled;
+        // NOTE: The label must be set before the value, otherwise IE10/11/EDGE create unresponsive
+        // selects in certain circumstances when multiple selects are next to each other and display
+        // the option list in listbox style, i.e. the select is [multiple], or specifies a [size].
+        // See https://github.com/angular/angular.js/issues/11314 for more info.
+        // This is unfortunately untestable with unit / e2e tests
+        if (option.label !== element.label) {
+          element.label = option.label;
+          element.textContent = option.label;
+        }
+        element.value = option.selectValue;
+      }
+
+      function updateOptions() {
+        var previousValue = options && selectCtrl.readValue();
+
+        // We must remove all current options, but cannot simply set innerHTML = null
+        // since the providedEmptyOption might have an ngIf on it that inserts comments which we
+        // must preserve.
+        // Instead, iterate over the current option elements and remove them or their optgroup
+        // parents
+        if (options) {
+
+          for (var i = options.items.length - 1; i >= 0; i--) {
+            var option = options.items[i];
+            if (isDefined(option.group)) {
+              jqLiteRemove(option.element.parentNode);
+            } else {
+              jqLiteRemove(option.element);
+            }
+          }
+        }
+
+        options = ngOptions.getOptions();
+
+        var groupElementMap = {};
+
+        // Ensure that the empty option is always there if it was explicitly provided
+        if (providedEmptyOption) {
+          selectElement.prepend(selectCtrl.emptyOption);
+        }
+
+        options.items.forEach(function addOption(option) {
+          var groupElement;
+
+          if (isDefined(option.group)) {
+
+            // This option is to live in a group
+            // See if we have already created this group
+            groupElement = groupElementMap[option.group];
+
+            if (!groupElement) {
+
+              groupElement = optGroupTemplate.cloneNode(false);
+              listFragment.appendChild(groupElement);
+
+              // Update the label on the group element
+              // "null" is special cased because of Safari
+              groupElement.label = option.group === null ? 'null' : option.group;
+
+              // Store it for use later
+              groupElementMap[option.group] = groupElement;
+            }
+
+            addOptionElement(option, groupElement);
+
+          } else {
+
+            // This option is not in a group
+            addOptionElement(option, listFragment);
+          }
+        });
+
+        selectElement[0].appendChild(listFragment);
+
+        ngModelCtrl.$render();
+
+        // Check to see if the value has changed due to the update to the options
+        if (!ngModelCtrl.$isEmpty(previousValue)) {
+          var nextValue = selectCtrl.readValue();
+          var isNotPrimitive = ngOptions.trackBy || multiple;
+          if (isNotPrimitive ? !equals(previousValue, nextValue) : previousValue !== nextValue) {
+            ngModelCtrl.$setViewValue(nextValue);
+            ngModelCtrl.$render();
+          }
+        }
+
+      }
+  }
+
+  return {
+    restrict: 'A',
+    terminal: true,
+    require: ['select', 'ngModel'],
+    link: {
+      pre: function ngOptionsPreLink(scope, selectElement, attr, ctrls) {
+        // Deactivate the SelectController.register method to prevent
+        // option directives from accidentally registering themselves
+        // (and unwanted $destroy handlers etc.)
+        ctrls[0].registerOption = noop;
+      },
+      post: ngOptionsPostLink
+    }
+  };
+}];
+
+/**
+ * @ngdoc directive
+ * @name ngPluralize
+ * @restrict EA
+ *
+ * @description
+ * `ngPluralize` is a directive that displays messages according to en-US localization rules.
+ * These rules are bundled with angular.js, but can be overridden
+ * (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive
+ * by specifying the mappings between
+ * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)
+ * and the strings to be displayed.
+ *
+ * # Plural categories and explicit number rules
+ * There are two
+ * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)
+ * in Angular's default en-US locale: "one" and "other".
+ *
+ * While a plural category may match many numbers (for example, in en-US locale, "other" can match
+ * any number that is not 1), an explicit number rule can only match one number. For example, the
+ * explicit number rule for "3" matches the number 3. There are examples of plural categories
+ * and explicit number rules throughout the rest of this documentation.
+ *
+ * # Configuring ngPluralize
+ * You configure ngPluralize by providing 2 attributes: `count` and `when`.
+ * You can also provide an optional attribute, `offset`.
+ *
+ * The value of the `count` attribute can be either a string or an {@link guide/expression
+ * Angular expression}; these are evaluated on the current scope for its bound value.
+ *
+ * The `when` attribute specifies the mappings between plural categories and the actual
+ * string to be displayed. The value of the attribute should be a JSON object.
+ *
+ * The following example shows how to configure ngPluralize:
+ *
+ * ```html
+ * <ng-pluralize count="personCount"
+                 when="{'0': 'Nobody is viewing.',
+ *                      'one': '1 person is viewing.',
+ *                      'other': '{} people are viewing.'}">
+ * </ng-pluralize>
+ *```
+ *
+ * In the example, `"0: Nobody is viewing."` is an explicit number rule. If you did not
+ * specify this rule, 0 would be matched to the "other" category and "0 people are viewing"
+ * would be shown instead of "Nobody is viewing". You can specify an explicit number rule for
+ * other numbers, for example 12, so that instead of showing "12 people are viewing", you can
+ * show "a dozen people are viewing".
+ *
+ * You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted
+ * into pluralized strings. In the previous example, Angular will replace `{}` with
+ * <span ng-non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder
+ * for <span ng-non-bindable>{{numberExpression}}</span>.
+ *
+ * If no rule is defined for a category, then an empty string is displayed and a warning is generated.
+ * Note that some locales define more categories than `one` and `other`. For example, fr-fr defines `few` and `many`.
+ *
+ * # Configuring ngPluralize with offset
+ * The `offset` attribute allows further customization of pluralized text, which can result in
+ * a better user experience. For example, instead of the message "4 people are viewing this document",
+ * you might display "John, Kate and 2 others are viewing this document".
+ * The offset attribute allows you to offset a number by any desired value.
+ * Let's take a look at an example:
+ *
+ * ```html
+ * <ng-pluralize count="personCount" offset=2
+ *               when="{'0': 'Nobody is viewing.',
+ *                      '1': '{{person1}} is viewing.',
+ *                      '2': '{{person1}} and {{person2}} are viewing.',
+ *                      'one': '{{person1}}, {{person2}} and one other person are viewing.',
+ *                      'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
+ * </ng-pluralize>
+ * ```
+ *
+ * Notice that we are still using two plural categories(one, other), but we added
+ * three explicit number rules 0, 1 and 2.
+ * When one person, perhaps John, views the document, "John is viewing" will be shown.
+ * When three people view the document, no explicit number rule is found, so
+ * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category.
+ * In this case, plural category 'one' is matched and "John, Mary and one other person are viewing"
+ * is shown.
+ *
+ * Note that when you specify offsets, you must provide explicit number rules for
+ * numbers from 0 up to and including the offset. If you use an offset of 3, for example,
+ * you must provide explicit number rules for 0, 1, 2 and 3. You must also provide plural strings for
+ * plural categories "one" and "other".
+ *
+ * @param {string|expression} count The variable to be bound to.
+ * @param {string} when The mapping between plural category to its corresponding strings.
+ * @param {number=} offset Offset to deduct from the total number.
+ *
+ * @example
+    <example module="pluralizeExample" name="ng-pluralize">
+      <file name="index.html">
+        <script>
+          angular.module('pluralizeExample', [])
+            .controller('ExampleController', ['$scope', function($scope) {
+              $scope.person1 = 'Igor';
+              $scope.person2 = 'Misko';
+              $scope.personCount = 1;
+            }]);
+        </script>
+        <div ng-controller="ExampleController">
+          <label>Person 1:<input type="text" ng-model="person1" value="Igor" /></label><br/>
+          <label>Person 2:<input type="text" ng-model="person2" value="Misko" /></label><br/>
+          <label>Number of People:<input type="text" ng-model="personCount" value="1" /></label><br/>
+
+          <!--- Example with simple pluralization rules for en locale --->
+          Without Offset:
+          <ng-pluralize count="personCount"
+                        when="{'0': 'Nobody is viewing.',
+                               'one': '1 person is viewing.',
+                               'other': '{} people are viewing.'}">
+          </ng-pluralize><br>
+
+          <!--- Example with offset --->
+          With Offset(2):
+          <ng-pluralize count="personCount" offset=2
+                        when="{'0': 'Nobody is viewing.',
+                               '1': '{{person1}} is viewing.',
+                               '2': '{{person1}} and {{person2}} are viewing.',
+                               'one': '{{person1}}, {{person2}} and one other person are viewing.',
+                               'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
+          </ng-pluralize>
+        </div>
+      </file>
+      <file name="protractor.js" type="protractor">
+        it('should show correct pluralized string', function() {
+          var withoutOffset = element.all(by.css('ng-pluralize')).get(0);
+          var withOffset = element.all(by.css('ng-pluralize')).get(1);
+          var countInput = element(by.model('personCount'));
+
+          expect(withoutOffset.getText()).toEqual('1 person is viewing.');
+          expect(withOffset.getText()).toEqual('Igor is viewing.');
+
+          countInput.clear();
+          countInput.sendKeys('0');
+
+          expect(withoutOffset.getText()).toEqual('Nobody is viewing.');
+          expect(withOffset.getText()).toEqual('Nobody is viewing.');
+
+          countInput.clear();
+          countInput.sendKeys('2');
+
+          expect(withoutOffset.getText()).toEqual('2 people are viewing.');
+          expect(withOffset.getText()).toEqual('Igor and Misko are viewing.');
+
+          countInput.clear();
+          countInput.sendKeys('3');
+
+          expect(withoutOffset.getText()).toEqual('3 people are viewing.');
+          expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.');
+
+          countInput.clear();
+          countInput.sendKeys('4');
+
+          expect(withoutOffset.getText()).toEqual('4 people are viewing.');
+          expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.');
+        });
+        it('should show data-bound names', function() {
+          var withOffset = element.all(by.css('ng-pluralize')).get(1);
+          var personCount = element(by.model('personCount'));
+          var person1 = element(by.model('person1'));
+          var person2 = element(by.model('person2'));
+          personCount.clear();
+          personCount.sendKeys('4');
+          person1.clear();
+          person1.sendKeys('Di');
+          person2.clear();
+          person2.sendKeys('Vojta');
+          expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.');
+        });
+      </file>
+    </example>
+ */
+var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale, $interpolate, $log) {
+  var BRACE = /{}/g,
+      IS_WHEN = /^when(Minus)?(.+)$/;
+
+  return {
+    link: function(scope, element, attr) {
+      var numberExp = attr.count,
+          whenExp = attr.$attr.when && element.attr(attr.$attr.when), // we have {{}} in attrs
+          offset = attr.offset || 0,
+          whens = scope.$eval(whenExp) || {},
+          whensExpFns = {},
+          startSymbol = $interpolate.startSymbol(),
+          endSymbol = $interpolate.endSymbol(),
+          braceReplacement = startSymbol + numberExp + '-' + offset + endSymbol,
+          watchRemover = angular.noop,
+          lastCount;
+
+      forEach(attr, function(expression, attributeName) {
+        var tmpMatch = IS_WHEN.exec(attributeName);
+        if (tmpMatch) {
+          var whenKey = (tmpMatch[1] ? '-' : '') + lowercase(tmpMatch[2]);
+          whens[whenKey] = element.attr(attr.$attr[attributeName]);
+        }
+      });
+      forEach(whens, function(expression, key) {
+        whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement));
+
+      });
+
+      scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {
+        var count = parseFloat(newVal);
+        var countIsNaN = isNumberNaN(count);
+
+        if (!countIsNaN && !(count in whens)) {
+          // If an explicit number rule such as 1, 2, 3... is defined, just use it.
+          // Otherwise, check it against pluralization rules in $locale service.
+          count = $locale.pluralCat(count - offset);
+        }
+
+        // If both `count` and `lastCount` are NaN, we don't need to re-register a watch.
+        // In JS `NaN !== NaN`, so we have to explicitly check.
+        if ((count !== lastCount) && !(countIsNaN && isNumberNaN(lastCount))) {
+          watchRemover();
+          var whenExpFn = whensExpFns[count];
+          if (isUndefined(whenExpFn)) {
+            if (newVal != null) {
+              $log.debug('ngPluralize: no rule defined for \'' + count + '\' in ' + whenExp);
+            }
+            watchRemover = noop;
+            updateElementText();
+          } else {
+            watchRemover = scope.$watch(whenExpFn, updateElementText);
+          }
+          lastCount = count;
+        }
+      });
+
+      function updateElementText(newText) {
+        element.text(newText || '');
+      }
+    }
+  };
+}];
+
+/* exported ngRepeatDirective */
+
+/**
+ * @ngdoc directive
+ * @name ngRepeat
+ * @multiElement
+ * @restrict A
+ *
+ * @description
+ * The `ngRepeat` directive instantiates a template once per item from a collection. Each template
+ * instance gets its own scope, where the given loop variable is set to the current collection item,
+ * and `$index` is set to the item index or key.
+ *
+ * Special properties are exposed on the local scope of each template instance, including:
+ *
+ * | Variable  | Type            | Details                                                                     |
+ * |-----------|-----------------|-----------------------------------------------------------------------------|
+ * | `$index`  | {@type number}  | iterator offset of the repeated element (0..length-1)                       |
+ * | `$first`  | {@type boolean} | true if the repeated element is first in the iterator.                      |
+ * | `$middle` | {@type boolean} | true if the repeated element is between the first and last in the iterator. |
+ * | `$last`   | {@type boolean} | true if the repeated element is last in the iterator.                       |
+ * | `$even`   | {@type boolean} | true if the iterator position `$index` is even (otherwise false).           |
+ * | `$odd`    | {@type boolean} | true if the iterator position `$index` is odd (otherwise false).            |
+ *
+ * <div class="alert alert-info">
+ *   Creating aliases for these properties is possible with {@link ng.directive:ngInit `ngInit`}.
+ *   This may be useful when, for instance, nesting ngRepeats.
+ * </div>
+ *
+ *
+ * # Iterating over object properties
+ *
+ * It is possible to get `ngRepeat` to iterate over the properties of an object using the following
+ * syntax:
+ *
+ * ```js
+ * <div ng-repeat="(key, value) in myObj"> ... </div>
+ * ```
+ *
+ * However, there are a few limitations compared to array iteration:
+ *
+ * - The JavaScript specification does not define the order of keys
+ *   returned for an object, so Angular relies on the order returned by the browser
+ *   when running `for key in myObj`. Browsers generally follow the strategy of providing
+ *   keys in the order in which they were defined, although there are exceptions when keys are deleted
+ *   and reinstated. See the
+ *   [MDN page on `delete` for more info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_notes).
+ *
+ * - `ngRepeat` will silently *ignore* object keys starting with `$`, because
+ *   it's a prefix used by Angular for public (`$`) and private (`$$`) properties.
+ *
+ * - The built-in filters {@link ng.orderBy orderBy} and {@link ng.filter filter} do not work with
+ *   objects, and will throw an error if used with one.
+ *
+ * If you are hitting any of these limitations, the recommended workaround is to convert your object into an array
+ * that is sorted into the order that you prefer before providing it to `ngRepeat`. You could
+ * do this with a filter such as [toArrayFilter](http://ngmodules.org/modules/angular-toArrayFilter)
+ * or implement a `$watch` on the object yourself.
+ *
+ *
+ * # Tracking and Duplicates
+ *
+ * `ngRepeat` uses {@link $rootScope.Scope#$watchCollection $watchCollection} to detect changes in
+ * the collection. When a change happens, `ngRepeat` then makes the corresponding changes to the DOM:
+ *
+ * * When an item is added, a new instance of the template is added to the DOM.
+ * * When an item is removed, its template instance is removed from the DOM.
+ * * When items are reordered, their respective templates are reordered in the DOM.
+ *
+ * To minimize creation of DOM elements, `ngRepeat` uses a function
+ * to "keep track" of all items in the collection and their corresponding DOM elements.
+ * For example, if an item is added to the collection, `ngRepeat` will know that all other items
+ * already have DOM elements, and will not re-render them.
+ *
+ * The default tracking function (which tracks items by their identity) does not allow
+ * duplicate items in arrays. This is because when there are duplicates, it is not possible
+ * to maintain a one-to-one mapping between collection items and DOM elements.
+ *
+ * If you do need to repeat duplicate items, you can substitute the default tracking behavior
+ * with your own using the `track by` expression.
+ *
+ * For example, you may track items by the index of each item in the collection, using the
+ * special scope property `$index`:
+ * ```html
+ *    <div ng-repeat="n in [42, 42, 43, 43] track by $index">
+ *      {{n}}
+ *    </div>
+ * ```
+ *
+ * You may also use arbitrary expressions in `track by`, including references to custom functions
+ * on the scope:
+ * ```html
+ *    <div ng-repeat="n in [42, 42, 43, 43] track by myTrackingFunction(n)">
+ *      {{n}}
+ *    </div>
+ * ```
+ *
+ * <div class="alert alert-success">
+ * If you are working with objects that have a unique identifier property, you should track
+ * by this identifier instead of the object instance. Should you reload your data later, `ngRepeat`
+ * will not have to rebuild the DOM elements for items it has already rendered, even if the
+ * JavaScript objects in the collection have been substituted for new ones. For large collections,
+ * this significantly improves rendering performance. If you don't have a unique identifier,
+ * `track by $index` can also provide a performance boost.
+ * </div>
+ *
+ * ```html
+ *    <div ng-repeat="model in collection track by model.id">
+ *      {{model.name}}
+ *    </div>
+ * ```
+ *
+ * <br />
+ * <div class="alert alert-warning">
+ * Avoid using `track by $index` when the repeated template contains
+ * {@link guide/expression#one-time-binding one-time bindings}. In such cases, the `nth` DOM
+ * element will always be matched with the `nth` item of the array, so the bindings on that element
+ * will not be updated even when the corresponding item changes, essentially causing the view to get
+ * out-of-sync with the underlying data.
+ * </div>
+ *
+ * When no `track by` expression is provided, it is equivalent to tracking by the built-in
+ * `$id` function, which tracks items by their identity:
+ * ```html
+ *    <div ng-repeat="obj in collection track by $id(obj)">
+ *      {{obj.prop}}
+ *    </div>
+ * ```
+ *
+ * <br />
+ * <div class="alert alert-warning">
+ * **Note:** `track by` must always be the last expression:
+ * </div>
+ * ```
+ *    <div ng-repeat="model in collection | orderBy: 'id' as filtered_result track by model.id">
+ *      {{model.name}}
+ *    </div>
+ * ```
+ *
+ *
+ * # Special repeat start and end points
+ * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending
+ * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.
+ * The **ng-repeat-start** directive works the same as **ng-repeat**, but will repeat all the HTML code (including the tag it's defined on)
+ * up to and including the ending HTML tag where **ng-repeat-end** is placed.
+ *
+ * The example below makes use of this feature:
+ * ```html
+ *   <header ng-repeat-start="item in items">
+ *     Header {{ item }}
+ *   </header>
+ *   <div class="body">
+ *     Body {{ item }}
+ *   </div>
+ *   <footer ng-repeat-end>
+ *     Footer {{ item }}
+ *   </footer>
+ * ```
+ *
+ * And with an input of {@type ['A','B']} for the items variable in the example above, the output will evaluate to:
+ * ```html
+ *   <header>
+ *     Header A
+ *   </header>
+ *   <div class="body">
+ *     Body A
+ *   </div>
+ *   <footer>
+ *     Footer A
+ *   </footer>
+ *   <header>
+ *     Header B
+ *   </header>
+ *   <div class="body">
+ *     Body B
+ *   </div>
+ *   <footer>
+ *     Footer B
+ *   </footer>
+ * ```
+ *
+ * The custom start and end points for ngRepeat also support all other HTML directive syntax flavors provided in AngularJS (such
+ * as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**).
+ *
+ * @animations
+ * | Animation                        | Occurs                              |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#enter enter} | when a new item is added to the list or when an item is revealed after a filter |
+ * | {@link ng.$animate#leave leave} | when an item is removed from the list or when an item is filtered out |
+ * | {@link ng.$animate#move move } | when an adjacent item is filtered out causing a reorder or when the item contents are reordered |
+ *
+ * See the example below for defining CSS animations with ngRepeat.
+ *
+ * @element ANY
+ * @scope
+ * @priority 1000
+ * @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. These
+ *   formats are currently supported:
+ *
+ *   * `variable in expression` – where variable is the user defined loop variable and `expression`
+ *     is a scope expression giving the collection to enumerate.
+ *
+ *     For example: `album in artist.albums`.
+ *
+ *   * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,
+ *     and `expression` is the scope expression giving the collection to enumerate.
+ *
+ *     For example: `(name, age) in {'adam':10, 'amalie':12}`.
+ *
+ *   * `variable in expression track by tracking_expression` – You can also provide an optional tracking expression
+ *     which can be used to associate the objects in the collection with the DOM elements. If no tracking expression
+ *     is specified, ng-repeat associates elements by identity. It is an error to have
+ *     more than one tracking expression value resolve to the same key. (This would mean that two distinct objects are
+ *     mapped to the same DOM element, which is not possible.)
+ *
+ *     Note that the tracking expression must come last, after any filters, and the alias expression.
+ *
+ *     For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
+ *     will be associated by item identity in the array.
+ *
+ *     For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique
+ *     `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements
+ *     with the corresponding item in the array by identity. Moving the same object in array would move the DOM
+ *     element in the same way in the DOM.
+ *
+ *     For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this
+ *     case the object identity does not matter. Two objects are considered equivalent as long as their `id`
+ *     property is same.
+ *
+ *     For example: `item in items | filter:searchText track by item.id` is a pattern that might be used to apply a filter
+ *     to items in conjunction with a tracking expression.
+ *
+ *   * `variable in expression as alias_expression` – You can also provide an optional alias expression which will then store the
+ *     intermediate results of the repeater after the filters have been applied. Typically this is used to render a special message
+ *     when a filter is active on the repeater, but the filtered result set is empty.
+ *
+ *     For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after
+ *     the items have been processed through the filter.
+ *
+ *     Please note that `as [variable name] is not an operator but rather a part of ngRepeat micro-syntax so it can be used only at the end
+ *     (and not as operator, inside an expression).
+ *
+ *     For example: `item in items | filter : x | orderBy : order | limitTo : limit as results` .
+ *
+ * @example
+ * This example uses `ngRepeat` to display a list of people. A filter is used to restrict the displayed
+ * results by name or by age. New (entering) and removed (leaving) items are animated.
+  <example module="ngRepeat" name="ngRepeat" deps="angular-animate.js" animations="true" name="ng-repeat">
+    <file name="index.html">
+      <div ng-controller="repeatController">
+        I have {{friends.length}} friends. They are:
+        <input type="search" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />
+        <ul class="example-animate-container">
+          <li class="animate-repeat" ng-repeat="friend in friends | filter:q as results">
+            [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
+          </li>
+          <li class="animate-repeat" ng-if="results.length === 0">
+            <strong>No results found...</strong>
+          </li>
+        </ul>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {
+        $scope.friends = [
+          {name:'John', age:25, gender:'boy'},
+          {name:'Jessie', age:30, gender:'girl'},
+          {name:'Johanna', age:28, gender:'girl'},
+          {name:'Joy', age:15, gender:'girl'},
+          {name:'Mary', age:28, gender:'girl'},
+          {name:'Peter', age:95, gender:'boy'},
+          {name:'Sebastian', age:50, gender:'boy'},
+          {name:'Erika', age:27, gender:'girl'},
+          {name:'Patrick', age:40, gender:'boy'},
+          {name:'Samantha', age:60, gender:'girl'}
+        ];
+      });
+    </file>
+    <file name="animations.css">
+      .example-animate-container {
+        background:white;
+        border:1px solid black;
+        list-style:none;
+        margin:0;
+        padding:0 10px;
+      }
+
+      .animate-repeat {
+        line-height:30px;
+        list-style:none;
+        box-sizing:border-box;
+      }
+
+      .animate-repeat.ng-move,
+      .animate-repeat.ng-enter,
+      .animate-repeat.ng-leave {
+        transition:all linear 0.5s;
+      }
+
+      .animate-repeat.ng-leave.ng-leave-active,
+      .animate-repeat.ng-move,
+      .animate-repeat.ng-enter {
+        opacity:0;
+        max-height:0;
+      }
+
+      .animate-repeat.ng-leave,
+      .animate-repeat.ng-move.ng-move-active,
+      .animate-repeat.ng-enter.ng-enter-active {
+        opacity:1;
+        max-height:30px;
+      }
+    </file>
+    <file name="protractor.js" type="protractor">
+      var friends = element.all(by.repeater('friend in friends'));
+
+      it('should render initial data set', function() {
+        expect(friends.count()).toBe(10);
+        expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.');
+        expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.');
+        expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.');
+        expect(element(by.binding('friends.length')).getText())
+            .toMatch("I have 10 friends. They are:");
+      });
+
+       it('should update repeater when filter predicate changes', function() {
+         expect(friends.count()).toBe(10);
+
+         element(by.model('q')).sendKeys('ma');
+
+         expect(friends.count()).toBe(2);
+         expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.');
+         expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.');
+       });
+      </file>
+    </example>
+ */
+var ngRepeatDirective = ['$parse', '$animate', '$compile', function($parse, $animate, $compile) {
+  var NG_REMOVED = '$$NG_REMOVED';
+  var ngRepeatMinErr = minErr('ngRepeat');
+
+  var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength) {
+    // TODO(perf): generate setters to shave off ~40ms or 1-1.5%
+    scope[valueIdentifier] = value;
+    if (keyIdentifier) scope[keyIdentifier] = key;
+    scope.$index = index;
+    scope.$first = (index === 0);
+    scope.$last = (index === (arrayLength - 1));
+    scope.$middle = !(scope.$first || scope.$last);
+    // eslint-disable-next-line no-bitwise
+    scope.$odd = !(scope.$even = (index & 1) === 0);
+  };
+
+  var getBlockStart = function(block) {
+    return block.clone[0];
+  };
+
+  var getBlockEnd = function(block) {
+    return block.clone[block.clone.length - 1];
+  };
+
+
+  return {
+    restrict: 'A',
+    multiElement: true,
+    transclude: 'element',
+    priority: 1000,
+    terminal: true,
+    $$tlb: true,
+    compile: function ngRepeatCompile($element, $attr) {
+      var expression = $attr.ngRepeat;
+      var ngRepeatEndComment = $compile.$$createComment('end ngRepeat', expression);
+
+      var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
+
+      if (!match) {
+        throw ngRepeatMinErr('iexp', 'Expected expression in form of \'_item_ in _collection_[ track by _id_]\' but got \'{0}\'.',
+            expression);
+      }
+
+      var lhs = match[1];
+      var rhs = match[2];
+      var aliasAs = match[3];
+      var trackByExp = match[4];
+
+      match = lhs.match(/^(?:(\s*[$\w]+)|\(\s*([$\w]+)\s*,\s*([$\w]+)\s*\))$/);
+
+      if (!match) {
+        throw ngRepeatMinErr('iidexp', '\'_item_\' in \'_item_ in _collection_\' should be an identifier or \'(_key_, _value_)\' expression, but got \'{0}\'.',
+            lhs);
+      }
+      var valueIdentifier = match[3] || match[1];
+      var keyIdentifier = match[2];
+
+      if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) ||
+          /^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent|\$root|\$id)$/.test(aliasAs))) {
+        throw ngRepeatMinErr('badident', 'alias \'{0}\' is invalid --- must be a valid JS identifier which is not a reserved name.',
+          aliasAs);
+      }
+
+      var trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn;
+      var hashFnLocals = {$id: hashKey};
+
+      if (trackByExp) {
+        trackByExpGetter = $parse(trackByExp);
+      } else {
+        trackByIdArrayFn = function(key, value) {
+          return hashKey(value);
+        };
+        trackByIdObjFn = function(key) {
+          return key;
+        };
+      }
+
+      return function ngRepeatLink($scope, $element, $attr, ctrl, $transclude) {
+
+        if (trackByExpGetter) {
+          trackByIdExpFn = function(key, value, index) {
+            // assign key, value, and $index to the locals so that they can be used in hash functions
+            if (keyIdentifier) hashFnLocals[keyIdentifier] = key;
+            hashFnLocals[valueIdentifier] = value;
+            hashFnLocals.$index = index;
+            return trackByExpGetter($scope, hashFnLocals);
+          };
+        }
+
+        // Store a list of elements from previous run. This is a hash where key is the item from the
+        // iterator, and the value is objects with following properties.
+        //   - scope: bound scope
+        //   - element: previous element.
+        //   - index: position
+        //
+        // We are using no-proto object so that we don't need to guard against inherited props via
+        // hasOwnProperty.
+        var lastBlockMap = createMap();
+
+        //watch props
+        $scope.$watchCollection(rhs, function ngRepeatAction(collection) {
+          var index, length,
+              previousNode = $element[0],     // node that cloned nodes should be inserted after
+                                              // initialized to the comment node anchor
+              nextNode,
+              // Same as lastBlockMap but it has the current state. It will become the
+              // lastBlockMap on the next iteration.
+              nextBlockMap = createMap(),
+              collectionLength,
+              key, value, // key/value of iteration
+              trackById,
+              trackByIdFn,
+              collectionKeys,
+              block,       // last object information {scope, element, id}
+              nextBlockOrder,
+              elementsToRemove;
+
+          if (aliasAs) {
+            $scope[aliasAs] = collection;
+          }
+
+          if (isArrayLike(collection)) {
+            collectionKeys = collection;
+            trackByIdFn = trackByIdExpFn || trackByIdArrayFn;
+          } else {
+            trackByIdFn = trackByIdExpFn || trackByIdObjFn;
+            // if object, extract keys, in enumeration order, unsorted
+            collectionKeys = [];
+            for (var itemKey in collection) {
+              if (hasOwnProperty.call(collection, itemKey) && itemKey.charAt(0) !== '$') {
+                collectionKeys.push(itemKey);
+              }
+            }
+          }
+
+          collectionLength = collectionKeys.length;
+          nextBlockOrder = new Array(collectionLength);
+
+          // locate existing items
+          for (index = 0; index < collectionLength; index++) {
+            key = (collection === collectionKeys) ? index : collectionKeys[index];
+            value = collection[key];
+            trackById = trackByIdFn(key, value, index);
+            if (lastBlockMap[trackById]) {
+              // found previously seen block
+              block = lastBlockMap[trackById];
+              delete lastBlockMap[trackById];
+              nextBlockMap[trackById] = block;
+              nextBlockOrder[index] = block;
+            } else if (nextBlockMap[trackById]) {
+              // if collision detected. restore lastBlockMap and throw an error
+              forEach(nextBlockOrder, function(block) {
+                if (block && block.scope) lastBlockMap[block.id] = block;
+              });
+              throw ngRepeatMinErr('dupes',
+                  'Duplicates in a repeater are not allowed. Use \'track by\' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}',
+                  expression, trackById, value);
+            } else {
+              // new never before seen block
+              nextBlockOrder[index] = {id: trackById, scope: undefined, clone: undefined};
+              nextBlockMap[trackById] = true;
+            }
+          }
+
+          // remove leftover items
+          for (var blockKey in lastBlockMap) {
+            block = lastBlockMap[blockKey];
+            elementsToRemove = getBlockNodes(block.clone);
+            $animate.leave(elementsToRemove);
+            if (elementsToRemove[0].parentNode) {
+              // if the element was not removed yet because of pending animation, mark it as deleted
+              // so that we can ignore it later
+              for (index = 0, length = elementsToRemove.length; index < length; index++) {
+                elementsToRemove[index][NG_REMOVED] = true;
+              }
+            }
+            block.scope.$destroy();
+          }
+
+          // we are not using forEach for perf reasons (trying to avoid #call)
+          for (index = 0; index < collectionLength; index++) {
+            key = (collection === collectionKeys) ? index : collectionKeys[index];
+            value = collection[key];
+            block = nextBlockOrder[index];
+
+            if (block.scope) {
+              // if we have already seen this object, then we need to reuse the
+              // associated scope/element
+
+              nextNode = previousNode;
+
+              // skip nodes that are already pending removal via leave animation
+              do {
+                nextNode = nextNode.nextSibling;
+              } while (nextNode && nextNode[NG_REMOVED]);
+
+              if (getBlockStart(block) !== nextNode) {
+                // existing item which got moved
+                $animate.move(getBlockNodes(block.clone), null, previousNode);
+              }
+              previousNode = getBlockEnd(block);
+              updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
+            } else {
+              // new item which we don't know about
+              $transclude(function ngRepeatTransclude(clone, scope) {
+                block.scope = scope;
+                // http://jsperf.com/clone-vs-createcomment
+                var endNode = ngRepeatEndComment.cloneNode(false);
+                clone[clone.length++] = endNode;
+
+                $animate.enter(clone, null, previousNode);
+                previousNode = endNode;
+                // Note: We only need the first/last node of the cloned nodes.
+                // However, we need to keep the reference to the jqlite wrapper as it might be changed later
+                // by a directive with templateUrl when its template arrives.
+                block.clone = clone;
+                nextBlockMap[block.id] = block;
+                updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
+              });
+            }
+          }
+          lastBlockMap = nextBlockMap;
+        });
+      };
+    }
+  };
+}];
+
+var NG_HIDE_CLASS = 'ng-hide';
+var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
+/**
+ * @ngdoc directive
+ * @name ngShow
+ * @multiElement
+ *
+ * @description
+ * The `ngShow` directive shows or hides the given HTML element based on the expression provided to
+ * the `ngShow` attribute.
+ *
+ * The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
+ * The `.ng-hide` CSS class is predefined in AngularJS and sets the display style to none (using an
+ * `!important` flag). For CSP mode please add `angular-csp.css` to your HTML file (see
+ * {@link ng.directive:ngCsp ngCsp}).
+ *
+ * ```html
+ * <!-- when $scope.myValue is truthy (element is visible) -->
+ * <div ng-show="myValue"></div>
+ *
+ * <!-- when $scope.myValue is falsy (element is hidden) -->
+ * <div ng-show="myValue" class="ng-hide"></div>
+ * ```
+ *
+ * When the `ngShow` expression evaluates to a falsy value then the `.ng-hide` CSS class is added
+ * to the class attribute on the element causing it to become hidden. When truthy, the `.ng-hide`
+ * CSS class is removed from the element causing the element not to appear hidden.
+ *
+ * ## Why is `!important` used?
+ *
+ * You may be wondering why `!important` is used for the `.ng-hide` CSS class. This is because the
+ * `.ng-hide` selector can be easily overridden by heavier selectors. For example, something as
+ * simple as changing the display style on a HTML list item would make hidden elements appear
+ * visible. This also becomes a bigger issue when dealing with CSS frameworks.
+ *
+ * By using `!important`, the show and hide behavior will work as expected despite any clash between
+ * CSS selector specificity (when `!important` isn't used with any conflicting styles). If a
+ * developer chooses to override the styling to change how to hide an element then it is just a
+ * matter of using `!important` in their own CSS code.
+ *
+ * ### Overriding `.ng-hide`
+ *
+ * By default, the `.ng-hide` class will style the element with `display: none !important`. If you
+ * wish to change the hide behavior with `ngShow`/`ngHide`, you can simply overwrite the styles for
+ * the `.ng-hide` CSS class. Note that the selector that needs to be used is actually
+ * `.ng-hide:not(.ng-hide-animate)` to cope with extra animation classes that can be added.
+ *
+ * ```css
+ * .ng-hide:not(.ng-hide-animate) {
+ *   /&#42; These are just alternative ways of hiding an element &#42;/
+ *   display: block!important;
+ *   position: absolute;
+ *   top: -9999px;
+ *   left: -9999px;
+ * }
+ * ```
+ *
+ * By default you don't need to override anything in CSS and the animations will work around the
+ * display style.
+ *
+ * ## A note about animations with `ngShow`
+ *
+ * Animations in `ngShow`/`ngHide` work with the show and hide events that are triggered when the
+ * directive expression is true and false. This system works like the animation system present with
+ * `ngClass` except that you must also include the `!important` flag to override the display
+ * property so that the elements are not actually hidden during the animation.
+ *
+ * ```css
+ * /&#42; A working example can be found at the bottom of this page. &#42;/
+ * .my-element.ng-hide-add, .my-element.ng-hide-remove {
+ *   transition: all 0.5s linear;
+ * }
+ *
+ * .my-element.ng-hide-add { ... }
+ * .my-element.ng-hide-add.ng-hide-add-active { ... }
+ * .my-element.ng-hide-remove { ... }
+ * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
+ * ```
+ *
+ * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display property
+ * to block during animation states - ngAnimate will automatically handle the style toggling for you.
+ *
+ * @animations
+ * | Animation                                           | Occurs                                                                                                        |
+ * |-----------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
+ * | {@link $animate#addClass addClass} `.ng-hide`       | After the `ngShow` expression evaluates to a non truthy value and just before the contents are set to hidden. |
+ * | {@link $animate#removeClass removeClass} `.ng-hide` | After the `ngShow` expression evaluates to a truthy value and just before contents are set to visible.        |
+ *
+ * @element ANY
+ * @param {expression} ngShow If the {@link guide/expression expression} is truthy/falsy then the
+ *                            element is shown/hidden respectively.
+ *
+ * @example
+ * A simple example, animating the element's opacity:
+ *
+  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-show-simple">
+    <file name="index.html">
+      Show: <input type="checkbox" ng-model="checked" aria-label="Toggle ngShow"><br />
+      <div class="check-element animate-show-hide" ng-show="checked">
+        I show up when your checkbox is checked.
+      </div>
+    </file>
+    <file name="animations.css">
+      .animate-show-hide.ng-hide {
+        opacity: 0;
+      }
+
+      .animate-show-hide.ng-hide-add,
+      .animate-show-hide.ng-hide-remove {
+        transition: all linear 0.5s;
+      }
+
+      .check-element {
+        border: 1px solid black;
+        opacity: 1;
+        padding: 10px;
+      }
+    </file>
+    <file name="protractor.js" type="protractor">
+      it('should check ngShow', function() {
+        var checkbox = element(by.model('checked'));
+        var checkElem = element(by.css('.check-element'));
+
+        expect(checkElem.isDisplayed()).toBe(false);
+        checkbox.click();
+        expect(checkElem.isDisplayed()).toBe(true);
+      });
+    </file>
+  </example>
+ *
+ * <hr />
+ * @example
+ * A more complex example, featuring different show/hide animations:
+ *
+  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-show-complex">
+    <file name="index.html">
+      Show: <input type="checkbox" ng-model="checked" aria-label="Toggle ngShow"><br />
+      <div class="check-element funky-show-hide" ng-show="checked">
+        I show up when your checkbox is checked.
+      </div>
+    </file>
+    <file name="animations.css">
+      body {
+        overflow: hidden;
+        perspective: 1000px;
+      }
+
+      .funky-show-hide.ng-hide-add {
+        transform: rotateZ(0);
+        transform-origin: right;
+        transition: all 0.5s ease-in-out;
+      }
+
+      .funky-show-hide.ng-hide-add.ng-hide-add-active {
+        transform: rotateZ(-135deg);
+      }
+
+      .funky-show-hide.ng-hide-remove {
+        transform: rotateY(90deg);
+        transform-origin: left;
+        transition: all 0.5s ease;
+      }
+
+      .funky-show-hide.ng-hide-remove.ng-hide-remove-active {
+        transform: rotateY(0);
+      }
+
+      .check-element {
+        border: 1px solid black;
+        opacity: 1;
+        padding: 10px;
+      }
+    </file>
+    <file name="protractor.js" type="protractor">
+      it('should check ngShow', function() {
+        var checkbox = element(by.model('checked'));
+        var checkElem = element(by.css('.check-element'));
+
+        expect(checkElem.isDisplayed()).toBe(false);
+        checkbox.click();
+        expect(checkElem.isDisplayed()).toBe(true);
+      });
+    </file>
+  </example>
+ */
+var ngShowDirective = ['$animate', function($animate) {
+  return {
+    restrict: 'A',
+    multiElement: true,
+    link: function(scope, element, attr) {
+      scope.$watch(attr.ngShow, function ngShowWatchAction(value) {
+        // we're adding a temporary, animation-specific class for ng-hide since this way
+        // we can control when the element is actually displayed on screen without having
+        // to have a global/greedy CSS selector that breaks when other animations are run.
+        // Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845
+        $animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {
+          tempClasses: NG_HIDE_IN_PROGRESS_CLASS
+        });
+      });
+    }
+  };
+}];
+
+
+/**
+ * @ngdoc directive
+ * @name ngHide
+ * @multiElement
+ *
+ * @description
+ * The `ngHide` directive shows or hides the given HTML element based on the expression provided to
+ * the `ngHide` attribute.
+ *
+ * The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
+ * The `.ng-hide` CSS class is predefined in AngularJS and sets the display style to none (using an
+ * `!important` flag). For CSP mode please add `angular-csp.css` to your HTML file (see
+ * {@link ng.directive:ngCsp ngCsp}).
+ *
+ * ```html
+ * <!-- when $scope.myValue is truthy (element is hidden) -->
+ * <div ng-hide="myValue" class="ng-hide"></div>
+ *
+ * <!-- when $scope.myValue is falsy (element is visible) -->
+ * <div ng-hide="myValue"></div>
+ * ```
+ *
+ * When the `ngHide` expression evaluates to a truthy value then the `.ng-hide` CSS class is added
+ * to the class attribute on the element causing it to become hidden. When falsy, the `.ng-hide`
+ * CSS class is removed from the element causing the element not to appear hidden.
+ *
+ * ## Why is `!important` used?
+ *
+ * You may be wondering why `!important` is used for the `.ng-hide` CSS class. This is because the
+ * `.ng-hide` selector can be easily overridden by heavier selectors. For example, something as
+ * simple as changing the display style on a HTML list item would make hidden elements appear
+ * visible. This also becomes a bigger issue when dealing with CSS frameworks.
+ *
+ * By using `!important`, the show and hide behavior will work as expected despite any clash between
+ * CSS selector specificity (when `!important` isn't used with any conflicting styles). If a
+ * developer chooses to override the styling to change how to hide an element then it is just a
+ * matter of using `!important` in their own CSS code.
+ *
+ * ### Overriding `.ng-hide`
+ *
+ * By default, the `.ng-hide` class will style the element with `display: none !important`. If you
+ * wish to change the hide behavior with `ngShow`/`ngHide`, you can simply overwrite the styles for
+ * the `.ng-hide` CSS class. Note that the selector that needs to be used is actually
+ * `.ng-hide:not(.ng-hide-animate)` to cope with extra animation classes that can be added.
+ *
+ * ```css
+ * .ng-hide:not(.ng-hide-animate) {
+ *   /&#42; These are just alternative ways of hiding an element &#42;/
+ *   display: block!important;
+ *   position: absolute;
+ *   top: -9999px;
+ *   left: -9999px;
+ * }
+ * ```
+ *
+ * By default you don't need to override in CSS anything and the animations will work around the
+ * display style.
+ *
+ * ## A note about animations with `ngHide`
+ *
+ * Animations in `ngShow`/`ngHide` work with the show and hide events that are triggered when the
+ * directive expression is true and false. This system works like the animation system present with
+ * `ngClass` except that you must also include the `!important` flag to override the display
+ * property so that the elements are not actually hidden during the animation.
+ *
+ * ```css
+ * /&#42; A working example can be found at the bottom of this page. &#42;/
+ * .my-element.ng-hide-add, .my-element.ng-hide-remove {
+ *   transition: all 0.5s linear;
+ * }
+ *
+ * .my-element.ng-hide-add { ... }
+ * .my-element.ng-hide-add.ng-hide-add-active { ... }
+ * .my-element.ng-hide-remove { ... }
+ * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
+ * ```
+ *
+ * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display property
+ * to block during animation states - ngAnimate will automatically handle the style toggling for you.
+ *
+ * @animations
+ * | Animation                                           | Occurs                                                                                                     |
+ * |-----------------------------------------------------|------------------------------------------------------------------------------------------------------------|
+ * | {@link $animate#addClass addClass} `.ng-hide`       | After the `ngHide` expression evaluates to a truthy value and just before the contents are set to hidden.  |
+ * | {@link $animate#removeClass removeClass} `.ng-hide` | After the `ngHide` expression evaluates to a non truthy value and just before contents are set to visible. |
+ *
+ *
+ * @element ANY
+ * @param {expression} ngHide If the {@link guide/expression expression} is truthy/falsy then the
+ *                            element is hidden/shown respectively.
+ *
+ * @example
+ * A simple example, animating the element's opacity:
+ *
+  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-hide-simple">
+    <file name="index.html">
+      Hide: <input type="checkbox" ng-model="checked" aria-label="Toggle ngHide"><br />
+      <div class="check-element animate-show-hide" ng-hide="checked">
+        I hide when your checkbox is checked.
+      </div>
+    </file>
+    <file name="animations.css">
+      .animate-show-hide.ng-hide {
+        opacity: 0;
+      }
+
+      .animate-show-hide.ng-hide-add,
+      .animate-show-hide.ng-hide-remove {
+        transition: all linear 0.5s;
+      }
+
+      .check-element {
+        border: 1px solid black;
+        opacity: 1;
+        padding: 10px;
+      }
+    </file>
+    <file name="protractor.js" type="protractor">
+      it('should check ngHide', function() {
+        var checkbox = element(by.model('checked'));
+        var checkElem = element(by.css('.check-element'));
+
+        expect(checkElem.isDisplayed()).toBe(true);
+        checkbox.click();
+        expect(checkElem.isDisplayed()).toBe(false);
+      });
+    </file>
+  </example>
+ *
+ * <hr />
+ * @example
+ * A more complex example, featuring different show/hide animations:
+ *
+  <example module="ngAnimate" deps="angular-animate.js" animations="true" name="ng-hide-complex">
+    <file name="index.html">
+      Hide: <input type="checkbox" ng-model="checked" aria-label="Toggle ngHide"><br />
+      <div class="check-element funky-show-hide" ng-hide="checked">
+        I hide when your checkbox is checked.
+      </div>
+    </file>
+    <file name="animations.css">
+      body {
+        overflow: hidden;
+        perspective: 1000px;
+      }
+
+      .funky-show-hide.ng-hide-add {
+        transform: rotateZ(0);
+        transform-origin: right;
+        transition: all 0.5s ease-in-out;
+      }
+
+      .funky-show-hide.ng-hide-add.ng-hide-add-active {
+        transform: rotateZ(-135deg);
+      }
+
+      .funky-show-hide.ng-hide-remove {
+        transform: rotateY(90deg);
+        transform-origin: left;
+        transition: all 0.5s ease;
+      }
+
+      .funky-show-hide.ng-hide-remove.ng-hide-remove-active {
+        transform: rotateY(0);
+      }
+
+      .check-element {
+        border: 1px solid black;
+        opacity: 1;
+        padding: 10px;
+      }
+    </file>
+    <file name="protractor.js" type="protractor">
+      it('should check ngHide', function() {
+        var checkbox = element(by.model('checked'));
+        var checkElem = element(by.css('.check-element'));
+
+        expect(checkElem.isDisplayed()).toBe(true);
+        checkbox.click();
+        expect(checkElem.isDisplayed()).toBe(false);
+      });
+    </file>
+  </example>
+ */
+var ngHideDirective = ['$animate', function($animate) {
+  return {
+    restrict: 'A',
+    multiElement: true,
+    link: function(scope, element, attr) {
+      scope.$watch(attr.ngHide, function ngHideWatchAction(value) {
+        // The comment inside of the ngShowDirective explains why we add and
+        // remove a temporary class for the show/hide animation
+        $animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, {
+          tempClasses: NG_HIDE_IN_PROGRESS_CLASS
+        });
+      });
+    }
+  };
+}];
+
+/**
+ * @ngdoc directive
+ * @name ngStyle
+ * @restrict AC
+ *
+ * @description
+ * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally.
+ *
+ * @knownIssue
+ * You should not use {@link guide/interpolation interpolation} in the value of the `style`
+ * attribute, when using the `ngStyle` directive on the same element.
+ * See {@link guide/interpolation#known-issues here} for more info.
+ *
+ * @element ANY
+ * @param {expression} ngStyle
+ *
+ * {@link guide/expression Expression} which evals to an
+ * object whose keys are CSS style names and values are corresponding values for those CSS
+ * keys.
+ *
+ * Since some CSS style names are not valid keys for an object, they must be quoted.
+ * See the 'background-color' style in the example below.
+ *
+ * @example
+   <example name="ng-style">
+     <file name="index.html">
+        <input type="button" value="set color" ng-click="myStyle={color:'red'}">
+        <input type="button" value="set background" ng-click="myStyle={'background-color':'blue'}">
+        <input type="button" value="clear" ng-click="myStyle={}">
+        <br/>
+        <span ng-style="myStyle">Sample Text</span>
+        <pre>myStyle={{myStyle}}</pre>
+     </file>
+     <file name="style.css">
+       span {
+         color: black;
+       }
+     </file>
+     <file name="protractor.js" type="protractor">
+       var colorSpan = element(by.css('span'));
+
+       it('should check ng-style', function() {
+         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
+         element(by.css('input[value=\'set color\']')).click();
+         expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
+         element(by.css('input[value=clear]')).click();
+         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
+       });
+     </file>
+   </example>
+ */
+var ngStyleDirective = ngDirective(function(scope, element, attr) {
+  scope.$watch(attr.ngStyle, function ngStyleWatchAction(newStyles, oldStyles) {
+    if (oldStyles && (newStyles !== oldStyles)) {
+      forEach(oldStyles, function(val, style) { element.css(style, '');});
+    }
+    if (newStyles) element.css(newStyles);
+  }, true);
+});
+
+/**
+ * @ngdoc directive
+ * @name ngSwitch
+ * @restrict EA
+ *
+ * @description
+ * The `ngSwitch` directive is used to conditionally swap DOM structure on your template based on a scope expression.
+ * Elements within `ngSwitch` but without `ngSwitchWhen` or `ngSwitchDefault` directives will be preserved at the location
+ * as specified in the template.
+ *
+ * The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it
+ * from the template cache), `ngSwitch` simply chooses one of the nested elements and makes it visible based on which element
+ * matches the value obtained from the evaluated expression. In other words, you define a container element
+ * (where you place the directive), place an expression on the **`on="..."` attribute**
+ * (or the **`ng-switch="..."` attribute**), define any inner elements inside of the directive and place
+ * a when attribute per element. The when attribute is used to inform ngSwitch which element to display when the on
+ * expression is evaluated. If a matching expression is not found via a when attribute then an element with the default
+ * attribute is displayed.
+ *
+ * <div class="alert alert-info">
+ * Be aware that the attribute values to match against cannot be expressions. They are interpreted
+ * as literal string values to match against.
+ * For example, **`ng-switch-when="someVal"`** will match against the string `"someVal"` not against the
+ * value of the expression `$scope.someVal`.
+ * </div>
+
+ * @animations
+ * | Animation                        | Occurs                              |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#enter enter}  | after the ngSwitch contents change and the matched child element is placed inside the container |
+ * | {@link ng.$animate#leave leave}  | after the ngSwitch contents change and just before the former contents are removed from the DOM |
+ *
+ * @usage
+ *
+ * ```
+ * <ANY ng-switch="expression">
+ *   <ANY ng-switch-when="matchValue1">...</ANY>
+ *   <ANY ng-switch-when="matchValue2">...</ANY>
+ *   <ANY ng-switch-default>...</ANY>
+ * </ANY>
+ * ```
+ *
+ *
+ * @scope
+ * @priority 1200
+ * @param {*} ngSwitch|on expression to match against <code>ng-switch-when</code>.
+ * On child elements add:
+ *
+ * * `ngSwitchWhen`: the case statement to match against. If match then this
+ *   case will be displayed. If the same match appears multiple times, all the
+ *   elements will be displayed. It is possible to associate multiple values to
+ *   the same `ngSwitchWhen` by defining the optional attribute
+ *   `ngSwitchWhenSeparator`. The separator will be used to split the value of
+ *   the `ngSwitchWhen` attribute into multiple tokens, and the element will show
+ *   if any of the `ngSwitch` evaluates to any of these tokens.
+ * * `ngSwitchDefault`: the default case when no other case match. If there
+ *   are multiple default cases, all of them will be displayed when no other
+ *   case match.
+ *
+ *
+ * @example
+  <example module="switchExample" deps="angular-animate.js" animations="true" name="ng-switch">
+    <file name="index.html">
+      <div ng-controller="ExampleController">
+        <select ng-model="selection" ng-options="item for item in items">
+        </select>
+        <code>selection={{selection}}</code>
+        <hr/>
+        <div class="animate-switch-container"
+          ng-switch on="selection">
+            <div class="animate-switch" ng-switch-when="settings|options" ng-switch-when-separator="|">Settings Div</div>
+            <div class="animate-switch" ng-switch-when="home">Home Span</div>
+            <div class="animate-switch" ng-switch-default>default</div>
+        </div>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('switchExample', ['ngAnimate'])
+        .controller('ExampleController', ['$scope', function($scope) {
+          $scope.items = ['settings', 'home', 'options', 'other'];
+          $scope.selection = $scope.items[0];
+        }]);
+    </file>
+    <file name="animations.css">
+      .animate-switch-container {
+        position:relative;
+        background:white;
+        border:1px solid black;
+        height:40px;
+        overflow:hidden;
+      }
+
+      .animate-switch {
+        padding:10px;
+      }
+
+      .animate-switch.ng-animate {
+        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
+
+        position:absolute;
+        top:0;
+        left:0;
+        right:0;
+        bottom:0;
+      }
+
+      .animate-switch.ng-leave.ng-leave-active,
+      .animate-switch.ng-enter {
+        top:-50px;
+      }
+      .animate-switch.ng-leave,
+      .animate-switch.ng-enter.ng-enter-active {
+        top:0;
+      }
+    </file>
+    <file name="protractor.js" type="protractor">
+      var switchElem = element(by.css('[ng-switch]'));
+      var select = element(by.model('selection'));
+
+      it('should start in settings', function() {
+        expect(switchElem.getText()).toMatch(/Settings Div/);
+      });
+      it('should change to home', function() {
+        select.all(by.css('option')).get(1).click();
+        expect(switchElem.getText()).toMatch(/Home Span/);
+      });
+      it('should change to settings via "options"', function() {
+        select.all(by.css('option')).get(2).click();
+        expect(switchElem.getText()).toMatch(/Settings Div/);
+      });
+      it('should select default', function() {
+        select.all(by.css('option')).get(3).click();
+        expect(switchElem.getText()).toMatch(/default/);
+      });
+    </file>
+  </example>
+ */
+var ngSwitchDirective = ['$animate', '$compile', function($animate, $compile) {
+  return {
+    require: 'ngSwitch',
+
+    // asks for $scope to fool the BC controller module
+    controller: ['$scope', function NgSwitchController() {
+     this.cases = {};
+    }],
+    link: function(scope, element, attr, ngSwitchController) {
+      var watchExpr = attr.ngSwitch || attr.on,
+          selectedTranscludes = [],
+          selectedElements = [],
+          previousLeaveAnimations = [],
+          selectedScopes = [];
+
+      var spliceFactory = function(array, index) {
+          return function(response) {
+            if (response !== false) array.splice(index, 1);
+          };
+      };
+
+      scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
+        var i, ii;
+
+        // Start with the last, in case the array is modified during the loop
+        while (previousLeaveAnimations.length) {
+          $animate.cancel(previousLeaveAnimations.pop());
+        }
+
+        for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
+          var selected = getBlockNodes(selectedElements[i].clone);
+          selectedScopes[i].$destroy();
+          var runner = previousLeaveAnimations[i] = $animate.leave(selected);
+          runner.done(spliceFactory(previousLeaveAnimations, i));
+        }
+
+        selectedElements.length = 0;
+        selectedScopes.length = 0;
+
+        if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
+          forEach(selectedTranscludes, function(selectedTransclude) {
+            selectedTransclude.transclude(function(caseElement, selectedScope) {
+              selectedScopes.push(selectedScope);
+              var anchor = selectedTransclude.element;
+              caseElement[caseElement.length++] = $compile.$$createComment('end ngSwitchWhen');
+              var block = { clone: caseElement };
+
+              selectedElements.push(block);
+              $animate.enter(caseElement, anchor.parent(), anchor);
+            });
+          });
+        }
+      });
+    }
+  };
+}];
+
+var ngSwitchWhenDirective = ngDirective({
+  transclude: 'element',
+  priority: 1200,
+  require: '^ngSwitch',
+  multiElement: true,
+  link: function(scope, element, attrs, ctrl, $transclude) {
+
+    var cases = attrs.ngSwitchWhen.split(attrs.ngSwitchWhenSeparator).sort().filter(
+      // Filter duplicate cases
+      function(element, index, array) { return array[index - 1] !== element; }
+    );
+
+    forEach(cases, function(whenCase) {
+      ctrl.cases['!' + whenCase] = (ctrl.cases['!' + whenCase] || []);
+      ctrl.cases['!' + whenCase].push({ transclude: $transclude, element: element });
+    });
+  }
+});
+
+var ngSwitchDefaultDirective = ngDirective({
+  transclude: 'element',
+  priority: 1200,
+  require: '^ngSwitch',
+  multiElement: true,
+  link: function(scope, element, attr, ctrl, $transclude) {
+    ctrl.cases['?'] = (ctrl.cases['?'] || []);
+    ctrl.cases['?'].push({ transclude: $transclude, element: element });
+   }
+});
+
+/**
+ * @ngdoc directive
+ * @name ngTransclude
+ * @restrict EAC
+ *
+ * @description
+ * Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.
+ *
+ * You can specify that you want to insert a named transclusion slot, instead of the default slot, by providing the slot name
+ * as the value of the `ng-transclude` or `ng-transclude-slot` attribute.
+ *
+ * If the transcluded content is not empty (i.e. contains one or more DOM nodes, including whitespace text nodes), any existing
+ * content of this element will be removed before the transcluded content is inserted.
+ * If the transcluded content is empty (or only whitespace), the existing content is left intact. This lets you provide fallback
+ * content in the case that no transcluded content is provided.
+ *
+ * @element ANY
+ *
+ * @param {string} ngTransclude|ngTranscludeSlot the name of the slot to insert at this point. If this is not provided, is empty
+ *                                               or its value is the same as the name of the attribute then the default slot is used.
+ *
+ * @example
+ * ### Basic transclusion
+ * This example demonstrates basic transclusion of content into a component directive.
+ * <example name="simpleTranscludeExample" module="transcludeExample">
+ *   <file name="index.html">
+ *     <script>
+ *       angular.module('transcludeExample', [])
+ *        .directive('pane', function(){
+ *           return {
+ *             restrict: 'E',
+ *             transclude: true,
+ *             scope: { title:'@' },
+ *             template: '<div style="border: 1px solid black;">' +
+ *                         '<div style="background-color: gray">{{title}}</div>' +
+ *                         '<ng-transclude></ng-transclude>' +
+ *                       '</div>'
+ *           };
+ *       })
+ *       .controller('ExampleController', ['$scope', function($scope) {
+ *         $scope.title = 'Lorem Ipsum';
+ *         $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
+ *       }]);
+ *     </script>
+ *     <div ng-controller="ExampleController">
+ *       <input ng-model="title" aria-label="title"> <br/>
+ *       <textarea ng-model="text" aria-label="text"></textarea> <br/>
+ *       <pane title="{{title}}"><span>{{text}}</span></pane>
+ *     </div>
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+ *      it('should have transcluded', function() {
+ *        var titleElement = element(by.model('title'));
+ *        titleElement.clear();
+ *        titleElement.sendKeys('TITLE');
+ *        var textElement = element(by.model('text'));
+ *        textElement.clear();
+ *        textElement.sendKeys('TEXT');
+ *        expect(element(by.binding('title')).getText()).toEqual('TITLE');
+ *        expect(element(by.binding('text')).getText()).toEqual('TEXT');
+ *      });
+ *   </file>
+ * </example>
+ *
+ * @example
+ * ### Transclude fallback content
+ * This example shows how to use `NgTransclude` with fallback content, that
+ * is displayed if no transcluded content is provided.
+ *
+ * <example module="transcludeFallbackContentExample" name="ng-transclude">
+ * <file name="index.html">
+ * <script>
+ * angular.module('transcludeFallbackContentExample', [])
+ * .directive('myButton', function(){
+ *             return {
+ *               restrict: 'E',
+ *               transclude: true,
+ *               scope: true,
+ *               template: '<button style="cursor: pointer;">' +
+ *                           '<ng-transclude>' +
+ *                             '<b style="color: red;">Button1</b>' +
+ *                           '</ng-transclude>' +
+ *                         '</button>'
+ *             };
+ *         });
+ * </script>
+ * <!-- fallback button content -->
+ * <my-button id="fallback"></my-button>
+ * <!-- modified button content -->
+ * <my-button id="modified">
+ *   <i style="color: green;">Button2</i>
+ * </my-button>
+ * </file>
+ * <file name="protractor.js" type="protractor">
+ * it('should have different transclude element content', function() {
+ *          expect(element(by.id('fallback')).getText()).toBe('Button1');
+ *          expect(element(by.id('modified')).getText()).toBe('Button2');
+ *        });
+ * </file>
+ * </example>
+ *
+ * @example
+ * ### Multi-slot transclusion
+ * This example demonstrates using multi-slot transclusion in a component directive.
+ * <example name="multiSlotTranscludeExample" module="multiSlotTranscludeExample">
+ *   <file name="index.html">
+ *    <style>
+ *      .title, .footer {
+ *        background-color: gray
+ *      }
+ *    </style>
+ *    <div ng-controller="ExampleController">
+ *      <input ng-model="title" aria-label="title"> <br/>
+ *      <textarea ng-model="text" aria-label="text"></textarea> <br/>
+ *      <pane>
+ *        <pane-title><a ng-href="{{link}}">{{title}}</a></pane-title>
+ *        <pane-body><p>{{text}}</p></pane-body>
+ *      </pane>
+ *    </div>
+ *   </file>
+ *   <file name="app.js">
+ *    angular.module('multiSlotTranscludeExample', [])
+ *     .directive('pane', function() {
+ *        return {
+ *          restrict: 'E',
+ *          transclude: {
+ *            'title': '?paneTitle',
+ *            'body': 'paneBody',
+ *            'footer': '?paneFooter'
+ *          },
+ *          template: '<div style="border: 1px solid black;">' +
+ *                      '<div class="title" ng-transclude="title">Fallback Title</div>' +
+ *                      '<div ng-transclude="body"></div>' +
+ *                      '<div class="footer" ng-transclude="footer">Fallback Footer</div>' +
+ *                    '</div>'
+ *        };
+ *    })
+ *    .controller('ExampleController', ['$scope', function($scope) {
+ *      $scope.title = 'Lorem Ipsum';
+ *      $scope.link = 'https://google.com';
+ *      $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
+ *    }]);
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+ *      it('should have transcluded the title and the body', function() {
+ *        var titleElement = element(by.model('title'));
+ *        titleElement.clear();
+ *        titleElement.sendKeys('TITLE');
+ *        var textElement = element(by.model('text'));
+ *        textElement.clear();
+ *        textElement.sendKeys('TEXT');
+ *        expect(element(by.css('.title')).getText()).toEqual('TITLE');
+ *        expect(element(by.binding('text')).getText()).toEqual('TEXT');
+ *        expect(element(by.css('.footer')).getText()).toEqual('Fallback Footer');
+ *      });
+ *   </file>
+ * </example>
+ */
+var ngTranscludeMinErr = minErr('ngTransclude');
+var ngTranscludeDirective = ['$compile', function($compile) {
+  return {
+    restrict: 'EAC',
+    terminal: true,
+    compile: function ngTranscludeCompile(tElement) {
+
+      // Remove and cache any original content to act as a fallback
+      var fallbackLinkFn = $compile(tElement.contents());
+      tElement.empty();
+
+      return function ngTranscludePostLink($scope, $element, $attrs, controller, $transclude) {
+
+        if (!$transclude) {
+          throw ngTranscludeMinErr('orphan',
+          'Illegal use of ngTransclude directive in the template! ' +
+          'No parent directive that requires a transclusion found. ' +
+          'Element: {0}',
+          startingTag($element));
+        }
+
+
+        // If the attribute is of the form: `ng-transclude="ng-transclude"` then treat it like the default
+        if ($attrs.ngTransclude === $attrs.$attr.ngTransclude) {
+          $attrs.ngTransclude = '';
+        }
+        var slotName = $attrs.ngTransclude || $attrs.ngTranscludeSlot;
+
+        // If the slot is required and no transclusion content is provided then this call will throw an error
+        $transclude(ngTranscludeCloneAttachFn, null, slotName);
+
+        // If the slot is optional and no transclusion content is provided then use the fallback content
+        if (slotName && !$transclude.isSlotFilled(slotName)) {
+          useFallbackContent();
+        }
+
+        function ngTranscludeCloneAttachFn(clone, transcludedScope) {
+          if (clone.length && notWhitespace(clone)) {
+            $element.append(clone);
+          } else {
+            useFallbackContent();
+            // There is nothing linked against the transcluded scope since no content was available,
+            // so it should be safe to clean up the generated scope.
+            transcludedScope.$destroy();
+          }
+        }
+
+        function useFallbackContent() {
+          // Since this is the fallback content rather than the transcluded content,
+          // we link against the scope of this directive rather than the transcluded scope
+          fallbackLinkFn($scope, function(clone) {
+            $element.append(clone);
+          });
+        }
+
+        function notWhitespace(nodes) {
+          for (var i = 0, ii = nodes.length; i < ii; i++) {
+            var node = nodes[i];
+            if (node.nodeType !== NODE_TYPE_TEXT || node.nodeValue.trim()) {
+              return true;
+            }
+          }
+        }
+      };
+    }
+  };
+}];
+
+/**
+ * @ngdoc directive
+ * @name script
+ * @restrict E
+ *
+ * @description
+ * Load the content of a `<script>` element into {@link ng.$templateCache `$templateCache`}, so that the
+ * template can be used by {@link ng.directive:ngInclude `ngInclude`},
+ * {@link ngRoute.directive:ngView `ngView`}, or {@link guide/directive directives}. The type of the
+ * `<script>` element must be specified as `text/ng-template`, and a cache name for the template must be
+ * assigned through the element's `id`, which can then be used as a directive's `templateUrl`.
+ *
+ * @param {string} type Must be set to `'text/ng-template'`.
+ * @param {string} id Cache name of the template.
+ *
+ * @example
+  <example  name="script-tag">
+    <file name="index.html">
+      <script type="text/ng-template" id="/tpl.html">
+        Content of the template.
+      </script>
+
+      <a ng-click="currentTpl='/tpl.html'" id="tpl-link">Load inlined template</a>
+      <div id="tpl-content" ng-include src="currentTpl"></div>
+    </file>
+    <file name="protractor.js" type="protractor">
+      it('should load template defined inside script tag', function() {
+        element(by.css('#tpl-link')).click();
+        expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/);
+      });
+    </file>
+  </example>
+ */
+var scriptDirective = ['$templateCache', function($templateCache) {
+  return {
+    restrict: 'E',
+    terminal: true,
+    compile: function(element, attr) {
+      if (attr.type === 'text/ng-template') {
+        var templateUrl = attr.id,
+            text = element[0].text;
+
+        $templateCache.put(templateUrl, text);
+      }
+    }
+  };
+}];
+
+/* exported selectDirective, optionDirective */
+
+var noopNgModelController = { $setViewValue: noop, $render: noop };
+
+function setOptionSelectedStatus(optionEl, value) {
+  optionEl.prop('selected', value); // needed for IE
+  /**
+   * When unselecting an option, setting the property to null / false should be enough
+   * However, screenreaders might react to the selected attribute instead, see
+   * https://github.com/angular/angular.js/issues/14419
+   * Note: "selected" is a boolean attr and will be removed when the "value" arg in attr() is false
+   * or null
+   */
+  optionEl.attr('selected', value);
+}
+
+/**
+ * @ngdoc type
+ * @name  select.SelectController
+ * @description
+ * The controller for the `<select>` directive. This provides support for reading
+ * and writing the selected value(s) of the control and also coordinates dynamically
+ * added `<option>` elements, perhaps by an `ngRepeat` directive.
+ */
+var SelectController =
+        ['$element', '$scope', /** @this */ function($element, $scope) {
+
+  var self = this,
+      optionsMap = new NgMap();
+
+  self.selectValueMap = {}; // Keys are the hashed values, values the original values
+
+  // If the ngModel doesn't get provided then provide a dummy noop version to prevent errors
+  self.ngModelCtrl = noopNgModelController;
+  self.multiple = false;
+
+  // The "unknown" option is one that is prepended to the list if the viewValue
+  // does not match any of the options. When it is rendered the value of the unknown
+  // option is '? XXX ?' where XXX is the hashKey of the value that is not known.
+  //
+  // We can't just jqLite('<option>') since jqLite is not smart enough
+  // to create it in <select> and IE barfs otherwise.
+  self.unknownOption = jqLite(window.document.createElement('option'));
+
+  // The empty option is an option with the value '' that te application developer can
+  // provide inside the select. When the model changes to a value that doesn't match an option,
+  // it is selected - so if an empty option is provided, no unknown option is generated.
+  // However, the empty option is not removed when the model matches an option. It is always selectable
+  // and indicates that a "null" selection has been made.
+  self.hasEmptyOption = false;
+  self.emptyOption = undefined;
+
+  self.renderUnknownOption = function(val) {
+    var unknownVal = self.generateUnknownOptionValue(val);
+    self.unknownOption.val(unknownVal);
+    $element.prepend(self.unknownOption);
+    setOptionSelectedStatus(self.unknownOption, true);
+    $element.val(unknownVal);
+  };
+
+  self.updateUnknownOption = function(val) {
+    var unknownVal = self.generateUnknownOptionValue(val);
+    self.unknownOption.val(unknownVal);
+    setOptionSelectedStatus(self.unknownOption, true);
+    $element.val(unknownVal);
+  };
+
+  self.generateUnknownOptionValue = function(val) {
+    return '? ' + hashKey(val) + ' ?';
+  };
+
+  self.removeUnknownOption = function() {
+    if (self.unknownOption.parent()) self.unknownOption.remove();
+  };
+
+  self.selectEmptyOption = function() {
+    if (self.emptyOption) {
+      $element.val('');
+      setOptionSelectedStatus(self.emptyOption, true);
+    }
+  };
+
+  self.unselectEmptyOption = function() {
+    if (self.hasEmptyOption) {
+      self.emptyOption.removeAttr('selected');
+    }
+  };
+
+  $scope.$on('$destroy', function() {
+    // disable unknown option so that we don't do work when the whole select is being destroyed
+    self.renderUnknownOption = noop;
+  });
+
+  // Read the value of the select control, the implementation of this changes depending
+  // upon whether the select can have multiple values and whether ngOptions is at work.
+  self.readValue = function readSingleValue() {
+    var val = $element.val();
+    // ngValue added option values are stored in the selectValueMap, normal interpolations are not
+    var realVal = val in self.selectValueMap ? self.selectValueMap[val] : val;
+
+    if (self.hasOption(realVal)) {
+      return realVal;
+    }
+
+    return null;
+  };
+
+
+  // Write the value to the select control, the implementation of this changes depending
+  // upon whether the select can have multiple values and whether ngOptions is at work.
+  self.writeValue = function writeSingleValue(value) {
+    // Make sure to remove the selected attribute from the previously selected option
+    // Otherwise, screen readers might get confused
+    var currentlySelectedOption = $element[0].options[$element[0].selectedIndex];
+    if (currentlySelectedOption) setOptionSelectedStatus(jqLite(currentlySelectedOption), false);
+
+    if (self.hasOption(value)) {
+      self.removeUnknownOption();
+
+      var hashedVal = hashKey(value);
+      $element.val(hashedVal in self.selectValueMap ? hashedVal : value);
+
+      // Set selected attribute and property on selected option for screen readers
+      var selectedOption = $element[0].options[$element[0].selectedIndex];
+      setOptionSelectedStatus(jqLite(selectedOption), true);
+    } else {
+      if (value == null && self.emptyOption) {
+        self.removeUnknownOption();
+        self.selectEmptyOption();
+      } else if (self.unknownOption.parent().length) {
+        self.updateUnknownOption(value);
+      } else {
+        self.renderUnknownOption(value);
+      }
+    }
+  };
+
+
+  // Tell the select control that an option, with the given value, has been added
+  self.addOption = function(value, element) {
+    // Skip comment nodes, as they only pollute the `optionsMap`
+    if (element[0].nodeType === NODE_TYPE_COMMENT) return;
+
+    assertNotHasOwnProperty(value, '"option value"');
+    if (value === '') {
+      self.hasEmptyOption = true;
+      self.emptyOption = element;
+    }
+    var count = optionsMap.get(value) || 0;
+    optionsMap.set(value, count + 1);
+    // Only render at the end of a digest. This improves render performance when many options
+    // are added during a digest and ensures all relevant options are correctly marked as selected
+    scheduleRender();
+  };
+
+  // Tell the select control that an option, with the given value, has been removed
+  self.removeOption = function(value) {
+    var count = optionsMap.get(value);
+    if (count) {
+      if (count === 1) {
+        optionsMap.delete(value);
+        if (value === '') {
+          self.hasEmptyOption = false;
+          self.emptyOption = undefined;
+        }
+      } else {
+        optionsMap.set(value, count - 1);
+      }
+    }
+  };
+
+  // Check whether the select control has an option matching the given value
+  self.hasOption = function(value) {
+    return !!optionsMap.get(value);
+  };
+
+
+  var renderScheduled = false;
+  function scheduleRender() {
+    if (renderScheduled) return;
+    renderScheduled = true;
+    $scope.$$postDigest(function() {
+      renderScheduled = false;
+      self.ngModelCtrl.$render();
+    });
+  }
+
+  var updateScheduled = false;
+  function scheduleViewValueUpdate(renderAfter) {
+    if (updateScheduled) return;
+
+    updateScheduled = true;
+
+    $scope.$$postDigest(function() {
+      if ($scope.$$destroyed) return;
+
+      updateScheduled = false;
+      self.ngModelCtrl.$setViewValue(self.readValue());
+      if (renderAfter) self.ngModelCtrl.$render();
+    });
+  }
+
+
+  self.registerOption = function(optionScope, optionElement, optionAttrs, interpolateValueFn, interpolateTextFn) {
+
+    if (optionAttrs.$attr.ngValue) {
+      // The value attribute is set by ngValue
+      var oldVal, hashedVal = NaN;
+      optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) {
+
+        var removal;
+        var previouslySelected = optionElement.prop('selected');
+
+        if (isDefined(hashedVal)) {
+          self.removeOption(oldVal);
+          delete self.selectValueMap[hashedVal];
+          removal = true;
+        }
+
+        hashedVal = hashKey(newVal);
+        oldVal = newVal;
+        self.selectValueMap[hashedVal] = newVal;
+        self.addOption(newVal, optionElement);
+        // Set the attribute directly instead of using optionAttrs.$set - this stops the observer
+        // from firing a second time. Other $observers on value will also get the result of the
+        // ngValue expression, not the hashed value
+        optionElement.attr('value', hashedVal);
+
+        if (removal && previouslySelected) {
+          scheduleViewValueUpdate();
+        }
+
+      });
+    } else if (interpolateValueFn) {
+      // The value attribute is interpolated
+      optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) {
+        // This method is overwritten in ngOptions and has side-effects!
+        self.readValue();
+
+        var removal;
+        var previouslySelected = optionElement.prop('selected');
+
+        if (isDefined(oldVal)) {
+          self.removeOption(oldVal);
+          removal = true;
+        }
+        oldVal = newVal;
+        self.addOption(newVal, optionElement);
+
+        if (removal && previouslySelected) {
+          scheduleViewValueUpdate();
+        }
+      });
+    } else if (interpolateTextFn) {
+      // The text content is interpolated
+      optionScope.$watch(interpolateTextFn, function interpolateWatchAction(newVal, oldVal) {
+        optionAttrs.$set('value', newVal);
+        var previouslySelected = optionElement.prop('selected');
+        if (oldVal !== newVal) {
+          self.removeOption(oldVal);
+        }
+        self.addOption(newVal, optionElement);
+
+        if (oldVal && previouslySelected) {
+          scheduleViewValueUpdate();
+        }
+      });
+    } else {
+      // The value attribute is static
+      self.addOption(optionAttrs.value, optionElement);
+    }
+
+
+    optionAttrs.$observe('disabled', function(newVal) {
+
+      // Since model updates will also select disabled options (like ngOptions),
+      // we only have to handle options becoming disabled, not enabled
+
+      if (newVal === 'true' || newVal && optionElement.prop('selected')) {
+        if (self.multiple) {
+          scheduleViewValueUpdate(true);
+        } else {
+          self.ngModelCtrl.$setViewValue(null);
+          self.ngModelCtrl.$render();
+        }
+      }
+    });
+
+    optionElement.on('$destroy', function() {
+      var currentValue = self.readValue();
+      var removeValue = optionAttrs.value;
+
+      self.removeOption(removeValue);
+      scheduleRender();
+
+      if (self.multiple && currentValue && currentValue.indexOf(removeValue) !== -1 ||
+          currentValue === removeValue
+      ) {
+        // When multiple (selected) options are destroyed at the same time, we don't want
+        // to run a model update for each of them. Instead, run a single update in the $$postDigest
+        scheduleViewValueUpdate(true);
+      }
+    });
+  };
+}];
+
+/**
+ * @ngdoc directive
+ * @name select
+ * @restrict E
+ *
+ * @description
+ * HTML `select` element with angular data-binding.
+ *
+ * The `select` directive is used together with {@link ngModel `ngModel`} to provide data-binding
+ * between the scope and the `<select>` control (including setting default values).
+ * It also handles dynamic `<option>` elements, which can be added using the {@link ngRepeat `ngRepeat}` or
+ * {@link ngOptions `ngOptions`} directives.
+ *
+ * When an item in the `<select>` menu is selected, the value of the selected option will be bound
+ * to the model identified by the `ngModel` directive. With static or repeated options, this is
+ * the content of the `value` attribute or the textContent of the `<option>`, if the value attribute is missing.
+ * Value and textContent can be interpolated.
+ *
+ * ## Matching model and option values
+ *
+ * In general, the match between the model and an option is evaluated by strictly comparing the model
+ * value against the value of the available options.
+ *
+ * If you are setting the option value with the option's `value` attribute, or textContent, the
+ * value will always be a `string` which means that the model value must also be a string.
+ * Otherwise the `select` directive cannot match them correctly.
+ *
+ * To bind the model to a non-string value, you can use one of the following strategies:
+ * - the {@link ng.ngOptions `ngOptions`} directive
+ *   ({@link ng.select#using-select-with-ngoptions-and-setting-a-default-value})
+ * - the {@link ng.ngValue `ngValue`} directive, which allows arbitrary expressions to be
+ *   option values ({@link ng.select#using-ngvalue-to-bind-the-model-to-an-array-of-objects Example})
+ * - model $parsers / $formatters to convert the string value
+ *   ({@link ng.select#binding-select-to-a-non-string-value-via-ngmodel-parsing-formatting Example})
+ *
+ * If the viewValue of `ngModel` does not match any of the options, then the control
+ * will automatically add an "unknown" option, which it then removes when the mismatch is resolved.
+ *
+ * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
+ * be nested into the `<select>` element. This element will then represent the `null` or "not selected"
+ * option. See example below for demonstration.
+ *
+ * ## Choosing between `ngRepeat` and `ngOptions`
+ *
+ * In many cases, `ngRepeat` can be used on `<option>` elements instead of {@link ng.directive:ngOptions
+ * ngOptions} to achieve a similar result. However, `ngOptions` provides some benefits:
+ * - more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the
+ * comprehension expression
+ * - reduced memory consumption by not creating a new scope for each repeated instance
+ * - increased render speed by creating the options in a documentFragment instead of individually
+ *
+ * Specifically, select with repeated options slows down significantly starting at 2000 options in
+ * Chrome and Internet Explorer / Edge.
+ *
+ *
+ * @param {string} ngModel Assignable angular expression to data-bind to.
+ * @param {string=} name Property name of the form under which the control is published.
+ * @param {string=} multiple Allows multiple options to be selected. The selected values will be
+ *     bound to the model as an array.
+ * @param {string=} required Sets `required` validation error key if the value is not entered.
+ * @param {string=} ngRequired Adds required attribute and required validation constraint to
+ * the element when the ngRequired expression evaluates to true. Use ngRequired instead of required
+ * when you want to data-bind to the required attribute.
+ * @param {string=} ngChange Angular expression to be executed when selected option(s) changes due to user
+ *    interaction with the select element.
+ * @param {string=} ngOptions sets the options that the select is populated with and defines what is
+ * set on the model on selection. See {@link ngOptions `ngOptions`}.
+ * @param {string=} ngAttrSize sets the size of the select element dynamically. Uses the
+ * {@link guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes ngAttr} directive.
+ *
+ * @example
+ * ### Simple `select` elements with static options
+ *
+ * <example name="static-select" module="staticSelect">
+ * <file name="index.html">
+ * <div ng-controller="ExampleController">
+ *   <form name="myForm">
+ *     <label for="singleSelect"> Single select: </label><br>
+ *     <select name="singleSelect" ng-model="data.singleSelect">
+ *       <option value="option-1">Option 1</option>
+ *       <option value="option-2">Option 2</option>
+ *     </select><br>
+ *
+ *     <label for="singleSelect"> Single select with "not selected" option and dynamic option values: </label><br>
+ *     <select name="singleSelect" id="singleSelect" ng-model="data.singleSelect">
+ *       <option value="">---Please select---</option> <!-- not selected / blank option -->
+ *       <option value="{{data.option1}}">Option 1</option> <!-- interpolation -->
+ *       <option value="option-2">Option 2</option>
+ *     </select><br>
+ *     <button ng-click="forceUnknownOption()">Force unknown option</button><br>
+ *     <tt>singleSelect = {{data.singleSelect}}</tt>
+ *
+ *     <hr>
+ *     <label for="multipleSelect"> Multiple select: </label><br>
+ *     <select name="multipleSelect" id="multipleSelect" ng-model="data.multipleSelect" multiple>
+ *       <option value="option-1">Option 1</option>
+ *       <option value="option-2">Option 2</option>
+ *       <option value="option-3">Option 3</option>
+ *     </select><br>
+ *     <tt>multipleSelect = {{data.multipleSelect}}</tt><br/>
+ *   </form>
+ * </div>
+ * </file>
+ * <file name="app.js">
+ *  angular.module('staticSelect', [])
+ *    .controller('ExampleController', ['$scope', function($scope) {
+ *      $scope.data = {
+ *       singleSelect: null,
+ *       multipleSelect: [],
+ *       option1: 'option-1'
+ *      };
+ *
+ *      $scope.forceUnknownOption = function() {
+ *        $scope.data.singleSelect = 'nonsense';
+ *      };
+ *   }]);
+ * </file>
+ *</example>
+ *
+ * ### Using `ngRepeat` to generate `select` options
+ * <example name="select-ngrepeat" module="ngrepeatSelect">
+ * <file name="index.html">
+ * <div ng-controller="ExampleController">
+ *   <form name="myForm">
+ *     <label for="repeatSelect"> Repeat select: </label>
+ *     <select name="repeatSelect" id="repeatSelect" ng-model="data.model">
+ *       <option ng-repeat="option in data.availableOptions" value="{{option.id}}">{{option.name}}</option>
+ *     </select>
+ *   </form>
+ *   <hr>
+ *   <tt>model = {{data.model}}</tt><br/>
+ * </div>
+ * </file>
+ * <file name="app.js">
+ *  angular.module('ngrepeatSelect', [])
+ *    .controller('ExampleController', ['$scope', function($scope) {
+ *      $scope.data = {
+ *       model: null,
+ *       availableOptions: [
+ *         {id: '1', name: 'Option A'},
+ *         {id: '2', name: 'Option B'},
+ *         {id: '3', name: 'Option C'}
+ *       ]
+ *      };
+ *   }]);
+ * </file>
+ *</example>
+ *
+ * ### Using `ngValue` to bind the model to an array of objects
+ * <example name="select-ngvalue" module="ngvalueSelect">
+ * <file name="index.html">
+ * <div ng-controller="ExampleController">
+ *   <form name="myForm">
+ *     <label for="ngvalueselect"> ngvalue select: </label>
+ *     <select size="6" name="ngvalueselect" ng-model="data.model" multiple>
+ *       <option ng-repeat="option in data.availableOptions" ng-value="option.value">{{option.name}}</option>
+ *     </select>
+ *   </form>
+ *   <hr>
+ *   <pre>model = {{data.model | json}}</pre><br/>
+ * </div>
+ * </file>
+ * <file name="app.js">
+ *  angular.module('ngvalueSelect', [])
+ *    .controller('ExampleController', ['$scope', function($scope) {
+ *      $scope.data = {
+ *       model: null,
+ *       availableOptions: [
+           {value: 'myString', name: 'string'},
+           {value: 1, name: 'integer'},
+           {value: true, name: 'boolean'},
+           {value: null, name: 'null'},
+           {value: {prop: 'value'}, name: 'object'},
+           {value: ['a'], name: 'array'}
+ *       ]
+ *      };
+ *   }]);
+ * </file>
+ *</example>
+ *
+ * ### Using `select` with `ngOptions` and setting a default value
+ * See the {@link ngOptions ngOptions documentation} for more `ngOptions` usage examples.
+ *
+ * <example name="select-with-default-values" module="defaultValueSelect">
+ * <file name="index.html">
+ * <div ng-controller="ExampleController">
+ *   <form name="myForm">
+ *     <label for="mySelect">Make a choice:</label>
+ *     <select name="mySelect" id="mySelect"
+ *       ng-options="option.name for option in data.availableOptions track by option.id"
+ *       ng-model="data.selectedOption"></select>
+ *   </form>
+ *   <hr>
+ *   <tt>option = {{data.selectedOption}}</tt><br/>
+ * </div>
+ * </file>
+ * <file name="app.js">
+ *  angular.module('defaultValueSelect', [])
+ *    .controller('ExampleController', ['$scope', function($scope) {
+ *      $scope.data = {
+ *       availableOptions: [
+ *         {id: '1', name: 'Option A'},
+ *         {id: '2', name: 'Option B'},
+ *         {id: '3', name: 'Option C'}
+ *       ],
+ *       selectedOption: {id: '3', name: 'Option C'} //This sets the default value of the select in the ui
+ *       };
+ *   }]);
+ * </file>
+ *</example>
+ *
+ *
+ * ### Binding `select` to a non-string value via `ngModel` parsing / formatting
+ *
+ * <example name="select-with-non-string-options" module="nonStringSelect">
+ *   <file name="index.html">
+ *     <select ng-model="model.id" convert-to-number>
+ *       <option value="0">Zero</option>
+ *       <option value="1">One</option>
+ *       <option value="2">Two</option>
+ *     </select>
+ *     {{ model }}
+ *   </file>
+ *   <file name="app.js">
+ *     angular.module('nonStringSelect', [])
+ *       .run(function($rootScope) {
+ *         $rootScope.model = { id: 2 };
+ *       })
+ *       .directive('convertToNumber', function() {
+ *         return {
+ *           require: 'ngModel',
+ *           link: function(scope, element, attrs, ngModel) {
+ *             ngModel.$parsers.push(function(val) {
+ *               return parseInt(val, 10);
+ *             });
+ *             ngModel.$formatters.push(function(val) {
+ *               return '' + val;
+ *             });
+ *           }
+ *         };
+ *       });
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+ *     it('should initialize to model', function() {
+ *       expect(element(by.model('model.id')).$('option:checked').getText()).toEqual('Two');
+ *     });
+ *   </file>
+ * </example>
+ *
+ */
+var selectDirective = function() {
+
+  return {
+    restrict: 'E',
+    require: ['select', '?ngModel'],
+    controller: SelectController,
+    priority: 1,
+    link: {
+      pre: selectPreLink,
+      post: selectPostLink
+    }
+  };
+
+  function selectPreLink(scope, element, attr, ctrls) {
+
+      var selectCtrl = ctrls[0];
+      var ngModelCtrl = ctrls[1];
+
+      // if ngModel is not defined, we don't need to do anything but set the registerOption
+      // function to noop, so options don't get added internally
+      if (!ngModelCtrl) {
+        selectCtrl.registerOption = noop;
+        return;
+      }
+
+
+      selectCtrl.ngModelCtrl = ngModelCtrl;
+
+      // When the selected item(s) changes we delegate getting the value of the select control
+      // to the `readValue` method, which can be changed if the select can have multiple
+      // selected values or if the options are being generated by `ngOptions`
+      element.on('change', function() {
+        selectCtrl.removeUnknownOption();
+        scope.$apply(function() {
+          ngModelCtrl.$setViewValue(selectCtrl.readValue());
+        });
+      });
+
+      // If the select allows multiple values then we need to modify how we read and write
+      // values from and to the control; also what it means for the value to be empty and
+      // we have to add an extra watch since ngModel doesn't work well with arrays - it
+      // doesn't trigger rendering if only an item in the array changes.
+      if (attr.multiple) {
+        selectCtrl.multiple = true;
+
+        // Read value now needs to check each option to see if it is selected
+        selectCtrl.readValue = function readMultipleValue() {
+          var array = [];
+          forEach(element.find('option'), function(option) {
+            if (option.selected && !option.disabled) {
+              var val = option.value;
+              array.push(val in selectCtrl.selectValueMap ? selectCtrl.selectValueMap[val] : val);
+            }
+          });
+          return array;
+        };
+
+        // Write value now needs to set the selected property of each matching option
+        selectCtrl.writeValue = function writeMultipleValue(value) {
+          forEach(element.find('option'), function(option) {
+            var shouldBeSelected = !!value && (includes(value, option.value) ||
+                                               includes(value, selectCtrl.selectValueMap[option.value]));
+            var currentlySelected = option.selected;
+
+            // IE and Edge, adding options to the selection via shift+click/UP/DOWN,
+            // will de-select already selected options if "selected" on those options was set
+            // more than once (i.e. when the options were already selected)
+            // So we only modify the selected property if neccessary.
+            // Note: this behavior cannot be replicated via unit tests because it only shows in the
+            // actual user interface.
+            if (shouldBeSelected !== currentlySelected) {
+              setOptionSelectedStatus(jqLite(option), shouldBeSelected);
+            }
+
+          });
+        };
+
+        // we have to do it on each watch since ngModel watches reference, but
+        // we need to work of an array, so we need to see if anything was inserted/removed
+        var lastView, lastViewRef = NaN;
+        scope.$watch(function selectMultipleWatch() {
+          if (lastViewRef === ngModelCtrl.$viewValue && !equals(lastView, ngModelCtrl.$viewValue)) {
+            lastView = shallowCopy(ngModelCtrl.$viewValue);
+            ngModelCtrl.$render();
+          }
+          lastViewRef = ngModelCtrl.$viewValue;
+        });
+
+        // If we are a multiple select then value is now a collection
+        // so the meaning of $isEmpty changes
+        ngModelCtrl.$isEmpty = function(value) {
+          return !value || value.length === 0;
+        };
+
+      }
+    }
+
+    function selectPostLink(scope, element, attrs, ctrls) {
+      // if ngModel is not defined, we don't need to do anything
+      var ngModelCtrl = ctrls[1];
+      if (!ngModelCtrl) return;
+
+      var selectCtrl = ctrls[0];
+
+      // We delegate rendering to the `writeValue` method, which can be changed
+      // if the select can have multiple selected values or if the options are being
+      // generated by `ngOptions`.
+      // This must be done in the postLink fn to prevent $render to be called before
+      // all nodes have been linked correctly.
+      ngModelCtrl.$render = function() {
+        selectCtrl.writeValue(ngModelCtrl.$viewValue);
+      };
+    }
+};
+
+
+// The option directive is purely designed to communicate the existence (or lack of)
+// of dynamically created (and destroyed) option elements to their containing select
+// directive via its controller.
+var optionDirective = ['$interpolate', function($interpolate) {
+  return {
+    restrict: 'E',
+    priority: 100,
+    compile: function(element, attr) {
+      var interpolateValueFn, interpolateTextFn;
+
+      if (isDefined(attr.ngValue)) {
+        // Will be handled by registerOption
+      } else if (isDefined(attr.value)) {
+        // If the value attribute is defined, check if it contains an interpolation
+        interpolateValueFn = $interpolate(attr.value, true);
+      } else {
+        // If the value attribute is not defined then we fall back to the
+        // text content of the option element, which may be interpolated
+        interpolateTextFn = $interpolate(element.text(), true);
+        if (!interpolateTextFn) {
+          attr.$set('value', element.text());
+        }
+      }
+
+      return function(scope, element, attr) {
+        // This is an optimization over using ^^ since we don't want to have to search
+        // all the way to the root of the DOM for every single option element
+        var selectCtrlName = '$selectController',
+            parent = element.parent(),
+            selectCtrl = parent.data(selectCtrlName) ||
+              parent.parent().data(selectCtrlName); // in case we are in optgroup
+
+        if (selectCtrl) {
+          selectCtrl.registerOption(scope, element, attr, interpolateValueFn, interpolateTextFn);
+        }
+      };
+    }
+  };
+}];
+
+/**
+ * @ngdoc directive
+ * @name ngRequired
+ * @restrict A
+ *
+ * @description
+ *
+ * ngRequired adds the required {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
+ * It is most often used for {@link input `input`} and {@link select `select`} controls, but can also be
+ * applied to custom controls.
+ *
+ * The directive sets the `required` attribute on the element if the Angular expression inside
+ * `ngRequired` evaluates to true. A special directive for setting `required` is necessary because we
+ * cannot use interpolation inside `required`. See the {@link guide/interpolation interpolation guide}
+ * for more info.
+ *
+ * The validator will set the `required` error key to true if the `required` attribute is set and
+ * calling {@link ngModel.NgModelController#$isEmpty `NgModelController.$isEmpty`} with the
+ * {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`} returns `true`. For example, the
+ * `$isEmpty()` implementation for `input[text]` checks the length of the `$viewValue`. When developing
+ * custom controls, `$isEmpty()` can be overwritten to account for a $viewValue that is not string-based.
+ *
+ * @example
+ * <example name="ngRequiredDirective" module="ngRequiredExample">
+ *   <file name="index.html">
+ *     <script>
+ *       angular.module('ngRequiredExample', [])
+ *         .controller('ExampleController', ['$scope', function($scope) {
+ *           $scope.required = true;
+ *         }]);
+ *     </script>
+ *     <div ng-controller="ExampleController">
+ *       <form name="form">
+ *         <label for="required">Toggle required: </label>
+ *         <input type="checkbox" ng-model="required" id="required" />
+ *         <br>
+ *         <label for="input">This input must be filled if `required` is true: </label>
+ *         <input type="text" ng-model="model" id="input" name="input" ng-required="required" /><br>
+ *         <hr>
+ *         required error set? = <code>{{form.input.$error.required}}</code><br>
+ *         model = <code>{{model}}</code>
+ *       </form>
+ *     </div>
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+       var required = element(by.binding('form.input.$error.required'));
+       var model = element(by.binding('model'));
+       var input = element(by.id('input'));
+
+       it('should set the required error', function() {
+         expect(required.getText()).toContain('true');
+
+         input.sendKeys('123');
+         expect(required.getText()).not.toContain('true');
+         expect(model.getText()).toContain('123');
+       });
+ *   </file>
+ * </example>
+ */
+var requiredDirective = function() {
+  return {
+    restrict: 'A',
+    require: '?ngModel',
+    link: function(scope, elm, attr, ctrl) {
+      if (!ctrl) return;
+      attr.required = true; // force truthy in case we are on non input element
+
+      ctrl.$validators.required = function(modelValue, viewValue) {
+        return !attr.required || !ctrl.$isEmpty(viewValue);
+      };
+
+      attr.$observe('required', function() {
+        ctrl.$validate();
+      });
+    }
+  };
+};
+
+/**
+ * @ngdoc directive
+ * @name ngPattern
+ *
+ * @description
+ *
+ * ngPattern adds the pattern {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
+ * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
+ *
+ * The validator sets the `pattern` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
+ * does not match a RegExp which is obtained by evaluating the Angular expression given in the
+ * `ngPattern` attribute value:
+ * * If the expression evaluates to a RegExp object, then this is used directly.
+ * * If the expression evaluates to a string, then it will be converted to a RegExp after wrapping it
+ * in `^` and `$` characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
+ *
+ * <div class="alert alert-info">
+ * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
+ * start at the index of the last search's match, thus not taking the whole input value into
+ * account.
+ * </div>
+ *
+ * <div class="alert alert-info">
+ * **Note:** This directive is also added when the plain `pattern` attribute is used, with two
+ * differences:
+ * <ol>
+ *   <li>
+ *     `ngPattern` does not set the `pattern` attribute and therefore HTML5 constraint validation is
+ *     not available.
+ *   </li>
+ *   <li>
+ *     The `ngPattern` attribute must be an expression, while the `pattern` value must be
+ *     interpolated.
+ *   </li>
+ * </ol>
+ * </div>
+ *
+ * @example
+ * <example name="ngPatternDirective" module="ngPatternExample">
+ *   <file name="index.html">
+ *     <script>
+ *       angular.module('ngPatternExample', [])
+ *         .controller('ExampleController', ['$scope', function($scope) {
+ *           $scope.regex = '\\d+';
+ *         }]);
+ *     </script>
+ *     <div ng-controller="ExampleController">
+ *       <form name="form">
+ *         <label for="regex">Set a pattern (regex string): </label>
+ *         <input type="text" ng-model="regex" id="regex" />
+ *         <br>
+ *         <label for="input">This input is restricted by the current pattern: </label>
+ *         <input type="text" ng-model="model" id="input" name="input" ng-pattern="regex" /><br>
+ *         <hr>
+ *         input valid? = <code>{{form.input.$valid}}</code><br>
+ *         model = <code>{{model}}</code>
+ *       </form>
+ *     </div>
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+       var model = element(by.binding('model'));
+       var input = element(by.id('input'));
+
+       it('should validate the input with the default pattern', function() {
+         input.sendKeys('aaa');
+         expect(model.getText()).not.toContain('aaa');
+
+         input.clear().then(function() {
+           input.sendKeys('123');
+           expect(model.getText()).toContain('123');
+         });
+       });
+ *   </file>
+ * </example>
+ */
+var patternDirective = function() {
+  return {
+    restrict: 'A',
+    require: '?ngModel',
+    link: function(scope, elm, attr, ctrl) {
+      if (!ctrl) return;
+
+      var regexp, patternExp = attr.ngPattern || attr.pattern;
+      attr.$observe('pattern', function(regex) {
+        if (isString(regex) && regex.length > 0) {
+          regex = new RegExp('^' + regex + '$');
+        }
+
+        if (regex && !regex.test) {
+          throw minErr('ngPattern')('noregexp',
+            'Expected {0} to be a RegExp but was {1}. Element: {2}', patternExp,
+            regex, startingTag(elm));
+        }
+
+        regexp = regex || undefined;
+        ctrl.$validate();
+      });
+
+      ctrl.$validators.pattern = function(modelValue, viewValue) {
+        // HTML5 pattern constraint validates the input value, so we validate the viewValue
+        return ctrl.$isEmpty(viewValue) || isUndefined(regexp) || regexp.test(viewValue);
+      };
+    }
+  };
+};
+
+/**
+ * @ngdoc directive
+ * @name ngMaxlength
+ *
+ * @description
+ *
+ * ngMaxlength adds the maxlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
+ * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
+ *
+ * The validator sets the `maxlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
+ * is longer than the integer obtained by evaluating the Angular expression given in the
+ * `ngMaxlength` attribute value.
+ *
+ * <div class="alert alert-info">
+ * **Note:** This directive is also added when the plain `maxlength` attribute is used, with two
+ * differences:
+ * <ol>
+ *   <li>
+ *     `ngMaxlength` does not set the `maxlength` attribute and therefore HTML5 constraint
+ *     validation is not available.
+ *   </li>
+ *   <li>
+ *     The `ngMaxlength` attribute must be an expression, while the `maxlength` value must be
+ *     interpolated.
+ *   </li>
+ * </ol>
+ * </div>
+ *
+ * @example
+ * <example name="ngMaxlengthDirective" module="ngMaxlengthExample">
+ *   <file name="index.html">
+ *     <script>
+ *       angular.module('ngMaxlengthExample', [])
+ *         .controller('ExampleController', ['$scope', function($scope) {
+ *           $scope.maxlength = 5;
+ *         }]);
+ *     </script>
+ *     <div ng-controller="ExampleController">
+ *       <form name="form">
+ *         <label for="maxlength">Set a maxlength: </label>
+ *         <input type="number" ng-model="maxlength" id="maxlength" />
+ *         <br>
+ *         <label for="input">This input is restricted by the current maxlength: </label>
+ *         <input type="text" ng-model="model" id="input" name="input" ng-maxlength="maxlength" /><br>
+ *         <hr>
+ *         input valid? = <code>{{form.input.$valid}}</code><br>
+ *         model = <code>{{model}}</code>
+ *       </form>
+ *     </div>
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+       var model = element(by.binding('model'));
+       var input = element(by.id('input'));
+
+       it('should validate the input with the default maxlength', function() {
+         input.sendKeys('abcdef');
+         expect(model.getText()).not.toContain('abcdef');
+
+         input.clear().then(function() {
+           input.sendKeys('abcde');
+           expect(model.getText()).toContain('abcde');
+         });
+       });
+ *   </file>
+ * </example>
+ */
+var maxlengthDirective = function() {
+  return {
+    restrict: 'A',
+    require: '?ngModel',
+    link: function(scope, elm, attr, ctrl) {
+      if (!ctrl) return;
+
+      var maxlength = -1;
+      attr.$observe('maxlength', function(value) {
+        var intVal = toInt(value);
+        maxlength = isNumberNaN(intVal) ? -1 : intVal;
+        ctrl.$validate();
+      });
+      ctrl.$validators.maxlength = function(modelValue, viewValue) {
+        return (maxlength < 0) || ctrl.$isEmpty(viewValue) || (viewValue.length <= maxlength);
+      };
+    }
+  };
+};
+
+/**
+ * @ngdoc directive
+ * @name ngMinlength
+ *
+ * @description
+ *
+ * ngMinlength adds the minlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
+ * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
+ *
+ * The validator sets the `minlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
+ * is shorter than the integer obtained by evaluating the Angular expression given in the
+ * `ngMinlength` attribute value.
+ *
+ * <div class="alert alert-info">
+ * **Note:** This directive is also added when the plain `minlength` attribute is used, with two
+ * differences:
+ * <ol>
+ *   <li>
+ *     `ngMinlength` does not set the `minlength` attribute and therefore HTML5 constraint
+ *     validation is not available.
+ *   </li>
+ *   <li>
+ *     The `ngMinlength` value must be an expression, while the `minlength` value must be
+ *     interpolated.
+ *   </li>
+ * </ol>
+ * </div>
+ *
+ * @example
+ * <example name="ngMinlengthDirective" module="ngMinlengthExample">
+ *   <file name="index.html">
+ *     <script>
+ *       angular.module('ngMinlengthExample', [])
+ *         .controller('ExampleController', ['$scope', function($scope) {
+ *           $scope.minlength = 3;
+ *         }]);
+ *     </script>
+ *     <div ng-controller="ExampleController">
+ *       <form name="form">
+ *         <label for="minlength">Set a minlength: </label>
+ *         <input type="number" ng-model="minlength" id="minlength" />
+ *         <br>
+ *         <label for="input">This input is restricted by the current minlength: </label>
+ *         <input type="text" ng-model="model" id="input" name="input" ng-minlength="minlength" /><br>
+ *         <hr>
+ *         input valid? = <code>{{form.input.$valid}}</code><br>
+ *         model = <code>{{model}}</code>
+ *       </form>
+ *     </div>
+ *   </file>
+ *   <file name="protractor.js" type="protractor">
+       var model = element(by.binding('model'));
+       var input = element(by.id('input'));
+
+       it('should validate the input with the default minlength', function() {
+         input.sendKeys('ab');
+         expect(model.getText()).not.toContain('ab');
+
+         input.sendKeys('abc');
+         expect(model.getText()).toContain('abc');
+       });
+ *   </file>
+ * </example>
+ */
+var minlengthDirective = function() {
+  return {
+    restrict: 'A',
+    require: '?ngModel',
+    link: function(scope, elm, attr, ctrl) {
+      if (!ctrl) return;
+
+      var minlength = 0;
+      attr.$observe('minlength', function(value) {
+        minlength = toInt(value) || 0;
+        ctrl.$validate();
+      });
+      ctrl.$validators.minlength = function(modelValue, viewValue) {
+        return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;
+      };
+    }
+  };
+};
+
+if (window.angular.bootstrap) {
+  // AngularJS is already loaded, so we can return here...
+  if (window.console) {
+    console.log('WARNING: Tried to load angular more than once.');
+  }
+  return;
+}
+
+// try to bind to jquery now so that one can write jqLite(fn)
+// but we will rebind on bootstrap again.
+bindJQuery();
+
+publishExternalAPI(angular);
+
+angular.module("ngLocale", [], ["$provide", function($provide) {
+var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
+function getDecimals(n) {
+  n = n + '';
+  var i = n.indexOf('.');
+  return (i == -1) ? 0 : n.length - i - 1;
+}
+
+function getVF(n, opt_precision) {
+  var v = opt_precision;
+
+  if (undefined === v) {
+    v = Math.min(getDecimals(n), 3);
+  }
+
+  var base = Math.pow(10, v);
+  var f = ((n * base) | 0) % base;
+  return {v: v, f: f};
+}
+
+$provide.value("$locale", {
+  "DATETIME_FORMATS": {
+    "AMPMS": [
+      "AM",
+      "PM"
+    ],
+    "DAY": [
+      "Sunday",
+      "Monday",
+      "Tuesday",
+      "Wednesday",
+      "Thursday",
+      "Friday",
+      "Saturday"
+    ],
+    "ERANAMES": [
+      "Before Christ",
+      "Anno Domini"
+    ],
+    "ERAS": [
+      "BC",
+      "AD"
+    ],
+    "FIRSTDAYOFWEEK": 6,
+    "MONTH": [
+      "January",
+      "February",
+      "March",
+      "April",
+      "May",
+      "June",
+      "July",
+      "August",
+      "September",
+      "October",
+      "November",
+      "December"
+    ],
+    "SHORTDAY": [
+      "Sun",
+      "Mon",
+      "Tue",
+      "Wed",
+      "Thu",
+      "Fri",
+      "Sat"
+    ],
+    "SHORTMONTH": [
+      "Jan",
+      "Feb",
+      "Mar",
+      "Apr",
+      "May",
+      "Jun",
+      "Jul",
+      "Aug",
+      "Sep",
+      "Oct",
+      "Nov",
+      "Dec"
+    ],
+    "STANDALONEMONTH": [
+      "January",
+      "February",
+      "March",
+      "April",
+      "May",
+      "June",
+      "July",
+      "August",
+      "September",
+      "October",
+      "November",
+      "December"
+    ],
+    "WEEKENDRANGE": [
+      5,
+      6
+    ],
+    "fullDate": "EEEE, MMMM d, y",
+    "longDate": "MMMM d, y",
+    "medium": "MMM d, y h:mm:ss a",
+    "mediumDate": "MMM d, y",
+    "mediumTime": "h:mm:ss a",
+    "short": "M/d/yy h:mm a",
+    "shortDate": "M/d/yy",
+    "shortTime": "h:mm a"
+  },
+  "NUMBER_FORMATS": {
+    "CURRENCY_SYM": "$",
+    "DECIMAL_SEP": ".",
+    "GROUP_SEP": ",",
+    "PATTERNS": [
+      {
+        "gSize": 3,
+        "lgSize": 3,
+        "maxFrac": 3,
+        "minFrac": 0,
+        "minInt": 1,
+        "negPre": "-",
+        "negSuf": "",
+        "posPre": "",
+        "posSuf": ""
+      },
+      {
+        "gSize": 3,
+        "lgSize": 3,
+        "maxFrac": 2,
+        "minFrac": 2,
+        "minInt": 1,
+        "negPre": "-\u00a4",
+        "negSuf": "",
+        "posPre": "\u00a4",
+        "posSuf": ""
+      }
+    ]
+  },
+  "id": "en-us",
+  "localeID": "en_US",
+  "pluralCat": function(n, opt_precision) {  var i = n | 0;  var vf = getVF(n, opt_precision);  if (i == 1 && vf.v == 0) {    return PLURAL_CATEGORY.ONE;  }  return PLURAL_CATEGORY.OTHER;}
+});
+}]);
+
+  jqLite(function() {
+    angularInit(window.document, bootstrap);
+  });
+
+})(window);
+
+!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>');
+
+/***/ },
+/* 11 */
+/***/ function(module, exports) {
+
+module.exports = "\n<!--\nCopyright 2017-present Open Networking Foundation\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n<div class = \"elinepanel\">\n  <h1>ELine Overview</h1>\n  <form ng-submit=\"vm.saveEline(vm.eng.eline)\">\n    <div class=\"form-group\" ng-hide=\"vm.eng.createMode\">\n      <label>ID</label><br/>\n      <p>{{vm.eng.eline.id}}</p>\n    </div>\n    <div class=\"form-group\">\n      <label for=\"name\">Name</label>\n      <input required class=\"form-control\" id=\"name\" type=\"text\" ng-value=\"vm.eng.eline.name\" ng-model=\"vm.eng.eline.name\">\n    </div>\n    <div class=\"form-group\" ng-hide=\"vm.eng.createMode\">\n      <label>Backend Status</label><br/>\n      <p>{{vm.eng.eline.backend_status}}</p>\n    </div>\n    <div class=\"form-group\">\n      <label for=\"cpi1\">Connect point 1 ID</label>\n      <input required class=\"form-control\" id=\"cpi1\" type=\"text\" ng-value=\"vm.eng.eline.connect_point_1_id\" ng-model=\"vm.eng.eline.connect_point_1_id\">\n    </div>\n    <div class=\"form-group\">\n      <label for=\"cpi2\">Connect point 2 ID</label>\n      <input required class=\"form-control\" id=\"cpi2\" type=\"text\" ng-value=\"vm.eng.eline.connect_point_2_id\" ng-model=\"vm.eng.eline.connect_point_2_id\">\n    </div>\n    <div class=\"form-group\">\n      <label for=\"bwps\">Bandwidth Profile</label>\n      <select required class=\"form-control\"\n              id=\"bwps\"\n              ng-model=\"vm.eng.eline.bwp\"\n              ng-options=\"bwp.name as bwp.name for bwp in vm.eng.bwps | orderBy:'name'\"\n      >\n      </select>\n    </div>\n    <div class=\"form-group\">\n      <label for=\"sitename\">CORD Site Name</label>\n      <input required class=\"form-control\" id=\"sitename\" type=\"text\" ng-value=\"vm.eng.eline.cord_site_name\" ng-model=\"vm.eng.eline.cord_site_name\">\n    </div>\n    <div class=\"form-group\">\n      <label for=\"vlanids\">Vlan IDs</label>\n      <input required class=\"form-control\" id=\"vlanids\" type=\"text\" ng-value=\"vm.eng.eline.vlanids\" ng-model=\"vm.eng.eline.vlanids\">\n    </div>\n    <div class=\"form-group\" style=\"text-align: center\">\n      <button type=\"submit\" class=\"btn btn-success btn-block\">Save Changes</button>\n    </div>\n  </form>\n  <button type=\"button\" class=\"btn btn-danger btn-block\" ng-click=\"vm.eng.elinePanel({}, vm.eng.eline, false)\">Close</button>\n  <button type=\"button\" class=\"btn btn-danger delete-eline\" ng-click=\"vm.deleteEline(vm.eng.eline)\">Delete Eline</button>\n</div>";
+
+/***/ },
+/* 12 */
+/***/ function(module, exports) {
+
+module.exports = "\n<!--\nCopyright 2017-present Open Networking Foundation\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n\n\n<div class = \"row\">\n  <div class = \"col-xs-12\">\n    <h1>Enterprise Network Map</h1>\n    <div map-lazy-load=\"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4\">\n      <ng-map\n        default-style=\"false\"\n        id=\"foobar\"\n        center=\"0,0\"\n        disable-default-u-i=\"true\"\n        map-type-id=\"ROADMAP\"\n        zoom-control=\"true\"\n        min-zoom=\"2\"\n        styles=\"{{vm.mapStyles}}\"\n      >\n        <!--Markers-->\n        <marker\n          ng-repeat=\"uni in vm.unis\"\n          id=\"marker-{{uni.id}}\"\n          position=\"{{uni.latlng.toString()}}\"\n          icon=\"{{vm.MapConfig.marker}}\"\n          on-click=\"vm.showUni(uni)\"\n        >\n        </marker>\n\n        <!--Marker Info Window-->\n\n        <info-window id = \"uni-info\">\n          <div class = \"marker-info\">\n            <h4>{{vm.current_uni.name}}</h4>\n            <p>\n              <b>LatLng: </b>{{vm.current_uni.latlng.toString()}}<br/>\n              <b>Cpe id: </b>{{vm.current_uni.cpe_id}}<br/>\n              <b>Tenant: </b>{{vm.current_uni.tenant}}<br/>\n            </p>\n            <button ng-show=\"vm.canCreateEline\" ng-click=\"vm.createConnection(vm.current_uni)()\">Create connection</button>\n            <button ng-show=\"!vm.canCreateEline && !uni.eline_start\" ng-click=\"vm.finishConnection(vm.current_uni)\">Finish connection</button>\n          </div>\n        </info-window>\n\n        <!--Connections-->\n\n        <shape\n          ng-repeat=\"eline in vm.elines\"\n          name=\"polyline\"\n          id=\"eline-{{eline.id}}\"\n          path=\"{{eline.path}}\"\n          stroke-color=\"{{vm.colorLine(eline.backend_status)}}\"\n          stroke-opacity=\"1.0\"\n          stroke-weight=\"5\"\n          on-click=\"vm.elinePanel({{eline}}, true)\"\n        >\n        </shape>\n\n      </ng-map>\n\n    </div>\n    Changes may not display until page refresh.\n  </div>\n</div>\n<!--\"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4\"-->";
+
+/***/ },
+/* 13 */
+/***/ function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(global, module) {var __WEBPACK_AMD_DEFINE_RESULT__;/**
+ * @license
+ * Lodash <https://lodash.com/>
+ * Copyright JS Foundation and other contributors <https://js.foundation/>
+ * Released under MIT license <https://lodash.com/license>
+ * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
+ * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ */
+;(function() {
+
+  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+  var undefined;
+
+  /** Used as the semantic version number. */
+  var VERSION = '4.17.4';
+
+  /** Used as the size to enable large array optimizations. */
+  var LARGE_ARRAY_SIZE = 200;
+
+  /** Error message constants. */
+  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
+      FUNC_ERROR_TEXT = 'Expected a function';
+
+  /** Used to stand-in for `undefined` hash values. */
+  var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+  /** Used as the maximum memoize cache size. */
+  var MAX_MEMOIZE_SIZE = 500;
+
+  /** Used as the internal argument placeholder. */
+  var PLACEHOLDER = '__lodash_placeholder__';
+
+  /** Used to compose bitmasks for cloning. */
+  var CLONE_DEEP_FLAG = 1,
+      CLONE_FLAT_FLAG = 2,
+      CLONE_SYMBOLS_FLAG = 4;
+
+  /** Used to compose bitmasks for value comparisons. */
+  var COMPARE_PARTIAL_FLAG = 1,
+      COMPARE_UNORDERED_FLAG = 2;
+
+  /** Used to compose bitmasks for function metadata. */
+  var WRAP_BIND_FLAG = 1,
+      WRAP_BIND_KEY_FLAG = 2,
+      WRAP_CURRY_BOUND_FLAG = 4,
+      WRAP_CURRY_FLAG = 8,
+      WRAP_CURRY_RIGHT_FLAG = 16,
+      WRAP_PARTIAL_FLAG = 32,
+      WRAP_PARTIAL_RIGHT_FLAG = 64,
+      WRAP_ARY_FLAG = 128,
+      WRAP_REARG_FLAG = 256,
+      WRAP_FLIP_FLAG = 512;
+
+  /** Used as default options for `_.truncate`. */
+  var DEFAULT_TRUNC_LENGTH = 30,
+      DEFAULT_TRUNC_OMISSION = '...';
+
+  /** Used to detect hot functions by number of calls within a span of milliseconds. */
+  var HOT_COUNT = 800,
+      HOT_SPAN = 16;
+
+  /** Used to indicate the type of lazy iteratees. */
+  var LAZY_FILTER_FLAG = 1,
+      LAZY_MAP_FLAG = 2,
+      LAZY_WHILE_FLAG = 3;
+
+  /** Used as references for various `Number` constants. */
+  var INFINITY = 1 / 0,
+      MAX_SAFE_INTEGER = 9007199254740991,
+      MAX_INTEGER = 1.7976931348623157e+308,
+      NAN = 0 / 0;
+
+  /** Used as references for the maximum length and index of an array. */
+  var MAX_ARRAY_LENGTH = 4294967295,
+      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
+      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
+
+  /** Used to associate wrap methods with their bit flags. */
+  var wrapFlags = [
+    ['ary', WRAP_ARY_FLAG],
+    ['bind', WRAP_BIND_FLAG],
+    ['bindKey', WRAP_BIND_KEY_FLAG],
+    ['curry', WRAP_CURRY_FLAG],
+    ['curryRight', WRAP_CURRY_RIGHT_FLAG],
+    ['flip', WRAP_FLIP_FLAG],
+    ['partial', WRAP_PARTIAL_FLAG],
+    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
+    ['rearg', WRAP_REARG_FLAG]
+  ];
+
+  /** `Object#toString` result references. */
+  var argsTag = '[object Arguments]',
+      arrayTag = '[object Array]',
+      asyncTag = '[object AsyncFunction]',
+      boolTag = '[object Boolean]',
+      dateTag = '[object Date]',
+      domExcTag = '[object DOMException]',
+      errorTag = '[object Error]',
+      funcTag = '[object Function]',
+      genTag = '[object GeneratorFunction]',
+      mapTag = '[object Map]',
+      numberTag = '[object Number]',
+      nullTag = '[object Null]',
+      objectTag = '[object Object]',
+      promiseTag = '[object Promise]',
+      proxyTag = '[object Proxy]',
+      regexpTag = '[object RegExp]',
+      setTag = '[object Set]',
+      stringTag = '[object String]',
+      symbolTag = '[object Symbol]',
+      undefinedTag = '[object Undefined]',
+      weakMapTag = '[object WeakMap]',
+      weakSetTag = '[object WeakSet]';
+
+  var arrayBufferTag = '[object ArrayBuffer]',
+      dataViewTag = '[object DataView]',
+      float32Tag = '[object Float32Array]',
+      float64Tag = '[object Float64Array]',
+      int8Tag = '[object Int8Array]',
+      int16Tag = '[object Int16Array]',
+      int32Tag = '[object Int32Array]',
+      uint8Tag = '[object Uint8Array]',
+      uint8ClampedTag = '[object Uint8ClampedArray]',
+      uint16Tag = '[object Uint16Array]',
+      uint32Tag = '[object Uint32Array]';
+
+  /** Used to match empty string literals in compiled template source. */
+  var reEmptyStringLeading = /\b__p \+= '';/g,
+      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
+      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
+
+  /** Used to match HTML entities and HTML characters. */
+  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
+      reUnescapedHtml = /[&<>"']/g,
+      reHasEscapedHtml = RegExp(reEscapedHtml.source),
+      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
+
+  /** Used to match template delimiters. */
+  var reEscape = /<%-([\s\S]+?)%>/g,
+      reEvaluate = /<%([\s\S]+?)%>/g,
+      reInterpolate = /<%=([\s\S]+?)%>/g;
+
+  /** Used to match property names within property paths. */
+  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
+      reIsPlainProp = /^\w*$/,
+      reLeadingDot = /^\./,
+      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
+
+  /**
+   * Used to match `RegExp`
+   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
+   */
+  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
+      reHasRegExpChar = RegExp(reRegExpChar.source);
+
+  /** Used to match leading and trailing whitespace. */
+  var reTrim = /^\s+|\s+$/g,
+      reTrimStart = /^\s+/,
+      reTrimEnd = /\s+$/;
+
+  /** Used to match wrap detail comments. */
+  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
+      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
+      reSplitDetails = /,? & /;
+
+  /** Used to match words composed of alphanumeric characters. */
+  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
+
+  /** Used to match backslashes in property paths. */
+  var reEscapeChar = /\\(\\)?/g;
+
+  /**
+   * Used to match
+   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
+   */
+  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
+
+  /** Used to match `RegExp` flags from their coerced string values. */
+  var reFlags = /\w*$/;
+
+  /** Used to detect bad signed hexadecimal string values. */
+  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
+
+  /** Used to detect binary string values. */
+  var reIsBinary = /^0b[01]+$/i;
+
+  /** Used to detect host constructors (Safari). */
+  var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+  /** Used to detect octal string values. */
+  var reIsOctal = /^0o[0-7]+$/i;
+
+  /** Used to detect unsigned integer values. */
+  var reIsUint = /^(?:0|[1-9]\d*)$/;
+
+  /** Used to match Latin Unicode letters (excluding mathematical operators). */
+  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
+
+  /** Used to ensure capturing order of template delimiters. */
+  var reNoMatch = /($^)/;
+
+  /** Used to match unescaped characters in compiled string literals. */
+  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
+
+  /** Used to compose unicode character classes. */
+  var rsAstralRange = '\\ud800-\\udfff',
+      rsComboMarksRange = '\\u0300-\\u036f',
+      reComboHalfMarksRange = '\\ufe20-\\ufe2f',
+      rsComboSymbolsRange = '\\u20d0-\\u20ff',
+      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
+      rsDingbatRange = '\\u2700-\\u27bf',
+      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
+      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
+      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
+      rsPunctuationRange = '\\u2000-\\u206f',
+      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
+      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
+      rsVarRange = '\\ufe0e\\ufe0f',
+      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
+
+  /** Used to compose unicode capture groups. */
+  var rsApos = "['\u2019]",
+      rsAstral = '[' + rsAstralRange + ']',
+      rsBreak = '[' + rsBreakRange + ']',
+      rsCombo = '[' + rsComboRange + ']',
+      rsDigits = '\\d+',
+      rsDingbat = '[' + rsDingbatRange + ']',
+      rsLower = '[' + rsLowerRange + ']',
+      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
+      rsFitz = '\\ud83c[\\udffb-\\udfff]',
+      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
+      rsNonAstral = '[^' + rsAstralRange + ']',
+      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
+      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
+      rsUpper = '[' + rsUpperRange + ']',
+      rsZWJ = '\\u200d';
+
+  /** Used to compose unicode regexes. */
+  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
+      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
+      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
+      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
+      reOptMod = rsModifier + '?',
+      rsOptVar = '[' + rsVarRange + ']?',
+      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+      rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
+      rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
+      rsSeq = rsOptVar + reOptMod + rsOptJoin,
+      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
+      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
+
+  /** Used to match apostrophes. */
+  var reApos = RegExp(rsApos, 'g');
+
+  /**
+   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
+   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
+   */
+  var reComboMark = RegExp(rsCombo, 'g');
+
+  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
+  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
+
+  /** Used to match complex or compound words. */
+  var reUnicodeWord = RegExp([
+    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
+    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
+    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
+    rsUpper + '+' + rsOptContrUpper,
+    rsOrdUpper,
+    rsOrdLower,
+    rsDigits,
+    rsEmoji
+  ].join('|'), 'g');
+
+  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
+  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
+
+  /** Used to detect strings that need a more robust regexp to match words. */
+  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
+
+  /** Used to assign default `context` object properties. */
+  var contextProps = [
+    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
+    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
+    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
+    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
+    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
+  ];
+
+  /** Used to make template sourceURLs easier to identify. */
+  var templateCounter = -1;
+
+  /** Used to identify `toStringTag` values of typed arrays. */
+  var typedArrayTags = {};
+  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
+  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
+  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
+  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
+  typedArrayTags[uint32Tag] = true;
+  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
+  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
+  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
+  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
+  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
+  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
+  typedArrayTags[setTag] = typedArrayTags[stringTag] =
+  typedArrayTags[weakMapTag] = false;
+
+  /** Used to identify `toStringTag` values supported by `_.clone`. */
+  var cloneableTags = {};
+  cloneableTags[argsTag] = cloneableTags[arrayTag] =
+  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
+  cloneableTags[boolTag] = cloneableTags[dateTag] =
+  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
+  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
+  cloneableTags[int32Tag] = cloneableTags[mapTag] =
+  cloneableTags[numberTag] = cloneableTags[objectTag] =
+  cloneableTags[regexpTag] = cloneableTags[setTag] =
+  cloneableTags[stringTag] = cloneableTags[symbolTag] =
+  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
+  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+  cloneableTags[errorTag] = cloneableTags[funcTag] =
+  cloneableTags[weakMapTag] = false;
+
+  /** Used to map Latin Unicode letters to basic Latin letters. */
+  var deburredLetters = {
+    // Latin-1 Supplement block.
+    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
+    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
+    '\xc7': 'C',  '\xe7': 'c',
+    '\xd0': 'D',  '\xf0': 'd',
+    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
+    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
+    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
+    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
+    '\xd1': 'N',  '\xf1': 'n',
+    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
+    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
+    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
+    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
+    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
+    '\xc6': 'Ae', '\xe6': 'ae',
+    '\xde': 'Th', '\xfe': 'th',
+    '\xdf': 'ss',
+    // Latin Extended-A block.
+    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
+    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
+    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
+    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
+    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
+    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
+    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
+    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
+    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
+    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
+    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
+    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
+    '\u0134': 'J',  '\u0135': 'j',
+    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
+    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
+    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
+    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
+    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
+    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
+    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
+    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
+    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
+    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
+    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
+    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
+    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
+    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
+    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
+    '\u0174': 'W',  '\u0175': 'w',
+    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
+    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
+    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
+    '\u0132': 'IJ', '\u0133': 'ij',
+    '\u0152': 'Oe', '\u0153': 'oe',
+    '\u0149': "'n", '\u017f': 's'
+  };
+
+  /** Used to map characters to HTML entities. */
+  var htmlEscapes = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#39;'
+  };
+
+  /** Used to map HTML entities to characters. */
+  var htmlUnescapes = {
+    '&amp;': '&',
+    '&lt;': '<',
+    '&gt;': '>',
+    '&quot;': '"',
+    '&#39;': "'"
+  };
+
+  /** Used to escape characters for inclusion in compiled string literals. */
+  var stringEscapes = {
+    '\\': '\\',
+    "'": "'",
+    '\n': 'n',
+    '\r': 'r',
+    '\u2028': 'u2028',
+    '\u2029': 'u2029'
+  };
+
+  /** Built-in method references without a dependency on `root`. */
+  var freeParseFloat = parseFloat,
+      freeParseInt = parseInt;
+
+  /** Detect free variable `global` from Node.js. */
+  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
+
+  /** Detect free variable `self`. */
+  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
+
+  /** Used as a reference to the global object. */
+  var root = freeGlobal || freeSelf || Function('return this')();
+
+  /** Detect free variable `exports`. */
+  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
+
+  /** Detect free variable `module`. */
+  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
+
+  /** Detect the popular CommonJS extension `module.exports`. */
+  var moduleExports = freeModule && freeModule.exports === freeExports;
+
+  /** Detect free variable `process` from Node.js. */
+  var freeProcess = moduleExports && freeGlobal.process;
+
+  /** Used to access faster Node.js helpers. */
+  var nodeUtil = (function() {
+    try {
+      return freeProcess && freeProcess.binding && freeProcess.binding('util');
+    } catch (e) {}
+  }());
+
+  /* Node.js helper references. */
+  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
+      nodeIsDate = nodeUtil && nodeUtil.isDate,
+      nodeIsMap = nodeUtil && nodeUtil.isMap,
+      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
+      nodeIsSet = nodeUtil && nodeUtil.isSet,
+      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Adds the key-value `pair` to `map`.
+   *
+   * @private
+   * @param {Object} map The map to modify.
+   * @param {Array} pair The key-value pair to add.
+   * @returns {Object} Returns `map`.
+   */
+  function addMapEntry(map, pair) {
+    // Don't return `map.set` because it's not chainable in IE 11.
+    map.set(pair[0], pair[1]);
+    return map;
+  }
+
+  /**
+   * Adds `value` to `set`.
+   *
+   * @private
+   * @param {Object} set The set to modify.
+   * @param {*} value The value to add.
+   * @returns {Object} Returns `set`.
+   */
+  function addSetEntry(set, value) {
+    // Don't return `set.add` because it's not chainable in IE 11.
+    set.add(value);
+    return set;
+  }
+
+  /**
+   * A faster alternative to `Function#apply`, this function invokes `func`
+   * with the `this` binding of `thisArg` and the arguments of `args`.
+   *
+   * @private
+   * @param {Function} func The function to invoke.
+   * @param {*} thisArg The `this` binding of `func`.
+   * @param {Array} args The arguments to invoke `func` with.
+   * @returns {*} Returns the result of `func`.
+   */
+  function apply(func, thisArg, args) {
+    switch (args.length) {
+      case 0: return func.call(thisArg);
+      case 1: return func.call(thisArg, args[0]);
+      case 2: return func.call(thisArg, args[0], args[1]);
+      case 3: return func.call(thisArg, args[0], args[1], args[2]);
+    }
+    return func.apply(thisArg, args);
+  }
+
+  /**
+   * A specialized version of `baseAggregator` for arrays.
+   *
+   * @private
+   * @param {Array} [array] The array to iterate over.
+   * @param {Function} setter The function to set `accumulator` values.
+   * @param {Function} iteratee The iteratee to transform keys.
+   * @param {Object} accumulator The initial aggregated object.
+   * @returns {Function} Returns `accumulator`.
+   */
+  function arrayAggregator(array, setter, iteratee, accumulator) {
+    var index = -1,
+        length = array == null ? 0 : array.length;
+
+    while (++index < length) {
+      var value = array[index];
+      setter(accumulator, value, iteratee(value), array);
+    }
+    return accumulator;
+  }
+
+  /**
+   * A specialized version of `_.forEach` for arrays without support for
+   * iteratee shorthands.
+   *
+   * @private
+   * @param {Array} [array] The array to iterate over.
+   * @param {Function} iteratee The function invoked per iteration.
+   * @returns {Array} Returns `array`.
+   */
+  function arrayEach(array, iteratee) {
+    var index = -1,
+        length = array == null ? 0 : array.length;
+
+    while (++index < length) {
+      if (iteratee(array[index], index, array) === false) {
+        break;
+      }
+    }
+    return array;
+  }
+
+  /**
+   * A specialized version of `_.forEachRight` for arrays without support for
+   * iteratee shorthands.
+   *
+   * @private
+   * @param {Array} [array] The array to iterate over.
+   * @param {Function} iteratee The function invoked per iteration.
+   * @returns {Array} Returns `array`.
+   */
+  function arrayEachRight(array, iteratee) {
+    var length = array == null ? 0 : array.length;
+
+    while (length--) {
+      if (iteratee(array[length], length, array) === false) {
+        break;
+      }
+    }
+    return array;
+  }
+
+  /**
+   * A specialized version of `_.every` for arrays without support for
+   * iteratee shorthands.
+   *
+   * @private
+   * @param {Array} [array] The array to iterate over.
+   * @param {Function} predicate The function invoked per iteration.
+   * @returns {boolean} Returns `true` if all elements pass the predicate check,
+   *  else `false`.
+   */
+  function arrayEvery(array, predicate) {
+    var index = -1,
+        length = array == null ? 0 : array.length;
+
+    while (++index < length) {
+      if (!predicate(array[index], index, array)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * A specialized version of `_.filter` for arrays without support for
+   * iteratee shorthands.
+   *
+   * @private
+   * @param {Array} [array] The array to iterate over.
+   * @param {Function} predicate The function invoked per iteration.
+   * @returns {Array} Returns the new filtered array.
+   */
+  function arrayFilter(array, predicate) {
+    var index = -1,
+        length = array == null ? 0 : array.length,
+        resIndex = 0,
+        result = [];
+
+    while (++index < length) {
+      var value = array[index];
+      if (predicate(value, index, array)) {
+        result[resIndex++] = value;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * A specialized version of `_.includes` for arrays without support for
+   * specifying an index to search from.
+   *
+   * @private
+   * @param {Array} [array] The array to inspect.
+   * @param {*} target The value to search for.
+   * @returns {boolean} Returns `true` if `target` is found, else `false`.
+   */
+  function arrayIncludes(array, value) {
+    var length = array == null ? 0 : array.length;
+    return !!length && baseIndexOf(array, value, 0) > -1;
+  }
+
+  /**
+   * This function is like `arrayIncludes` except that it accepts a comparator.
+   *
+   * @private
+   * @param {Array} [array] The array to inspect.
+   * @param {*} target The value to search for.
+   * @param {Function} comparator The comparator invoked per element.
+   * @returns {boolean} Returns `true` if `target` is found, else `false`.
+   */
+  function arrayIncludesWith(array, value, comparator) {
+    var index = -1,
+        length = array == null ? 0 : array.length;
+
+    while (++index < length) {
+      if (comparator(value, array[index])) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * A specialized version of `_.map` for arrays without support for iteratee
+   * shorthands.
+   *
+   * @private
+   * @param {Array} [array] The array to iterate over.
+   * @param {Function} iteratee The function invoked per iteration.
+   * @returns {Array} Returns the new mapped array.
+   */
+  function arrayMap(array, iteratee) {
+    var index = -1,
+        length = array == null ? 0 : array.length,
+        result = Array(length);
+
+    while (++index < length) {
+      result[index] = iteratee(array[index], index, array);
+    }
+    return result;
+  }
+
+  /**
+   * Appends the elements of `values` to `array`.
+   *
+   * @private
+   * @param {Array} array The array to modify.
+   * @param {Array} values The values to append.
+   * @returns {Array} Returns `array`.
+   */
+  function arrayPush(array, values) {
+    var index = -1,
+        length = values.length,
+        offset = array.length;
+
+    while (++index < length) {
+      array[offset + index] = values[index];
+    }
+    return array;
+  }
+
+  /**
+   * A specialized version of `_.reduce` for arrays without support for
+   * iteratee shorthands.
+   *
+   * @private
+   * @param {Array} [array] The array to iterate over.
+   * @param {Function} iteratee The function invoked per iteration.
+   * @param {*} [accumulator] The initial value.
+   * @param {boolean} [initAccum] Specify using the first element of `array` as
+   *  the initial value.
+   * @returns {*} Returns the accumulated value.
+   */
+  function arrayReduce(array, iteratee, accumulator, initAccum) {
+    var index = -1,
+        length = array == null ? 0 : array.length;
+
+    if (initAccum && length) {
+      accumulator = array[++index];
+    }
+    while (++index < length) {
+      accumulator = iteratee(accumulator, array[index], index, array);
+    }
+    return accumulator;
+  }
+
+  /**
+   * A specialized version of `_.reduceRight` for arrays without support for
+   * iteratee shorthands.
+   *
+   * @private
+   * @param {Array} [array] The array to iterate over.
+   * @param {Function} iteratee The function invoked per iteration.
+   * @param {*} [accumulator] The initial value.
+   * @param {boolean} [initAccum] Specify using the last element of `array` as
+   *  the initial value.
+   * @returns {*} Returns the accumulated value.
+   */
+  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
+    var length = array == null ? 0 : array.length;
+    if (initAccum && length) {
+      accumulator = array[--length];
+    }
+    while (length--) {
+      accumulator = iteratee(accumulator, array[length], length, array);
+    }
+    return accumulator;
+  }
+
+  /**
+   * A specialized version of `_.some` for arrays without support for iteratee
+   * shorthands.
+   *
+   * @private
+   * @param {Array} [array] The array to iterate over.
+   * @param {Function} predicate The function invoked per iteration.
+   * @returns {boolean} Returns `true` if any element passes the predicate check,
+   *  else `false`.
+   */
+  function arraySome(array, predicate) {
+    var index = -1,
+        length = array == null ? 0 : array.length;
+
+    while (++index < length) {
+      if (predicate(array[index], index, array)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Gets the size of an ASCII `string`.
+   *
+   * @private
+   * @param {string} string The string inspect.
+   * @returns {number} Returns the string size.
+   */
+  var asciiSize = baseProperty('length');
+
+  /**
+   * Converts an ASCII `string` to an array.
+   *
+   * @private
+   * @param {string} string The string to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function asciiToArray(string) {
+    return string.split('');
+  }
+
+  /**
+   * Splits an ASCII `string` into an array of its words.
+   *
+   * @private
+   * @param {string} The string to inspect.
+   * @returns {Array} Returns the words of `string`.
+   */
+  function asciiWords(string) {
+    return string.match(reAsciiWord) || [];
+  }
+
+  /**
+   * The base implementation of methods like `_.findKey` and `_.findLastKey`,
+   * without support for iteratee shorthands, which iterates over `collection`
+   * using `eachFunc`.
+   *
+   * @private
+   * @param {Array|Object} collection The collection to inspect.
+   * @param {Function} predicate The function invoked per iteration.
+   * @param {Function} eachFunc The function to iterate over `collection`.
+   * @returns {*} Returns the found element or its key, else `undefined`.
+   */
+  function baseFindKey(collection, predicate, eachFunc) {
+    var result;
+    eachFunc(collection, function(value, key, collection) {
+      if (predicate(value, key, collection)) {
+        result = key;
+        return false;
+      }
+    });
+    return result;
+  }
+
+  /**
+   * The base implementation of `_.findIndex` and `_.findLastIndex` without
+   * support for iteratee shorthands.
+   *
+   * @private
+   * @param {Array} array The array to inspect.
+   * @param {Function} predicate The function invoked per iteration.
+   * @param {number} fromIndex The index to search from.
+   * @param {boolean} [fromRight] Specify iterating from right to left.
+   * @returns {number} Returns the index of the matched value, else `-1`.
+   */
+  function baseFindIndex(array, predicate, fromIndex, fromRight) {
+    var length = array.length,
+        index = fromIndex + (fromRight ? 1 : -1);
+
+    while ((fromRight ? index-- : ++index < length)) {
+      if (predicate(array[index], index, array)) {
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
+   *
+   * @private
+   * @param {Array} array The array to inspect.
+   * @param {*} value The value to search for.
+   * @param {number} fromIndex The index to search from.
+   * @returns {number} Returns the index of the matched value, else `-1`.
+   */
+  function baseIndexOf(array, value, fromIndex) {
+    return value === value
+      ? strictIndexOf(array, value, fromIndex)
+      : baseFindIndex(array, baseIsNaN, fromIndex);
+  }
+
+  /**
+   * This function is like `baseIndexOf` except that it accepts a comparator.
+   *
+   * @private
+   * @param {Array} array The array to inspect.
+   * @param {*} value The value to search for.
+   * @param {number} fromIndex The index to search from.
+   * @param {Function} comparator The comparator invoked per element.
+   * @returns {number} Returns the index of the matched value, else `-1`.
+   */
+  function baseIndexOfWith(array, value, fromIndex, comparator) {
+    var index = fromIndex - 1,
+        length = array.length;
+
+    while (++index < length) {
+      if (comparator(array[index], value)) {
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * The base implementation of `_.isNaN` without support for number objects.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
+   */
+  function baseIsNaN(value) {
+    return value !== value;
+  }
+
+  /**
+   * The base implementation of `_.mean` and `_.meanBy` without support for
+   * iteratee shorthands.
+   *
+   * @private
+   * @param {Array} array The array to iterate over.
+   * @param {Function} iteratee The function invoked per iteration.
+   * @returns {number} Returns the mean.
+   */
+  function baseMean(array, iteratee) {
+    var length = array == null ? 0 : array.length;
+    return length ? (baseSum(array, iteratee) / length) : NAN;
+  }
+
+  /**
+   * The base implementation of `_.property` without support for deep paths.
+   *
+   * @private
+   * @param {string} key The key of the property to get.
+   * @returns {Function} Returns the new accessor function.
+   */
+  function baseProperty(key) {
+    return function(object) {
+      return object == null ? undefined : object[key];
+    };
+  }
+
+  /**
+   * The base implementation of `_.propertyOf` without support for deep paths.
+   *
+   * @private
+   * @param {Object} object The object to query.
+   * @returns {Function} Returns the new accessor function.
+   */
+  function basePropertyOf(object) {
+    return function(key) {
+      return object == null ? undefined : object[key];
+    };
+  }
+
+  /**
+   * The base implementation of `_.reduce` and `_.reduceRight`, without support
+   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
+   *
+   * @private
+   * @param {Array|Object} collection The collection to iterate over.
+   * @param {Function} iteratee The function invoked per iteration.
+   * @param {*} accumulator The initial value.
+   * @param {boolean} initAccum Specify using the first or last element of
+   *  `collection` as the initial value.
+   * @param {Function} eachFunc The function to iterate over `collection`.
+   * @returns {*} Returns the accumulated value.
+   */
+  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
+    eachFunc(collection, function(value, index, collection) {
+      accumulator = initAccum
+        ? (initAccum = false, value)
+        : iteratee(accumulator, value, index, collection);
+    });
+    return accumulator;
+  }
+
+  /**
+   * The base implementation of `_.sortBy` which uses `comparer` to define the
+   * sort order of `array` and replaces criteria objects with their corresponding
+   * values.
+   *
+   * @private
+   * @param {Array} array The array to sort.
+   * @param {Function} comparer The function to define sort order.
+   * @returns {Array} Returns `array`.
+   */
+  function baseSortBy(array, comparer) {
+    var length = array.length;
+
+    array.sort(comparer);
+    while (length--) {
+      array[length] = array[length].value;
+    }
+    return array;
+  }
+
+  /**
+   * The base implementation of `_.sum` and `_.sumBy` without support for
+   * iteratee shorthands.
+   *
+   * @private
+   * @param {Array} array The array to iterate over.
+   * @param {Function} iteratee The function invoked per iteration.
+   * @returns {number} Returns the sum.
+   */
+  function baseSum(array, iteratee) {
+    var result,
+        index = -1,
+        length = array.length;
+
+    while (++index < length) {
+      var current = iteratee(array[index]);
+      if (current !== undefined) {
+        result = result === undefined ? current : (result + current);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * The base implementation of `_.times` without support for iteratee shorthands
+   * or max array length checks.
+   *
+   * @private
+   * @param {number} n The number of times to invoke `iteratee`.
+   * @param {Function} iteratee The function invoked per iteration.
+   * @returns {Array} Returns the array of results.
+   */
+  function baseTimes(n, iteratee) {
+    var index = -1,
+        result = Array(n);
+
+    while (++index < n) {
+      result[index] = iteratee(index);
+    }
+    return result;
+  }
+
+  /**
+   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
+   * of key-value pairs for `object` corresponding to the property names of `props`.
+   *
+   * @private
+   * @param {Object} object The object to query.
+   * @param {Array} props The property names to get values for.
+   * @returns {Object} Returns the key-value pairs.
+   */
+  function baseToPairs(object, props) {
+    return arrayMap(props, function(key) {
+      return [key, object[key]];
+    });
+  }
+
+  /**
+   * The base implementation of `_.unary` without support for storing metadata.
+   *
+   * @private
+   * @param {Function} func The function to cap arguments for.
+   * @returns {Function} Returns the new capped function.
+   */
+  function baseUnary(func) {
+    return function(value) {
+      return func(value);
+    };
+  }
+
+  /**
+   * The base implementation of `_.values` and `_.valuesIn` which creates an
+   * array of `object` property values corresponding to the property names
+   * of `props`.
+   *
+   * @private
+   * @param {Object} object The object to query.
+   * @param {Array} props The property names to get values for.
+   * @returns {Object} Returns the array of property values.
+   */
+  function baseValues(object, props) {
+    return arrayMap(props, function(key) {
+      return object[key];
+    });
+  }
+
+  /**
+   * Checks if a `cache` value for `key` exists.
+   *
+   * @private
+   * @param {Object} cache The cache to query.
+   * @param {string} key The key of the entry to check.
+   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+   */
+  function cacheHas(cache, key) {
+    return cache.has(key);
+  }
+
+  /**
+   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
+   * that is not found in the character symbols.
+   *
+   * @private
+   * @param {Array} strSymbols The string symbols to inspect.
+   * @param {Array} chrSymbols The character symbols to find.
+   * @returns {number} Returns the index of the first unmatched string symbol.
+   */
+  function charsStartIndex(strSymbols, chrSymbols) {
+    var index = -1,
+        length = strSymbols.length;
+
+    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
+    return index;
+  }
+
+  /**
+   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
+   * that is not found in the character symbols.
+   *
+   * @private
+   * @param {Array} strSymbols The string symbols to inspect.
+   * @param {Array} chrSymbols The character symbols to find.
+   * @returns {number} Returns the index of the last unmatched string symbol.
+   */
+  function charsEndIndex(strSymbols, chrSymbols) {
+    var index = strSymbols.length;
+
+    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
+    return index;
+  }
+
+  /**
+   * Gets the number of `placeholder` occurrences in `array`.
+   *
+   * @private
+   * @param {Array} array The array to inspect.
+   * @param {*} placeholder The placeholder to search for.
+   * @returns {number} Returns the placeholder count.
+   */
+  function countHolders(array, placeholder) {
+    var length = array.length,
+        result = 0;
+
+    while (length--) {
+      if (array[length] === placeholder) {
+        ++result;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
+   * letters to basic Latin letters.
+   *
+   * @private
+   * @param {string} letter The matched letter to deburr.
+   * @returns {string} Returns the deburred letter.
+   */
+  var deburrLetter = basePropertyOf(deburredLetters);
+
+  /**
+   * Used by `_.escape` to convert characters to HTML entities.
+   *
+   * @private
+   * @param {string} chr The matched character to escape.
+   * @returns {string} Returns the escaped character.
+   */
+  var escapeHtmlChar = basePropertyOf(htmlEscapes);
+
+  /**
+   * Used by `_.template` to escape characters for inclusion in compiled string literals.
+   *
+   * @private
+   * @param {string} chr The matched character to escape.
+   * @returns {string} Returns the escaped character.
+   */
+  function escapeStringChar(chr) {
+    return '\\' + stringEscapes[chr];
+  }
+
+  /**
+   * Gets the value at `key` of `object`.
+   *
+   * @private
+   * @param {Object} [object] The object to query.
+   * @param {string} key The key of the property to get.
+   * @returns {*} Returns the property value.
+   */
+  function getValue(object, key) {
+    return object == null ? undefined : object[key];
+  }
+
+  /**
+   * Checks if `string` contains Unicode symbols.
+   *
+   * @private
+   * @param {string} string The string to inspect.
+   * @returns {boolean} Returns `true` if a symbol is found, else `false`.
+   */
+  function hasUnicode(string) {
+    return reHasUnicode.test(string);
+  }
+
+  /**
+   * Checks if `string` contains a word composed of Unicode symbols.
+   *
+   * @private
+   * @param {string} string The string to inspect.
+   * @returns {boolean} Returns `true` if a word is found, else `false`.
+   */
+  function hasUnicodeWord(string) {
+    return reHasUnicodeWord.test(string);
+  }
+
+  /**
+   * Converts `iterator` to an array.
+   *
+   * @private
+   * @param {Object} iterator The iterator to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function iteratorToArray(iterator) {
+    var data,
+        result = [];
+
+    while (!(data = iterator.next()).done) {
+      result.push(data.value);
+    }
+    return result;
+  }
+
+  /**
+   * Converts `map` to its key-value pairs.
+   *
+   * @private
+   * @param {Object} map The map to convert.
+   * @returns {Array} Returns the key-value pairs.
+   */
+  function mapToArray(map) {
+    var index = -1,
+        result = Array(map.size);
+
+    map.forEach(function(value, key) {
+      result[++index] = [key, value];
+    });
+    return result;
+  }
+
+  /**
+   * Creates a unary function that invokes `func` with its argument transformed.
+   *
+   * @private
+   * @param {Function} func The function to wrap.
+   * @param {Function} transform The argument transform.
+   * @returns {Function} Returns the new function.
+   */
+  function overArg(func, transform) {
+    return function(arg) {
+      return func(transform(arg));
+    };
+  }
+
+  /**
+   * Replaces all `placeholder` elements in `array` with an internal placeholder
+   * and returns an array of their indexes.
+   *
+   * @private
+   * @param {Array} array The array to modify.
+   * @param {*} placeholder The placeholder to replace.
+   * @returns {Array} Returns the new array of placeholder indexes.
+   */
+  function replaceHolders(array, placeholder) {
+    var index = -1,
+        length = array.length,
+        resIndex = 0,
+        result = [];
+
+    while (++index < length) {
+      var value = array[index];
+      if (value === placeholder || value === PLACEHOLDER) {
+        array[index] = PLACEHOLDER;
+        result[resIndex++] = index;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Converts `set` to an array of its values.
+   *
+   * @private
+   * @param {Object} set The set to convert.
+   * @returns {Array} Returns the values.
+   */
+  function setToArray(set) {
+    var index = -1,
+        result = Array(set.size);
+
+    set.forEach(function(value) {
+      result[++index] = value;
+    });
+    return result;
+  }
+
+  /**
+   * Converts `set` to its value-value pairs.
+   *
+   * @private
+   * @param {Object} set The set to convert.
+   * @returns {Array} Returns the value-value pairs.
+   */
+  function setToPairs(set) {
+    var index = -1,
+        result = Array(set.size);
+
+    set.forEach(function(value) {
+      result[++index] = [value, value];
+    });
+    return result;
+  }
+
+  /**
+   * A specialized version of `_.indexOf` which performs strict equality
+   * comparisons of values, i.e. `===`.
+   *
+   * @private
+   * @param {Array} array The array to inspect.
+   * @param {*} value The value to search for.
+   * @param {number} fromIndex The index to search from.
+   * @returns {number} Returns the index of the matched value, else `-1`.
+   */
+  function strictIndexOf(array, value, fromIndex) {
+    var index = fromIndex - 1,
+        length = array.length;
+
+    while (++index < length) {
+      if (array[index] === value) {
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * A specialized version of `_.lastIndexOf` which performs strict equality
+   * comparisons of values, i.e. `===`.
+   *
+   * @private
+   * @param {Array} array The array to inspect.
+   * @param {*} value The value to search for.
+   * @param {number} fromIndex The index to search from.
+   * @returns {number} Returns the index of the matched value, else `-1`.
+   */
+  function strictLastIndexOf(array, value, fromIndex) {
+    var index = fromIndex + 1;
+    while (index--) {
+      if (array[index] === value) {
+        return index;
+      }
+    }
+    return index;
+  }
+
+  /**
+   * Gets the number of symbols in `string`.
+   *
+   * @private
+   * @param {string} string The string to inspect.
+   * @returns {number} Returns the string size.
+   */
+  function stringSize(string) {
+    return hasUnicode(string)
+      ? unicodeSize(string)
+      : asciiSize(string);
+  }
+
+  /**
+   * Converts `string` to an array.
+   *
+   * @private
+   * @param {string} string The string to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function stringToArray(string) {
+    return hasUnicode(string)
+      ? unicodeToArray(string)
+      : asciiToArray(string);
+  }
+
+  /**
+   * Used by `_.unescape` to convert HTML entities to characters.
+   *
+   * @private
+   * @param {string} chr The matched character to unescape.
+   * @returns {string} Returns the unescaped character.
+   */
+  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
+
+  /**
+   * Gets the size of a Unicode `string`.
+   *
+   * @private
+   * @param {string} string The string inspect.
+   * @returns {number} Returns the string size.
+   */
+  function unicodeSize(string) {
+    var result = reUnicode.lastIndex = 0;
+    while (reUnicode.test(string)) {
+      ++result;
+    }
+    return result;
+  }
+
+  /**
+   * Converts a Unicode `string` to an array.
+   *
+   * @private
+   * @param {string} string The string to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function unicodeToArray(string) {
+    return string.match(reUnicode) || [];
+  }
+
+  /**
+   * Splits a Unicode `string` into an array of its words.
+   *
+   * @private
+   * @param {string} The string to inspect.
+   * @returns {Array} Returns the words of `string`.
+   */
+  function unicodeWords(string) {
+    return string.match(reUnicodeWord) || [];
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Create a new pristine `lodash` function using the `context` object.
+   *
+   * @static
+   * @memberOf _
+   * @since 1.1.0
+   * @category Util
+   * @param {Object} [context=root] The context object.
+   * @returns {Function} Returns a new `lodash` function.
+   * @example
+   *
+   * _.mixin({ 'foo': _.constant('foo') });
+   *
+   * var lodash = _.runInContext();
+   * lodash.mixin({ 'bar': lodash.constant('bar') });
+   *
+   * _.isFunction(_.foo);
+   * // => true
+   * _.isFunction(_.bar);
+   * // => false
+   *
+   * lodash.isFunction(lodash.foo);
+   * // => false
+   * lodash.isFunction(lodash.bar);
+   * // => true
+   *
+   * // Create a suped-up `defer` in Node.js.
+   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
+   */
+  var runInContext = (function runInContext(context) {
+    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
+
+    /** Built-in constructor references. */
+    var Array = context.Array,
+        Date = context.Date,
+        Error = context.Error,
+        Function = context.Function,
+        Math = context.Math,
+        Object = context.Object,
+        RegExp = context.RegExp,
+        String = context.String,
+        TypeError = context.TypeError;
+
+    /** Used for built-in method references. */
+    var arrayProto = Array.prototype,
+        funcProto = Function.prototype,
+        objectProto = Object.prototype;
+
+    /** Used to detect overreaching core-js shims. */
+    var coreJsData = context['__core-js_shared__'];
+
+    /** Used to resolve the decompiled source of functions. */
+    var funcToString = funcProto.toString;
+
+    /** Used to check objects for own properties. */
+    var hasOwnProperty = objectProto.hasOwnProperty;
+
+    /** Used to generate unique IDs. */
+    var idCounter = 0;
+
+    /** Used to detect methods masquerading as native. */
+    var maskSrcKey = (function() {
+      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
+      return uid ? ('Symbol(src)_1.' + uid) : '';
+    }());
+
+    /**
+     * Used to resolve the
+     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
+     * of values.
+     */
+    var nativeObjectToString = objectProto.toString;
+
+    /** Used to infer the `Object` constructor. */
+    var objectCtorString = funcToString.call(Object);
+
+    /** Used to restore the original `_` reference in `_.noConflict`. */
+    var oldDash = root._;
+
+    /** Used to detect if a method is native. */
+    var reIsNative = RegExp('^' +
+      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
+      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+    );
+
+    /** Built-in value references. */
+    var Buffer = moduleExports ? context.Buffer : undefined,
+        Symbol = context.Symbol,
+        Uint8Array = context.Uint8Array,
+        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
+        getPrototype = overArg(Object.getPrototypeOf, Object),
+        objectCreate = Object.create,
+        propertyIsEnumerable = objectProto.propertyIsEnumerable,
+        splice = arrayProto.splice,
+        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
+        symIterator = Symbol ? Symbol.iterator : undefined,
+        symToStringTag = Symbol ? Symbol.toStringTag : undefined;
+
+    var defineProperty = (function() {
+      try {
+        var func = getNative(Object, 'defineProperty');
+        func({}, '', {});
+        return func;
+      } catch (e) {}
+    }());
+
+    /** Mocked built-ins. */
+    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
+        ctxNow = Date && Date.now !== root.Date.now && Date.now,
+        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
+
+    /* Built-in method references for those with the same name as other `lodash` methods. */
+    var nativeCeil = Math.ceil,
+        nativeFloor = Math.floor,
+        nativeGetSymbols = Object.getOwnPropertySymbols,
+        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
+        nativeIsFinite = context.isFinite,
+        nativeJoin = arrayProto.join,
+        nativeKeys = overArg(Object.keys, Object),
+        nativeMax = Math.max,
+        nativeMin = Math.min,
+        nativeNow = Date.now,
+        nativeParseInt = context.parseInt,
+        nativeRandom = Math.random,
+        nativeReverse = arrayProto.reverse;
+
+    /* Built-in method references that are verified to be native. */
+    var DataView = getNative(context, 'DataView'),
+        Map = getNative(context, 'Map'),
+        Promise = getNative(context, 'Promise'),
+        Set = getNative(context, 'Set'),
+        WeakMap = getNative(context, 'WeakMap'),
+        nativeCreate = getNative(Object, 'create');
+
+    /** Used to store function metadata. */
+    var metaMap = WeakMap && new WeakMap;
+
+    /** Used to lookup unminified function names. */
+    var realNames = {};
+
+    /** Used to detect maps, sets, and weakmaps. */
+    var dataViewCtorString = toSource(DataView),
+        mapCtorString = toSource(Map),
+        promiseCtorString = toSource(Promise),
+        setCtorString = toSource(Set),
+        weakMapCtorString = toSource(WeakMap);
+
+    /** Used to convert symbols to primitives and strings. */
+    var symbolProto = Symbol ? Symbol.prototype : undefined,
+        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
+        symbolToString = symbolProto ? symbolProto.toString : undefined;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a `lodash` object which wraps `value` to enable implicit method
+     * chain sequences. Methods that operate on and return arrays, collections,
+     * and functions can be chained together. Methods that retrieve a single value
+     * or may return a primitive value will automatically end the chain sequence
+     * and return the unwrapped value. Otherwise, the value must be unwrapped
+     * with `_#value`.
+     *
+     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
+     * enabled using `_.chain`.
+     *
+     * The execution of chained methods is lazy, that is, it's deferred until
+     * `_#value` is implicitly or explicitly called.
+     *
+     * Lazy evaluation allows several methods to support shortcut fusion.
+     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
+     * the creation of intermediate arrays and can greatly reduce the number of
+     * iteratee executions. Sections of a chain sequence qualify for shortcut
+     * fusion if the section is applied to an array and iteratees accept only
+     * one argument. The heuristic for whether a section qualifies for shortcut
+     * fusion is subject to change.
+     *
+     * Chaining is supported in custom builds as long as the `_#value` method is
+     * directly or indirectly included in the build.
+     *
+     * In addition to lodash methods, wrappers have `Array` and `String` methods.
+     *
+     * The wrapper `Array` methods are:
+     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
+     *
+     * The wrapper `String` methods are:
+     * `replace` and `split`
+     *
+     * The wrapper methods that support shortcut fusion are:
+     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
+     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
+     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
+     *
+     * The chainable wrapper methods are:
+     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
+     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
+     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
+     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
+     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
+     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
+     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
+     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
+     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
+     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
+     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
+     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
+     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
+     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
+     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
+     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
+     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
+     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
+     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
+     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
+     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
+     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
+     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
+     * `zipObject`, `zipObjectDeep`, and `zipWith`
+     *
+     * The wrapper methods that are **not** chainable by default are:
+     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
+     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
+     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
+     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
+     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
+     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
+     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
+     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
+     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
+     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
+     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
+     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
+     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
+     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
+     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
+     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
+     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
+     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
+     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
+     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
+     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
+     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
+     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
+     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
+     * `upperFirst`, `value`, and `words`
+     *
+     * @name _
+     * @constructor
+     * @category Seq
+     * @param {*} value The value to wrap in a `lodash` instance.
+     * @returns {Object} Returns the new `lodash` wrapper instance.
+     * @example
+     *
+     * function square(n) {
+     *   return n * n;
+     * }
+     *
+     * var wrapped = _([1, 2, 3]);
+     *
+     * // Returns an unwrapped value.
+     * wrapped.reduce(_.add);
+     * // => 6
+     *
+     * // Returns a wrapped value.
+     * var squares = wrapped.map(square);
+     *
+     * _.isArray(squares);
+     * // => false
+     *
+     * _.isArray(squares.value());
+     * // => true
+     */
+    function lodash(value) {
+      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
+        if (value instanceof LodashWrapper) {
+          return value;
+        }
+        if (hasOwnProperty.call(value, '__wrapped__')) {
+          return wrapperClone(value);
+        }
+      }
+      return new LodashWrapper(value);
+    }
+
+    /**
+     * The base implementation of `_.create` without support for assigning
+     * properties to the created object.
+     *
+     * @private
+     * @param {Object} proto The object to inherit from.
+     * @returns {Object} Returns the new object.
+     */
+    var baseCreate = (function() {
+      function object() {}
+      return function(proto) {
+        if (!isObject(proto)) {
+          return {};
+        }
+        if (objectCreate) {
+          return objectCreate(proto);
+        }
+        object.prototype = proto;
+        var result = new object;
+        object.prototype = undefined;
+        return result;
+      };
+    }());
+
+    /**
+     * The function whose prototype chain sequence wrappers inherit from.
+     *
+     * @private
+     */
+    function baseLodash() {
+      // No operation performed.
+    }
+
+    /**
+     * The base constructor for creating `lodash` wrapper objects.
+     *
+     * @private
+     * @param {*} value The value to wrap.
+     * @param {boolean} [chainAll] Enable explicit method chain sequences.
+     */
+    function LodashWrapper(value, chainAll) {
+      this.__wrapped__ = value;
+      this.__actions__ = [];
+      this.__chain__ = !!chainAll;
+      this.__index__ = 0;
+      this.__values__ = undefined;
+    }
+
+    /**
+     * By default, the template delimiters used by lodash are like those in
+     * embedded Ruby (ERB) as well as ES2015 template strings. Change the
+     * following template settings to use alternative delimiters.
+     *
+     * @static
+     * @memberOf _
+     * @type {Object}
+     */
+    lodash.templateSettings = {
+
+      /**
+       * Used to detect `data` property values to be HTML-escaped.
+       *
+       * @memberOf _.templateSettings
+       * @type {RegExp}
+       */
+      'escape': reEscape,
+
+      /**
+       * Used to detect code to be evaluated.
+       *
+       * @memberOf _.templateSettings
+       * @type {RegExp}
+       */
+      'evaluate': reEvaluate,
+
+      /**
+       * Used to detect `data` property values to inject.
+       *
+       * @memberOf _.templateSettings
+       * @type {RegExp}
+       */
+      'interpolate': reInterpolate,
+
+      /**
+       * Used to reference the data object in the template text.
+       *
+       * @memberOf _.templateSettings
+       * @type {string}
+       */
+      'variable': '',
+
+      /**
+       * Used to import variables into the compiled template.
+       *
+       * @memberOf _.templateSettings
+       * @type {Object}
+       */
+      'imports': {
+
+        /**
+         * A reference to the `lodash` function.
+         *
+         * @memberOf _.templateSettings.imports
+         * @type {Function}
+         */
+        '_': lodash
+      }
+    };
+
+    // Ensure wrappers are instances of `baseLodash`.
+    lodash.prototype = baseLodash.prototype;
+    lodash.prototype.constructor = lodash;
+
+    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
+    LodashWrapper.prototype.constructor = LodashWrapper;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
+     *
+     * @private
+     * @constructor
+     * @param {*} value The value to wrap.
+     */
+    function LazyWrapper(value) {
+      this.__wrapped__ = value;
+      this.__actions__ = [];
+      this.__dir__ = 1;
+      this.__filtered__ = false;
+      this.__iteratees__ = [];
+      this.__takeCount__ = MAX_ARRAY_LENGTH;
+      this.__views__ = [];
+    }
+
+    /**
+     * Creates a clone of the lazy wrapper object.
+     *
+     * @private
+     * @name clone
+     * @memberOf LazyWrapper
+     * @returns {Object} Returns the cloned `LazyWrapper` object.
+     */
+    function lazyClone() {
+      var result = new LazyWrapper(this.__wrapped__);
+      result.__actions__ = copyArray(this.__actions__);
+      result.__dir__ = this.__dir__;
+      result.__filtered__ = this.__filtered__;
+      result.__iteratees__ = copyArray(this.__iteratees__);
+      result.__takeCount__ = this.__takeCount__;
+      result.__views__ = copyArray(this.__views__);
+      return result;
+    }
+
+    /**
+     * Reverses the direction of lazy iteration.
+     *
+     * @private
+     * @name reverse
+     * @memberOf LazyWrapper
+     * @returns {Object} Returns the new reversed `LazyWrapper` object.
+     */
+    function lazyReverse() {
+      if (this.__filtered__) {
+        var result = new LazyWrapper(this);
+        result.__dir__ = -1;
+        result.__filtered__ = true;
+      } else {
+        result = this.clone();
+        result.__dir__ *= -1;
+      }
+      return result;
+    }
+
+    /**
+     * Extracts the unwrapped value from its lazy wrapper.
+     *
+     * @private
+     * @name value
+     * @memberOf LazyWrapper
+     * @returns {*} Returns the unwrapped value.
+     */
+    function lazyValue() {
+      var array = this.__wrapped__.value(),
+          dir = this.__dir__,
+          isArr = isArray(array),
+          isRight = dir < 0,
+          arrLength = isArr ? array.length : 0,
+          view = getView(0, arrLength, this.__views__),
+          start = view.start,
+          end = view.end,
+          length = end - start,
+          index = isRight ? end : (start - 1),
+          iteratees = this.__iteratees__,
+          iterLength = iteratees.length,
+          resIndex = 0,
+          takeCount = nativeMin(length, this.__takeCount__);
+
+      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
+        return baseWrapperValue(array, this.__actions__);
+      }
+      var result = [];
+
+      outer:
+      while (length-- && resIndex < takeCount) {
+        index += dir;
+
+        var iterIndex = -1,
+            value = array[index];
+
+        while (++iterIndex < iterLength) {
+          var data = iteratees[iterIndex],
+              iteratee = data.iteratee,
+              type = data.type,
+              computed = iteratee(value);
+
+          if (type == LAZY_MAP_FLAG) {
+            value = computed;
+          } else if (!computed) {
+            if (type == LAZY_FILTER_FLAG) {
+              continue outer;
+            } else {
+              break outer;
+            }
+          }
+        }
+        result[resIndex++] = value;
+      }
+      return result;
+    }
+
+    // Ensure `LazyWrapper` is an instance of `baseLodash`.
+    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
+    LazyWrapper.prototype.constructor = LazyWrapper;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a hash object.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [entries] The key-value pairs to cache.
+     */
+    function Hash(entries) {
+      var index = -1,
+          length = entries == null ? 0 : entries.length;
+
+      this.clear();
+      while (++index < length) {
+        var entry = entries[index];
+        this.set(entry[0], entry[1]);
+      }
+    }
+
+    /**
+     * Removes all key-value entries from the hash.
+     *
+     * @private
+     * @name clear
+     * @memberOf Hash
+     */
+    function hashClear() {
+      this.__data__ = nativeCreate ? nativeCreate(null) : {};
+      this.size = 0;
+    }
+
+    /**
+     * Removes `key` and its value from the hash.
+     *
+     * @private
+     * @name delete
+     * @memberOf Hash
+     * @param {Object} hash The hash to modify.
+     * @param {string} key The key of the value to remove.
+     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+     */
+    function hashDelete(key) {
+      var result = this.has(key) && delete this.__data__[key];
+      this.size -= result ? 1 : 0;
+      return result;
+    }
+
+    /**
+     * Gets the hash value for `key`.
+     *
+     * @private
+     * @name get
+     * @memberOf Hash
+     * @param {string} key The key of the value to get.
+     * @returns {*} Returns the entry value.
+     */
+    function hashGet(key) {
+      var data = this.__data__;
+      if (nativeCreate) {
+        var result = data[key];
+        return result === HASH_UNDEFINED ? undefined : result;
+      }
+      return hasOwnProperty.call(data, key) ? data[key] : undefined;
+    }
+
+    /**
+     * Checks if a hash value for `key` exists.
+     *
+     * @private
+     * @name has
+     * @memberOf Hash
+     * @param {string} key The key of the entry to check.
+     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+     */
+    function hashHas(key) {
+      var data = this.__data__;
+      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
+    }
+
+    /**
+     * Sets the hash `key` to `value`.
+     *
+     * @private
+     * @name set
+     * @memberOf Hash
+     * @param {string} key The key of the value to set.
+     * @param {*} value The value to set.
+     * @returns {Object} Returns the hash instance.
+     */
+    function hashSet(key, value) {
+      var data = this.__data__;
+      this.size += this.has(key) ? 0 : 1;
+      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
+      return this;
+    }
+
+    // Add methods to `Hash`.
+    Hash.prototype.clear = hashClear;
+    Hash.prototype['delete'] = hashDelete;
+    Hash.prototype.get = hashGet;
+    Hash.prototype.has = hashHas;
+    Hash.prototype.set = hashSet;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates an list cache object.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [entries] The key-value pairs to cache.
+     */
+    function ListCache(entries) {
+      var index = -1,
+          length = entries == null ? 0 : entries.length;
+
+      this.clear();
+      while (++index < length) {
+        var entry = entries[index];
+        this.set(entry[0], entry[1]);
+      }
+    }
+
+    /**
+     * Removes all key-value entries from the list cache.
+     *
+     * @private
+     * @name clear
+     * @memberOf ListCache
+     */
+    function listCacheClear() {
+      this.__data__ = [];
+      this.size = 0;
+    }
+
+    /**
+     * Removes `key` and its value from the list cache.
+     *
+     * @private
+     * @name delete
+     * @memberOf ListCache
+     * @param {string} key The key of the value to remove.
+     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+     */
+    function listCacheDelete(key) {
+      var data = this.__data__,
+          index = assocIndexOf(data, key);
+
+      if (index < 0) {
+        return false;
+      }
+      var lastIndex = data.length - 1;
+      if (index == lastIndex) {
+        data.pop();
+      } else {
+        splice.call(data, index, 1);
+      }
+      --this.size;
+      return true;
+    }
+
+    /**
+     * Gets the list cache value for `key`.
+     *
+     * @private
+     * @name get
+     * @memberOf ListCache
+     * @param {string} key The key of the value to get.
+     * @returns {*} Returns the entry value.
+     */
+    function listCacheGet(key) {
+      var data = this.__data__,
+          index = assocIndexOf(data, key);
+
+      return index < 0 ? undefined : data[index][1];
+    }
+
+    /**
+     * Checks if a list cache value for `key` exists.
+     *
+     * @private
+     * @name has
+     * @memberOf ListCache
+     * @param {string} key The key of the entry to check.
+     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+     */
+    function listCacheHas(key) {
+      return assocIndexOf(this.__data__, key) > -1;
+    }
+
+    /**
+     * Sets the list cache `key` to `value`.
+     *
+     * @private
+     * @name set
+     * @memberOf ListCache
+     * @param {string} key The key of the value to set.
+     * @param {*} value The value to set.
+     * @returns {Object} Returns the list cache instance.
+     */
+    function listCacheSet(key, value) {
+      var data = this.__data__,
+          index = assocIndexOf(data, key);
+
+      if (index < 0) {
+        ++this.size;
+        data.push([key, value]);
+      } else {
+        data[index][1] = value;
+      }
+      return this;
+    }
+
+    // Add methods to `ListCache`.
+    ListCache.prototype.clear = listCacheClear;
+    ListCache.prototype['delete'] = listCacheDelete;
+    ListCache.prototype.get = listCacheGet;
+    ListCache.prototype.has = listCacheHas;
+    ListCache.prototype.set = listCacheSet;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a map cache object to store key-value pairs.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [entries] The key-value pairs to cache.
+     */
+    function MapCache(entries) {
+      var index = -1,
+          length = entries == null ? 0 : entries.length;
+
+      this.clear();
+      while (++index < length) {
+        var entry = entries[index];
+        this.set(entry[0], entry[1]);
+      }
+    }
+
+    /**
+     * Removes all key-value entries from the map.
+     *
+     * @private
+     * @name clear
+     * @memberOf MapCache
+     */
+    function mapCacheClear() {
+      this.size = 0;
+      this.__data__ = {
+        'hash': new Hash,
+        'map': new (Map || ListCache),
+        'string': new Hash
+      };
+    }
+
+    /**
+     * Removes `key` and its value from the map.
+     *
+     * @private
+     * @name delete
+     * @memberOf MapCache
+     * @param {string} key The key of the value to remove.
+     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+     */
+    function mapCacheDelete(key) {
+      var result = getMapData(this, key)['delete'](key);
+      this.size -= result ? 1 : 0;
+      return result;
+    }
+
+    /**
+     * Gets the map value for `key`.
+     *
+     * @private
+     * @name get
+     * @memberOf MapCache
+     * @param {string} key The key of the value to get.
+     * @returns {*} Returns the entry value.
+     */
+    function mapCacheGet(key) {
+      return getMapData(this, key).get(key);
+    }
+
+    /**
+     * Checks if a map value for `key` exists.
+     *
+     * @private
+     * @name has
+     * @memberOf MapCache
+     * @param {string} key The key of the entry to check.
+     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+     */
+    function mapCacheHas(key) {
+      return getMapData(this, key).has(key);
+    }
+
+    /**
+     * Sets the map `key` to `value`.
+     *
+     * @private
+     * @name set
+     * @memberOf MapCache
+     * @param {string} key The key of the value to set.
+     * @param {*} value The value to set.
+     * @returns {Object} Returns the map cache instance.
+     */
+    function mapCacheSet(key, value) {
+      var data = getMapData(this, key),
+          size = data.size;
+
+      data.set(key, value);
+      this.size += data.size == size ? 0 : 1;
+      return this;
+    }
+
+    // Add methods to `MapCache`.
+    MapCache.prototype.clear = mapCacheClear;
+    MapCache.prototype['delete'] = mapCacheDelete;
+    MapCache.prototype.get = mapCacheGet;
+    MapCache.prototype.has = mapCacheHas;
+    MapCache.prototype.set = mapCacheSet;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     *
+     * Creates an array cache object to store unique values.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [values] The values to cache.
+     */
+    function SetCache(values) {
+      var index = -1,
+          length = values == null ? 0 : values.length;
+
+      this.__data__ = new MapCache;
+      while (++index < length) {
+        this.add(values[index]);
+      }
+    }
+
+    /**
+     * Adds `value` to the array cache.
+     *
+     * @private
+     * @name add
+     * @memberOf SetCache
+     * @alias push
+     * @param {*} value The value to cache.
+     * @returns {Object} Returns the cache instance.
+     */
+    function setCacheAdd(value) {
+      this.__data__.set(value, HASH_UNDEFINED);
+      return this;
+    }
+
+    /**
+     * Checks if `value` is in the array cache.
+     *
+     * @private
+     * @name has
+     * @memberOf SetCache
+     * @param {*} value The value to search for.
+     * @returns {number} Returns `true` if `value` is found, else `false`.
+     */
+    function setCacheHas(value) {
+      return this.__data__.has(value);
+    }
+
+    // Add methods to `SetCache`.
+    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
+    SetCache.prototype.has = setCacheHas;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a stack cache object to store key-value pairs.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [entries] The key-value pairs to cache.
+     */
+    function Stack(entries) {
+      var data = this.__data__ = new ListCache(entries);
+      this.size = data.size;
+    }
+
+    /**
+     * Removes all key-value entries from the stack.
+     *
+     * @private
+     * @name clear
+     * @memberOf Stack
+     */
+    function stackClear() {
+      this.__data__ = new ListCache;
+      this.size = 0;
+    }
+
+    /**
+     * Removes `key` and its value from the stack.
+     *
+     * @private
+     * @name delete
+     * @memberOf Stack
+     * @param {string} key The key of the value to remove.
+     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+     */
+    function stackDelete(key) {
+      var data = this.__data__,
+          result = data['delete'](key);
+
+      this.size = data.size;
+      return result;
+    }
+
+    /**
+     * Gets the stack value for `key`.
+     *
+     * @private
+     * @name get
+     * @memberOf Stack
+     * @param {string} key The key of the value to get.
+     * @returns {*} Returns the entry value.
+     */
+    function stackGet(key) {
+      return this.__data__.get(key);
+    }
+
+    /**
+     * Checks if a stack value for `key` exists.
+     *
+     * @private
+     * @name has
+     * @memberOf Stack
+     * @param {string} key The key of the entry to check.
+     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+     */
+    function stackHas(key) {
+      return this.__data__.has(key);
+    }
+
+    /**
+     * Sets the stack `key` to `value`.
+     *
+     * @private
+     * @name set
+     * @memberOf Stack
+     * @param {string} key The key of the value to set.
+     * @param {*} value The value to set.
+     * @returns {Object} Returns the stack cache instance.
+     */
+    function stackSet(key, value) {
+      var data = this.__data__;
+      if (data instanceof ListCache) {
+        var pairs = data.__data__;
+        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
+          pairs.push([key, value]);
+          this.size = ++data.size;
+          return this;
+        }
+        data = this.__data__ = new MapCache(pairs);
+      }
+      data.set(key, value);
+      this.size = data.size;
+      return this;
+    }
+
+    // Add methods to `Stack`.
+    Stack.prototype.clear = stackClear;
+    Stack.prototype['delete'] = stackDelete;
+    Stack.prototype.get = stackGet;
+    Stack.prototype.has = stackHas;
+    Stack.prototype.set = stackSet;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates an array of the enumerable property names of the array-like `value`.
+     *
+     * @private
+     * @param {*} value The value to query.
+     * @param {boolean} inherited Specify returning inherited property names.
+     * @returns {Array} Returns the array of property names.
+     */
+    function arrayLikeKeys(value, inherited) {
+      var isArr = isArray(value),
+          isArg = !isArr && isArguments(value),
+          isBuff = !isArr && !isArg && isBuffer(value),
+          isType = !isArr && !isArg && !isBuff && isTypedArray(value),
+          skipIndexes = isArr || isArg || isBuff || isType,
+          result = skipIndexes ? baseTimes(value.length, String) : [],
+          length = result.length;
+
+      for (var key in value) {
+        if ((inherited || hasOwnProperty.call(value, key)) &&
+            !(skipIndexes && (
+               // Safari 9 has enumerable `arguments.length` in strict mode.
+               key == 'length' ||
+               // Node.js 0.10 has enumerable non-index properties on buffers.
+               (isBuff && (key == 'offset' || key == 'parent')) ||
+               // PhantomJS 2 has enumerable non-index properties on typed arrays.
+               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
+               // Skip index properties.
+               isIndex(key, length)
+            ))) {
+          result.push(key);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * A specialized version of `_.sample` for arrays.
+     *
+     * @private
+     * @param {Array} array The array to sample.
+     * @returns {*} Returns the random element.
+     */
+    function arraySample(array) {
+      var length = array.length;
+      return length ? array[baseRandom(0, length - 1)] : undefined;
+    }
+
+    /**
+     * A specialized version of `_.sampleSize` for arrays.
+     *
+     * @private
+     * @param {Array} array The array to sample.
+     * @param {number} n The number of elements to sample.
+     * @returns {Array} Returns the random elements.
+     */
+    function arraySampleSize(array, n) {
+      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
+    }
+
+    /**
+     * A specialized version of `_.shuffle` for arrays.
+     *
+     * @private
+     * @param {Array} array The array to shuffle.
+     * @returns {Array} Returns the new shuffled array.
+     */
+    function arrayShuffle(array) {
+      return shuffleSelf(copyArray(array));
+    }
+
+    /**
+     * This function is like `assignValue` except that it doesn't assign
+     * `undefined` values.
+     *
+     * @private
+     * @param {Object} object The object to modify.
+     * @param {string} key The key of the property to assign.
+     * @param {*} value The value to assign.
+     */
+    function assignMergeValue(object, key, value) {
+      if ((value !== undefined && !eq(object[key], value)) ||
+          (value === undefined && !(key in object))) {
+        baseAssignValue(object, key, value);
+      }
+    }
+
+    /**
+     * Assigns `value` to `key` of `object` if the existing value is not equivalent
+     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * for equality comparisons.
+     *
+     * @private
+     * @param {Object} object The object to modify.
+     * @param {string} key The key of the property to assign.
+     * @param {*} value The value to assign.
+     */
+    function assignValue(object, key, value) {
+      var objValue = object[key];
+      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
+          (value === undefined && !(key in object))) {
+        baseAssignValue(object, key, value);
+      }
+    }
+
+    /**
+     * Gets the index at which the `key` is found in `array` of key-value pairs.
+     *
+     * @private
+     * @param {Array} array The array to inspect.
+     * @param {*} key The key to search for.
+     * @returns {number} Returns the index of the matched value, else `-1`.
+     */
+    function assocIndexOf(array, key) {
+      var length = array.length;
+      while (length--) {
+        if (eq(array[length][0], key)) {
+          return length;
+        }
+      }
+      return -1;
+    }
+
+    /**
+     * Aggregates elements of `collection` on `accumulator` with keys transformed
+     * by `iteratee` and values set by `setter`.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} setter The function to set `accumulator` values.
+     * @param {Function} iteratee The iteratee to transform keys.
+     * @param {Object} accumulator The initial aggregated object.
+     * @returns {Function} Returns `accumulator`.
+     */
+    function baseAggregator(collection, setter, iteratee, accumulator) {
+      baseEach(collection, function(value, key, collection) {
+        setter(accumulator, value, iteratee(value), collection);
+      });
+      return accumulator;
+    }
+
+    /**
+     * The base implementation of `_.assign` without support for multiple sources
+     * or `customizer` functions.
+     *
+     * @private
+     * @param {Object} object The destination object.
+     * @param {Object} source The source object.
+     * @returns {Object} Returns `object`.
+     */
+    function baseAssign(object, source) {
+      return object && copyObject(source, keys(source), object);
+    }
+
+    /**
+     * The base implementation of `_.assignIn` without support for multiple sources
+     * or `customizer` functions.
+     *
+     * @private
+     * @param {Object} object The destination object.
+     * @param {Object} source The source object.
+     * @returns {Object} Returns `object`.
+     */
+    function baseAssignIn(object, source) {
+      return object && copyObject(source, keysIn(source), object);
+    }
+
+    /**
+     * The base implementation of `assignValue` and `assignMergeValue` without
+     * value checks.
+     *
+     * @private
+     * @param {Object} object The object to modify.
+     * @param {string} key The key of the property to assign.
+     * @param {*} value The value to assign.
+     */
+    function baseAssignValue(object, key, value) {
+      if (key == '__proto__' && defineProperty) {
+        defineProperty(object, key, {
+          'configurable': true,
+          'enumerable': true,
+          'value': value,
+          'writable': true
+        });
+      } else {
+        object[key] = value;
+      }
+    }
+
+    /**
+     * The base implementation of `_.at` without support for individual paths.
+     *
+     * @private
+     * @param {Object} object The object to iterate over.
+     * @param {string[]} paths The property paths to pick.
+     * @returns {Array} Returns the picked elements.
+     */
+    function baseAt(object, paths) {
+      var index = -1,
+          length = paths.length,
+          result = Array(length),
+          skip = object == null;
+
+      while (++index < length) {
+        result[index] = skip ? undefined : get(object, paths[index]);
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.clamp` which doesn't coerce arguments.
+     *
+     * @private
+     * @param {number} number The number to clamp.
+     * @param {number} [lower] The lower bound.
+     * @param {number} upper The upper bound.
+     * @returns {number} Returns the clamped number.
+     */
+    function baseClamp(number, lower, upper) {
+      if (number === number) {
+        if (upper !== undefined) {
+          number = number <= upper ? number : upper;
+        }
+        if (lower !== undefined) {
+          number = number >= lower ? number : lower;
+        }
+      }
+      return number;
+    }
+
+    /**
+     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
+     * traversed objects.
+     *
+     * @private
+     * @param {*} value The value to clone.
+     * @param {boolean} bitmask The bitmask flags.
+     *  1 - Deep clone
+     *  2 - Flatten inherited properties
+     *  4 - Clone symbols
+     * @param {Function} [customizer] The function to customize cloning.
+     * @param {string} [key] The key of `value`.
+     * @param {Object} [object] The parent object of `value`.
+     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
+     * @returns {*} Returns the cloned value.
+     */
+    function baseClone(value, bitmask, customizer, key, object, stack) {
+      var result,
+          isDeep = bitmask & CLONE_DEEP_FLAG,
+          isFlat = bitmask & CLONE_FLAT_FLAG,
+          isFull = bitmask & CLONE_SYMBOLS_FLAG;
+
+      if (customizer) {
+        result = object ? customizer(value, key, object, stack) : customizer(value);
+      }
+      if (result !== undefined) {
+        return result;
+      }
+      if (!isObject(value)) {
+        return value;
+      }
+      var isArr = isArray(value);
+      if (isArr) {
+        result = initCloneArray(value);
+        if (!isDeep) {
+          return copyArray(value, result);
+        }
+      } else {
+        var tag = getTag(value),
+            isFunc = tag == funcTag || tag == genTag;
+
+        if (isBuffer(value)) {
+          return cloneBuffer(value, isDeep);
+        }
+        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
+          result = (isFlat || isFunc) ? {} : initCloneObject(value);
+          if (!isDeep) {
+            return isFlat
+              ? copySymbolsIn(value, baseAssignIn(result, value))
+              : copySymbols(value, baseAssign(result, value));
+          }
+        } else {
+          if (!cloneableTags[tag]) {
+            return object ? value : {};
+          }
+          result = initCloneByTag(value, tag, baseClone, isDeep);
+        }
+      }
+      // Check for circular references and return its corresponding clone.
+      stack || (stack = new Stack);
+      var stacked = stack.get(value);
+      if (stacked) {
+        return stacked;
+      }
+      stack.set(value, result);
+
+      var keysFunc = isFull
+        ? (isFlat ? getAllKeysIn : getAllKeys)
+        : (isFlat ? keysIn : keys);
+
+      var props = isArr ? undefined : keysFunc(value);
+      arrayEach(props || value, function(subValue, key) {
+        if (props) {
+          key = subValue;
+          subValue = value[key];
+        }
+        // Recursively populate clone (susceptible to call stack limits).
+        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
+      });
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.conforms` which doesn't clone `source`.
+     *
+     * @private
+     * @param {Object} source The object of property predicates to conform to.
+     * @returns {Function} Returns the new spec function.
+     */
+    function baseConforms(source) {
+      var props = keys(source);
+      return function(object) {
+        return baseConformsTo(object, source, props);
+      };
+    }
+
+    /**
+     * The base implementation of `_.conformsTo` which accepts `props` to check.
+     *
+     * @private
+     * @param {Object} object The object to inspect.
+     * @param {Object} source The object of property predicates to conform to.
+     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
+     */
+    function baseConformsTo(object, source, props) {
+      var length = props.length;
+      if (object == null) {
+        return !length;
+      }
+      object = Object(object);
+      while (length--) {
+        var key = props[length],
+            predicate = source[key],
+            value = object[key];
+
+        if ((value === undefined && !(key in object)) || !predicate(value)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    /**
+     * The base implementation of `_.delay` and `_.defer` which accepts `args`
+     * to provide to `func`.
+     *
+     * @private
+     * @param {Function} func The function to delay.
+     * @param {number} wait The number of milliseconds to delay invocation.
+     * @param {Array} args The arguments to provide to `func`.
+     * @returns {number|Object} Returns the timer id or timeout object.
+     */
+    function baseDelay(func, wait, args) {
+      if (typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      return setTimeout(function() { func.apply(undefined, args); }, wait);
+    }
+
+    /**
+     * The base implementation of methods like `_.difference` without support
+     * for excluding multiple arrays or iteratee shorthands.
+     *
+     * @private
+     * @param {Array} array The array to inspect.
+     * @param {Array} values The values to exclude.
+     * @param {Function} [iteratee] The iteratee invoked per element.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns the new array of filtered values.
+     */
+    function baseDifference(array, values, iteratee, comparator) {
+      var index = -1,
+          includes = arrayIncludes,
+          isCommon = true,
+          length = array.length,
+          result = [],
+          valuesLength = values.length;
+
+      if (!length) {
+        return result;
+      }
+      if (iteratee) {
+        values = arrayMap(values, baseUnary(iteratee));
+      }
+      if (comparator) {
+        includes = arrayIncludesWith;
+        isCommon = false;
+      }
+      else if (values.length >= LARGE_ARRAY_SIZE) {
+        includes = cacheHas;
+        isCommon = false;
+        values = new SetCache(values);
+      }
+      outer:
+      while (++index < length) {
+        var value = array[index],
+            computed = iteratee == null ? value : iteratee(value);
+
+        value = (comparator || value !== 0) ? value : 0;
+        if (isCommon && computed === computed) {
+          var valuesIndex = valuesLength;
+          while (valuesIndex--) {
+            if (values[valuesIndex] === computed) {
+              continue outer;
+            }
+          }
+          result.push(value);
+        }
+        else if (!includes(values, computed, comparator)) {
+          result.push(value);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.forEach` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} iteratee The function invoked per iteration.
+     * @returns {Array|Object} Returns `collection`.
+     */
+    var baseEach = createBaseEach(baseForOwn);
+
+    /**
+     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} iteratee The function invoked per iteration.
+     * @returns {Array|Object} Returns `collection`.
+     */
+    var baseEachRight = createBaseEach(baseForOwnRight, true);
+
+    /**
+     * The base implementation of `_.every` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} predicate The function invoked per iteration.
+     * @returns {boolean} Returns `true` if all elements pass the predicate check,
+     *  else `false`
+     */
+    function baseEvery(collection, predicate) {
+      var result = true;
+      baseEach(collection, function(value, index, collection) {
+        result = !!predicate(value, index, collection);
+        return result;
+      });
+      return result;
+    }
+
+    /**
+     * The base implementation of methods like `_.max` and `_.min` which accepts a
+     * `comparator` to determine the extremum value.
+     *
+     * @private
+     * @param {Array} array The array to iterate over.
+     * @param {Function} iteratee The iteratee invoked per iteration.
+     * @param {Function} comparator The comparator used to compare values.
+     * @returns {*} Returns the extremum value.
+     */
+    function baseExtremum(array, iteratee, comparator) {
+      var index = -1,
+          length = array.length;
+
+      while (++index < length) {
+        var value = array[index],
+            current = iteratee(value);
+
+        if (current != null && (computed === undefined
+              ? (current === current && !isSymbol(current))
+              : comparator(current, computed)
+            )) {
+          var computed = current,
+              result = value;
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.fill` without an iteratee call guard.
+     *
+     * @private
+     * @param {Array} array The array to fill.
+     * @param {*} value The value to fill `array` with.
+     * @param {number} [start=0] The start position.
+     * @param {number} [end=array.length] The end position.
+     * @returns {Array} Returns `array`.
+     */
+    function baseFill(array, value, start, end) {
+      var length = array.length;
+
+      start = toInteger(start);
+      if (start < 0) {
+        start = -start > length ? 0 : (length + start);
+      }
+      end = (end === undefined || end > length) ? length : toInteger(end);
+      if (end < 0) {
+        end += length;
+      }
+      end = start > end ? 0 : toLength(end);
+      while (start < end) {
+        array[start++] = value;
+      }
+      return array;
+    }
+
+    /**
+     * The base implementation of `_.filter` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} predicate The function invoked per iteration.
+     * @returns {Array} Returns the new filtered array.
+     */
+    function baseFilter(collection, predicate) {
+      var result = [];
+      baseEach(collection, function(value, index, collection) {
+        if (predicate(value, index, collection)) {
+          result.push(value);
+        }
+      });
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.flatten` with support for restricting flattening.
+     *
+     * @private
+     * @param {Array} array The array to flatten.
+     * @param {number} depth The maximum recursion depth.
+     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
+     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
+     * @param {Array} [result=[]] The initial result value.
+     * @returns {Array} Returns the new flattened array.
+     */
+    function baseFlatten(array, depth, predicate, isStrict, result) {
+      var index = -1,
+          length = array.length;
+
+      predicate || (predicate = isFlattenable);
+      result || (result = []);
+
+      while (++index < length) {
+        var value = array[index];
+        if (depth > 0 && predicate(value)) {
+          if (depth > 1) {
+            // Recursively flatten arrays (susceptible to call stack limits).
+            baseFlatten(value, depth - 1, predicate, isStrict, result);
+          } else {
+            arrayPush(result, value);
+          }
+        } else if (!isStrict) {
+          result[result.length] = value;
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `baseForOwn` which iterates over `object`
+     * properties returned by `keysFunc` and invokes `iteratee` for each property.
+     * Iteratee functions may exit iteration early by explicitly returning `false`.
+     *
+     * @private
+     * @param {Object} object The object to iterate over.
+     * @param {Function} iteratee The function invoked per iteration.
+     * @param {Function} keysFunc The function to get the keys of `object`.
+     * @returns {Object} Returns `object`.
+     */
+    var baseFor = createBaseFor();
+
+    /**
+     * This function is like `baseFor` except that it iterates over properties
+     * in the opposite order.
+     *
+     * @private
+     * @param {Object} object The object to iterate over.
+     * @param {Function} iteratee The function invoked per iteration.
+     * @param {Function} keysFunc The function to get the keys of `object`.
+     * @returns {Object} Returns `object`.
+     */
+    var baseForRight = createBaseFor(true);
+
+    /**
+     * The base implementation of `_.forOwn` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Object} object The object to iterate over.
+     * @param {Function} iteratee The function invoked per iteration.
+     * @returns {Object} Returns `object`.
+     */
+    function baseForOwn(object, iteratee) {
+      return object && baseFor(object, iteratee, keys);
+    }
+
+    /**
+     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Object} object The object to iterate over.
+     * @param {Function} iteratee The function invoked per iteration.
+     * @returns {Object} Returns `object`.
+     */
+    function baseForOwnRight(object, iteratee) {
+      return object && baseForRight(object, iteratee, keys);
+    }
+
+    /**
+     * The base implementation of `_.functions` which creates an array of
+     * `object` function property names filtered from `props`.
+     *
+     * @private
+     * @param {Object} object The object to inspect.
+     * @param {Array} props The property names to filter.
+     * @returns {Array} Returns the function names.
+     */
+    function baseFunctions(object, props) {
+      return arrayFilter(props, function(key) {
+        return isFunction(object[key]);
+      });
+    }
+
+    /**
+     * The base implementation of `_.get` without support for default values.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @param {Array|string} path The path of the property to get.
+     * @returns {*} Returns the resolved value.
+     */
+    function baseGet(object, path) {
+      path = castPath(path, object);
+
+      var index = 0,
+          length = path.length;
+
+      while (object != null && index < length) {
+        object = object[toKey(path[index++])];
+      }
+      return (index && index == length) ? object : undefined;
+    }
+
+    /**
+     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
+     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
+     * symbols of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @param {Function} keysFunc The function to get the keys of `object`.
+     * @param {Function} symbolsFunc The function to get the symbols of `object`.
+     * @returns {Array} Returns the array of property names and symbols.
+     */
+    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
+      var result = keysFunc(object);
+      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
+    }
+
+    /**
+     * The base implementation of `getTag` without fallbacks for buggy environments.
+     *
+     * @private
+     * @param {*} value The value to query.
+     * @returns {string} Returns the `toStringTag`.
+     */
+    function baseGetTag(value) {
+      if (value == null) {
+        return value === undefined ? undefinedTag : nullTag;
+      }
+      return (symToStringTag && symToStringTag in Object(value))
+        ? getRawTag(value)
+        : objectToString(value);
+    }
+
+    /**
+     * The base implementation of `_.gt` which doesn't coerce arguments.
+     *
+     * @private
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @returns {boolean} Returns `true` if `value` is greater than `other`,
+     *  else `false`.
+     */
+    function baseGt(value, other) {
+      return value > other;
+    }
+
+    /**
+     * The base implementation of `_.has` without support for deep paths.
+     *
+     * @private
+     * @param {Object} [object] The object to query.
+     * @param {Array|string} key The key to check.
+     * @returns {boolean} Returns `true` if `key` exists, else `false`.
+     */
+    function baseHas(object, key) {
+      return object != null && hasOwnProperty.call(object, key);
+    }
+
+    /**
+     * The base implementation of `_.hasIn` without support for deep paths.
+     *
+     * @private
+     * @param {Object} [object] The object to query.
+     * @param {Array|string} key The key to check.
+     * @returns {boolean} Returns `true` if `key` exists, else `false`.
+     */
+    function baseHasIn(object, key) {
+      return object != null && key in Object(object);
+    }
+
+    /**
+     * The base implementation of `_.inRange` which doesn't coerce arguments.
+     *
+     * @private
+     * @param {number} number The number to check.
+     * @param {number} start The start of the range.
+     * @param {number} end The end of the range.
+     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
+     */
+    function baseInRange(number, start, end) {
+      return number >= nativeMin(start, end) && number < nativeMax(start, end);
+    }
+
+    /**
+     * The base implementation of methods like `_.intersection`, without support
+     * for iteratee shorthands, that accepts an array of arrays to inspect.
+     *
+     * @private
+     * @param {Array} arrays The arrays to inspect.
+     * @param {Function} [iteratee] The iteratee invoked per element.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns the new array of shared values.
+     */
+    function baseIntersection(arrays, iteratee, comparator) {
+      var includes = comparator ? arrayIncludesWith : arrayIncludes,
+          length = arrays[0].length,
+          othLength = arrays.length,
+          othIndex = othLength,
+          caches = Array(othLength),
+          maxLength = Infinity,
+          result = [];
+
+      while (othIndex--) {
+        var array = arrays[othIndex];
+        if (othIndex && iteratee) {
+          array = arrayMap(array, baseUnary(iteratee));
+        }
+        maxLength = nativeMin(array.length, maxLength);
+        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
+          ? new SetCache(othIndex && array)
+          : undefined;
+      }
+      array = arrays[0];
+
+      var index = -1,
+          seen = caches[0];
+
+      outer:
+      while (++index < length && result.length < maxLength) {
+        var value = array[index],
+            computed = iteratee ? iteratee(value) : value;
+
+        value = (comparator || value !== 0) ? value : 0;
+        if (!(seen
+              ? cacheHas(seen, computed)
+              : includes(result, computed, comparator)
+            )) {
+          othIndex = othLength;
+          while (--othIndex) {
+            var cache = caches[othIndex];
+            if (!(cache
+                  ? cacheHas(cache, computed)
+                  : includes(arrays[othIndex], computed, comparator))
+                ) {
+              continue outer;
+            }
+          }
+          if (seen) {
+            seen.push(computed);
+          }
+          result.push(value);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.invert` and `_.invertBy` which inverts
+     * `object` with values transformed by `iteratee` and set by `setter`.
+     *
+     * @private
+     * @param {Object} object The object to iterate over.
+     * @param {Function} setter The function to set `accumulator` values.
+     * @param {Function} iteratee The iteratee to transform values.
+     * @param {Object} accumulator The initial inverted object.
+     * @returns {Function} Returns `accumulator`.
+     */
+    function baseInverter(object, setter, iteratee, accumulator) {
+      baseForOwn(object, function(value, key, object) {
+        setter(accumulator, iteratee(value), key, object);
+      });
+      return accumulator;
+    }
+
+    /**
+     * The base implementation of `_.invoke` without support for individual
+     * method arguments.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @param {Array|string} path The path of the method to invoke.
+     * @param {Array} args The arguments to invoke the method with.
+     * @returns {*} Returns the result of the invoked method.
+     */
+    function baseInvoke(object, path, args) {
+      path = castPath(path, object);
+      object = parent(object, path);
+      var func = object == null ? object : object[toKey(last(path))];
+      return func == null ? undefined : apply(func, object, args);
+    }
+
+    /**
+     * The base implementation of `_.isArguments`.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+     */
+    function baseIsArguments(value) {
+      return isObjectLike(value) && baseGetTag(value) == argsTag;
+    }
+
+    /**
+     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
+     */
+    function baseIsArrayBuffer(value) {
+      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
+    }
+
+    /**
+     * The base implementation of `_.isDate` without Node.js optimizations.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
+     */
+    function baseIsDate(value) {
+      return isObjectLike(value) && baseGetTag(value) == dateTag;
+    }
+
+    /**
+     * The base implementation of `_.isEqual` which supports partial comparisons
+     * and tracks traversed objects.
+     *
+     * @private
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @param {boolean} bitmask The bitmask flags.
+     *  1 - Unordered comparison
+     *  2 - Partial comparison
+     * @param {Function} [customizer] The function to customize comparisons.
+     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+     */
+    function baseIsEqual(value, other, bitmask, customizer, stack) {
+      if (value === other) {
+        return true;
+      }
+      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
+        return value !== value && other !== other;
+      }
+      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
+    }
+
+    /**
+     * A specialized version of `baseIsEqual` for arrays and objects which performs
+     * deep comparisons and tracks traversed objects enabling objects with circular
+     * references to be compared.
+     *
+     * @private
+     * @param {Object} object The object to compare.
+     * @param {Object} other The other object to compare.
+     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {Function} equalFunc The function to determine equivalents of values.
+     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
+     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+     */
+    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
+      var objIsArr = isArray(object),
+          othIsArr = isArray(other),
+          objTag = objIsArr ? arrayTag : getTag(object),
+          othTag = othIsArr ? arrayTag : getTag(other);
+
+      objTag = objTag == argsTag ? objectTag : objTag;
+      othTag = othTag == argsTag ? objectTag : othTag;
+
+      var objIsObj = objTag == objectTag,
+          othIsObj = othTag == objectTag,
+          isSameTag = objTag == othTag;
+
+      if (isSameTag && isBuffer(object)) {
+        if (!isBuffer(other)) {
+          return false;
+        }
+        objIsArr = true;
+        objIsObj = false;
+      }
+      if (isSameTag && !objIsObj) {
+        stack || (stack = new Stack);
+        return (objIsArr || isTypedArray(object))
+          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
+          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
+      }
+      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
+        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
+            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
+
+        if (objIsWrapped || othIsWrapped) {
+          var objUnwrapped = objIsWrapped ? object.value() : object,
+              othUnwrapped = othIsWrapped ? other.value() : other;
+
+          stack || (stack = new Stack);
+          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
+        }
+      }
+      if (!isSameTag) {
+        return false;
+      }
+      stack || (stack = new Stack);
+      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
+    }
+
+    /**
+     * The base implementation of `_.isMap` without Node.js optimizations.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
+     */
+    function baseIsMap(value) {
+      return isObjectLike(value) && getTag(value) == mapTag;
+    }
+
+    /**
+     * The base implementation of `_.isMatch` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Object} object The object to inspect.
+     * @param {Object} source The object of property values to match.
+     * @param {Array} matchData The property names, values, and compare flags to match.
+     * @param {Function} [customizer] The function to customize comparisons.
+     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+     */
+    function baseIsMatch(object, source, matchData, customizer) {
+      var index = matchData.length,
+          length = index,
+          noCustomizer = !customizer;
+
+      if (object == null) {
+        return !length;
+      }
+      object = Object(object);
+      while (index--) {
+        var data = matchData[index];
+        if ((noCustomizer && data[2])
+              ? data[1] !== object[data[0]]
+              : !(data[0] in object)
+            ) {
+          return false;
+        }
+      }
+      while (++index < length) {
+        data = matchData[index];
+        var key = data[0],
+            objValue = object[key],
+            srcValue = data[1];
+
+        if (noCustomizer && data[2]) {
+          if (objValue === undefined && !(key in object)) {
+            return false;
+          }
+        } else {
+          var stack = new Stack;
+          if (customizer) {
+            var result = customizer(objValue, srcValue, key, object, source, stack);
+          }
+          if (!(result === undefined
+                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
+                : result
+              )) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+
+    /**
+     * The base implementation of `_.isNative` without bad shim checks.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a native function,
+     *  else `false`.
+     */
+    function baseIsNative(value) {
+      if (!isObject(value) || isMasked(value)) {
+        return false;
+      }
+      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
+      return pattern.test(toSource(value));
+    }
+
+    /**
+     * The base implementation of `_.isRegExp` without Node.js optimizations.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
+     */
+    function baseIsRegExp(value) {
+      return isObjectLike(value) && baseGetTag(value) == regexpTag;
+    }
+
+    /**
+     * The base implementation of `_.isSet` without Node.js optimizations.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+     */
+    function baseIsSet(value) {
+      return isObjectLike(value) && getTag(value) == setTag;
+    }
+
+    /**
+     * The base implementation of `_.isTypedArray` without Node.js optimizations.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+     */
+    function baseIsTypedArray(value) {
+      return isObjectLike(value) &&
+        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
+    }
+
+    /**
+     * The base implementation of `_.iteratee`.
+     *
+     * @private
+     * @param {*} [value=_.identity] The value to convert to an iteratee.
+     * @returns {Function} Returns the iteratee.
+     */
+    function baseIteratee(value) {
+      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
+      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
+      if (typeof value == 'function') {
+        return value;
+      }
+      if (value == null) {
+        return identity;
+      }
+      if (typeof value == 'object') {
+        return isArray(value)
+          ? baseMatchesProperty(value[0], value[1])
+          : baseMatches(value);
+      }
+      return property(value);
+    }
+
+    /**
+     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names.
+     */
+    function baseKeys(object) {
+      if (!isPrototype(object)) {
+        return nativeKeys(object);
+      }
+      var result = [];
+      for (var key in Object(object)) {
+        if (hasOwnProperty.call(object, key) && key != 'constructor') {
+          result.push(key);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names.
+     */
+    function baseKeysIn(object) {
+      if (!isObject(object)) {
+        return nativeKeysIn(object);
+      }
+      var isProto = isPrototype(object),
+          result = [];
+
+      for (var key in object) {
+        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+          result.push(key);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.lt` which doesn't coerce arguments.
+     *
+     * @private
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @returns {boolean} Returns `true` if `value` is less than `other`,
+     *  else `false`.
+     */
+    function baseLt(value, other) {
+      return value < other;
+    }
+
+    /**
+     * The base implementation of `_.map` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} iteratee The function invoked per iteration.
+     * @returns {Array} Returns the new mapped array.
+     */
+    function baseMap(collection, iteratee) {
+      var index = -1,
+          result = isArrayLike(collection) ? Array(collection.length) : [];
+
+      baseEach(collection, function(value, key, collection) {
+        result[++index] = iteratee(value, key, collection);
+      });
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.matches` which doesn't clone `source`.
+     *
+     * @private
+     * @param {Object} source The object of property values to match.
+     * @returns {Function} Returns the new spec function.
+     */
+    function baseMatches(source) {
+      var matchData = getMatchData(source);
+      if (matchData.length == 1 && matchData[0][2]) {
+        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
+      }
+      return function(object) {
+        return object === source || baseIsMatch(object, source, matchData);
+      };
+    }
+
+    /**
+     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
+     *
+     * @private
+     * @param {string} path The path of the property to get.
+     * @param {*} srcValue The value to match.
+     * @returns {Function} Returns the new spec function.
+     */
+    function baseMatchesProperty(path, srcValue) {
+      if (isKey(path) && isStrictComparable(srcValue)) {
+        return matchesStrictComparable(toKey(path), srcValue);
+      }
+      return function(object) {
+        var objValue = get(object, path);
+        return (objValue === undefined && objValue === srcValue)
+          ? hasIn(object, path)
+          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
+      };
+    }
+
+    /**
+     * The base implementation of `_.merge` without support for multiple sources.
+     *
+     * @private
+     * @param {Object} object The destination object.
+     * @param {Object} source The source object.
+     * @param {number} srcIndex The index of `source`.
+     * @param {Function} [customizer] The function to customize merged values.
+     * @param {Object} [stack] Tracks traversed source values and their merged
+     *  counterparts.
+     */
+    function baseMerge(object, source, srcIndex, customizer, stack) {
+      if (object === source) {
+        return;
+      }
+      baseFor(source, function(srcValue, key) {
+        if (isObject(srcValue)) {
+          stack || (stack = new Stack);
+          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
+        }
+        else {
+          var newValue = customizer
+            ? customizer(object[key], srcValue, (key + ''), object, source, stack)
+            : undefined;
+
+          if (newValue === undefined) {
+            newValue = srcValue;
+          }
+          assignMergeValue(object, key, newValue);
+        }
+      }, keysIn);
+    }
+
+    /**
+     * A specialized version of `baseMerge` for arrays and objects which performs
+     * deep merges and tracks traversed objects enabling objects with circular
+     * references to be merged.
+     *
+     * @private
+     * @param {Object} object The destination object.
+     * @param {Object} source The source object.
+     * @param {string} key The key of the value to merge.
+     * @param {number} srcIndex The index of `source`.
+     * @param {Function} mergeFunc The function to merge values.
+     * @param {Function} [customizer] The function to customize assigned values.
+     * @param {Object} [stack] Tracks traversed source values and their merged
+     *  counterparts.
+     */
+    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
+      var objValue = object[key],
+          srcValue = source[key],
+          stacked = stack.get(srcValue);
+
+      if (stacked) {
+        assignMergeValue(object, key, stacked);
+        return;
+      }
+      var newValue = customizer
+        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
+        : undefined;
+
+      var isCommon = newValue === undefined;
+
+      if (isCommon) {
+        var isArr = isArray(srcValue),
+            isBuff = !isArr && isBuffer(srcValue),
+            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
+
+        newValue = srcValue;
+        if (isArr || isBuff || isTyped) {
+          if (isArray(objValue)) {
+            newValue = objValue;
+          }
+          else if (isArrayLikeObject(objValue)) {
+            newValue = copyArray(objValue);
+          }
+          else if (isBuff) {
+            isCommon = false;
+            newValue = cloneBuffer(srcValue, true);
+          }
+          else if (isTyped) {
+            isCommon = false;
+            newValue = cloneTypedArray(srcValue, true);
+          }
+          else {
+            newValue = [];
+          }
+        }
+        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
+          newValue = objValue;
+          if (isArguments(objValue)) {
+            newValue = toPlainObject(objValue);
+          }
+          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
+            newValue = initCloneObject(srcValue);
+          }
+        }
+        else {
+          isCommon = false;
+        }
+      }
+      if (isCommon) {
+        // Recursively merge objects and arrays (susceptible to call stack limits).
+        stack.set(srcValue, newValue);
+        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
+        stack['delete'](srcValue);
+      }
+      assignMergeValue(object, key, newValue);
+    }
+
+    /**
+     * The base implementation of `_.nth` which doesn't coerce arguments.
+     *
+     * @private
+     * @param {Array} array The array to query.
+     * @param {number} n The index of the element to return.
+     * @returns {*} Returns the nth element of `array`.
+     */
+    function baseNth(array, n) {
+      var length = array.length;
+      if (!length) {
+        return;
+      }
+      n += n < 0 ? length : 0;
+      return isIndex(n, length) ? array[n] : undefined;
+    }
+
+    /**
+     * The base implementation of `_.orderBy` without param guards.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
+     * @param {string[]} orders The sort orders of `iteratees`.
+     * @returns {Array} Returns the new sorted array.
+     */
+    function baseOrderBy(collection, iteratees, orders) {
+      var index = -1;
+      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
+
+      var result = baseMap(collection, function(value, key, collection) {
+        var criteria = arrayMap(iteratees, function(iteratee) {
+          return iteratee(value);
+        });
+        return { 'criteria': criteria, 'index': ++index, 'value': value };
+      });
+
+      return baseSortBy(result, function(object, other) {
+        return compareMultiple(object, other, orders);
+      });
+    }
+
+    /**
+     * The base implementation of `_.pick` without support for individual
+     * property identifiers.
+     *
+     * @private
+     * @param {Object} object The source object.
+     * @param {string[]} paths The property paths to pick.
+     * @returns {Object} Returns the new object.
+     */
+    function basePick(object, paths) {
+      return basePickBy(object, paths, function(value, path) {
+        return hasIn(object, path);
+      });
+    }
+
+    /**
+     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Object} object The source object.
+     * @param {string[]} paths The property paths to pick.
+     * @param {Function} predicate The function invoked per property.
+     * @returns {Object} Returns the new object.
+     */
+    function basePickBy(object, paths, predicate) {
+      var index = -1,
+          length = paths.length,
+          result = {};
+
+      while (++index < length) {
+        var path = paths[index],
+            value = baseGet(object, path);
+
+        if (predicate(value, path)) {
+          baseSet(result, castPath(path, object), value);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * A specialized version of `baseProperty` which supports deep paths.
+     *
+     * @private
+     * @param {Array|string} path The path of the property to get.
+     * @returns {Function} Returns the new accessor function.
+     */
+    function basePropertyDeep(path) {
+      return function(object) {
+        return baseGet(object, path);
+      };
+    }
+
+    /**
+     * The base implementation of `_.pullAllBy` without support for iteratee
+     * shorthands.
+     *
+     * @private
+     * @param {Array} array The array to modify.
+     * @param {Array} values The values to remove.
+     * @param {Function} [iteratee] The iteratee invoked per element.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns `array`.
+     */
+    function basePullAll(array, values, iteratee, comparator) {
+      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
+          index = -1,
+          length = values.length,
+          seen = array;
+
+      if (array === values) {
+        values = copyArray(values);
+      }
+      if (iteratee) {
+        seen = arrayMap(array, baseUnary(iteratee));
+      }
+      while (++index < length) {
+        var fromIndex = 0,
+            value = values[index],
+            computed = iteratee ? iteratee(value) : value;
+
+        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
+          if (seen !== array) {
+            splice.call(seen, fromIndex, 1);
+          }
+          splice.call(array, fromIndex, 1);
+        }
+      }
+      return array;
+    }
+
+    /**
+     * The base implementation of `_.pullAt` without support for individual
+     * indexes or capturing the removed elements.
+     *
+     * @private
+     * @param {Array} array The array to modify.
+     * @param {number[]} indexes The indexes of elements to remove.
+     * @returns {Array} Returns `array`.
+     */
+    function basePullAt(array, indexes) {
+      var length = array ? indexes.length : 0,
+          lastIndex = length - 1;
+
+      while (length--) {
+        var index = indexes[length];
+        if (length == lastIndex || index !== previous) {
+          var previous = index;
+          if (isIndex(index)) {
+            splice.call(array, index, 1);
+          } else {
+            baseUnset(array, index);
+          }
+        }
+      }
+      return array;
+    }
+
+    /**
+     * The base implementation of `_.random` without support for returning
+     * floating-point numbers.
+     *
+     * @private
+     * @param {number} lower The lower bound.
+     * @param {number} upper The upper bound.
+     * @returns {number} Returns the random number.
+     */
+    function baseRandom(lower, upper) {
+      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
+    }
+
+    /**
+     * The base implementation of `_.range` and `_.rangeRight` which doesn't
+     * coerce arguments.
+     *
+     * @private
+     * @param {number} start The start of the range.
+     * @param {number} end The end of the range.
+     * @param {number} step The value to increment or decrement by.
+     * @param {boolean} [fromRight] Specify iterating from right to left.
+     * @returns {Array} Returns the range of numbers.
+     */
+    function baseRange(start, end, step, fromRight) {
+      var index = -1,
+          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
+          result = Array(length);
+
+      while (length--) {
+        result[fromRight ? length : ++index] = start;
+        start += step;
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.repeat` which doesn't coerce arguments.
+     *
+     * @private
+     * @param {string} string The string to repeat.
+     * @param {number} n The number of times to repeat the string.
+     * @returns {string} Returns the repeated string.
+     */
+    function baseRepeat(string, n) {
+      var result = '';
+      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
+        return result;
+      }
+      // Leverage the exponentiation by squaring algorithm for a faster repeat.
+      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
+      do {
+        if (n % 2) {
+          result += string;
+        }
+        n = nativeFloor(n / 2);
+        if (n) {
+          string += string;
+        }
+      } while (n);
+
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.rest` which doesn't validate or coerce arguments.
+     *
+     * @private
+     * @param {Function} func The function to apply a rest parameter to.
+     * @param {number} [start=func.length-1] The start position of the rest parameter.
+     * @returns {Function} Returns the new function.
+     */
+    function baseRest(func, start) {
+      return setToString(overRest(func, start, identity), func + '');
+    }
+
+    /**
+     * The base implementation of `_.sample`.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to sample.
+     * @returns {*} Returns the random element.
+     */
+    function baseSample(collection) {
+      return arraySample(values(collection));
+    }
+
+    /**
+     * The base implementation of `_.sampleSize` without param guards.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to sample.
+     * @param {number} n The number of elements to sample.
+     * @returns {Array} Returns the random elements.
+     */
+    function baseSampleSize(collection, n) {
+      var array = values(collection);
+      return shuffleSelf(array, baseClamp(n, 0, array.length));
+    }
+
+    /**
+     * The base implementation of `_.set`.
+     *
+     * @private
+     * @param {Object} object The object to modify.
+     * @param {Array|string} path The path of the property to set.
+     * @param {*} value The value to set.
+     * @param {Function} [customizer] The function to customize path creation.
+     * @returns {Object} Returns `object`.
+     */
+    function baseSet(object, path, value, customizer) {
+      if (!isObject(object)) {
+        return object;
+      }
+      path = castPath(path, object);
+
+      var index = -1,
+          length = path.length,
+          lastIndex = length - 1,
+          nested = object;
+
+      while (nested != null && ++index < length) {
+        var key = toKey(path[index]),
+            newValue = value;
+
+        if (index != lastIndex) {
+          var objValue = nested[key];
+          newValue = customizer ? customizer(objValue, key, nested) : undefined;
+          if (newValue === undefined) {
+            newValue = isObject(objValue)
+              ? objValue
+              : (isIndex(path[index + 1]) ? [] : {});
+          }
+        }
+        assignValue(nested, key, newValue);
+        nested = nested[key];
+      }
+      return object;
+    }
+
+    /**
+     * The base implementation of `setData` without support for hot loop shorting.
+     *
+     * @private
+     * @param {Function} func The function to associate metadata with.
+     * @param {*} data The metadata.
+     * @returns {Function} Returns `func`.
+     */
+    var baseSetData = !metaMap ? identity : function(func, data) {
+      metaMap.set(func, data);
+      return func;
+    };
+
+    /**
+     * The base implementation of `setToString` without support for hot loop shorting.
+     *
+     * @private
+     * @param {Function} func The function to modify.
+     * @param {Function} string The `toString` result.
+     * @returns {Function} Returns `func`.
+     */
+    var baseSetToString = !defineProperty ? identity : function(func, string) {
+      return defineProperty(func, 'toString', {
+        'configurable': true,
+        'enumerable': false,
+        'value': constant(string),
+        'writable': true
+      });
+    };
+
+    /**
+     * The base implementation of `_.shuffle`.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to shuffle.
+     * @returns {Array} Returns the new shuffled array.
+     */
+    function baseShuffle(collection) {
+      return shuffleSelf(values(collection));
+    }
+
+    /**
+     * The base implementation of `_.slice` without an iteratee call guard.
+     *
+     * @private
+     * @param {Array} array The array to slice.
+     * @param {number} [start=0] The start position.
+     * @param {number} [end=array.length] The end position.
+     * @returns {Array} Returns the slice of `array`.
+     */
+    function baseSlice(array, start, end) {
+      var index = -1,
+          length = array.length;
+
+      if (start < 0) {
+        start = -start > length ? 0 : (length + start);
+      }
+      end = end > length ? length : end;
+      if (end < 0) {
+        end += length;
+      }
+      length = start > end ? 0 : ((end - start) >>> 0);
+      start >>>= 0;
+
+      var result = Array(length);
+      while (++index < length) {
+        result[index] = array[index + start];
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.some` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} predicate The function invoked per iteration.
+     * @returns {boolean} Returns `true` if any element passes the predicate check,
+     *  else `false`.
+     */
+    function baseSome(collection, predicate) {
+      var result;
+
+      baseEach(collection, function(value, index, collection) {
+        result = predicate(value, index, collection);
+        return !result;
+      });
+      return !!result;
+    }
+
+    /**
+     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
+     * performs a binary search of `array` to determine the index at which `value`
+     * should be inserted into `array` in order to maintain its sort order.
+     *
+     * @private
+     * @param {Array} array The sorted array to inspect.
+     * @param {*} value The value to evaluate.
+     * @param {boolean} [retHighest] Specify returning the highest qualified index.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     */
+    function baseSortedIndex(array, value, retHighest) {
+      var low = 0,
+          high = array == null ? low : array.length;
+
+      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
+        while (low < high) {
+          var mid = (low + high) >>> 1,
+              computed = array[mid];
+
+          if (computed !== null && !isSymbol(computed) &&
+              (retHighest ? (computed <= value) : (computed < value))) {
+            low = mid + 1;
+          } else {
+            high = mid;
+          }
+        }
+        return high;
+      }
+      return baseSortedIndexBy(array, value, identity, retHighest);
+    }
+
+    /**
+     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
+     * which invokes `iteratee` for `value` and each element of `array` to compute
+     * their sort ranking. The iteratee is invoked with one argument; (value).
+     *
+     * @private
+     * @param {Array} array The sorted array to inspect.
+     * @param {*} value The value to evaluate.
+     * @param {Function} iteratee The iteratee invoked per element.
+     * @param {boolean} [retHighest] Specify returning the highest qualified index.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     */
+    function baseSortedIndexBy(array, value, iteratee, retHighest) {
+      value = iteratee(value);
+
+      var low = 0,
+          high = array == null ? 0 : array.length,
+          valIsNaN = value !== value,
+          valIsNull = value === null,
+          valIsSymbol = isSymbol(value),
+          valIsUndefined = value === undefined;
+
+      while (low < high) {
+        var mid = nativeFloor((low + high) / 2),
+            computed = iteratee(array[mid]),
+            othIsDefined = computed !== undefined,
+            othIsNull = computed === null,
+            othIsReflexive = computed === computed,
+            othIsSymbol = isSymbol(computed);
+
+        if (valIsNaN) {
+          var setLow = retHighest || othIsReflexive;
+        } else if (valIsUndefined) {
+          setLow = othIsReflexive && (retHighest || othIsDefined);
+        } else if (valIsNull) {
+          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
+        } else if (valIsSymbol) {
+          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
+        } else if (othIsNull || othIsSymbol) {
+          setLow = false;
+        } else {
+          setLow = retHighest ? (computed <= value) : (computed < value);
+        }
+        if (setLow) {
+          low = mid + 1;
+        } else {
+          high = mid;
+        }
+      }
+      return nativeMin(high, MAX_ARRAY_INDEX);
+    }
+
+    /**
+     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
+     * support for iteratee shorthands.
+     *
+     * @private
+     * @param {Array} array The array to inspect.
+     * @param {Function} [iteratee] The iteratee invoked per element.
+     * @returns {Array} Returns the new duplicate free array.
+     */
+    function baseSortedUniq(array, iteratee) {
+      var index = -1,
+          length = array.length,
+          resIndex = 0,
+          result = [];
+
+      while (++index < length) {
+        var value = array[index],
+            computed = iteratee ? iteratee(value) : value;
+
+        if (!index || !eq(computed, seen)) {
+          var seen = computed;
+          result[resIndex++] = value === 0 ? 0 : value;
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.toNumber` which doesn't ensure correct
+     * conversions of binary, hexadecimal, or octal string values.
+     *
+     * @private
+     * @param {*} value The value to process.
+     * @returns {number} Returns the number.
+     */
+    function baseToNumber(value) {
+      if (typeof value == 'number') {
+        return value;
+      }
+      if (isSymbol(value)) {
+        return NAN;
+      }
+      return +value;
+    }
+
+    /**
+     * The base implementation of `_.toString` which doesn't convert nullish
+     * values to empty strings.
+     *
+     * @private
+     * @param {*} value The value to process.
+     * @returns {string} Returns the string.
+     */
+    function baseToString(value) {
+      // Exit early for strings to avoid a performance hit in some environments.
+      if (typeof value == 'string') {
+        return value;
+      }
+      if (isArray(value)) {
+        // Recursively convert values (susceptible to call stack limits).
+        return arrayMap(value, baseToString) + '';
+      }
+      if (isSymbol(value)) {
+        return symbolToString ? symbolToString.call(value) : '';
+      }
+      var result = (value + '');
+      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+    }
+
+    /**
+     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Array} array The array to inspect.
+     * @param {Function} [iteratee] The iteratee invoked per element.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns the new duplicate free array.
+     */
+    function baseUniq(array, iteratee, comparator) {
+      var index = -1,
+          includes = arrayIncludes,
+          length = array.length,
+          isCommon = true,
+          result = [],
+          seen = result;
+
+      if (comparator) {
+        isCommon = false;
+        includes = arrayIncludesWith;
+      }
+      else if (length >= LARGE_ARRAY_SIZE) {
+        var set = iteratee ? null : createSet(array);
+        if (set) {
+          return setToArray(set);
+        }
+        isCommon = false;
+        includes = cacheHas;
+        seen = new SetCache;
+      }
+      else {
+        seen = iteratee ? [] : result;
+      }
+      outer:
+      while (++index < length) {
+        var value = array[index],
+            computed = iteratee ? iteratee(value) : value;
+
+        value = (comparator || value !== 0) ? value : 0;
+        if (isCommon && computed === computed) {
+          var seenIndex = seen.length;
+          while (seenIndex--) {
+            if (seen[seenIndex] === computed) {
+              continue outer;
+            }
+          }
+          if (iteratee) {
+            seen.push(computed);
+          }
+          result.push(value);
+        }
+        else if (!includes(seen, computed, comparator)) {
+          if (seen !== result) {
+            seen.push(computed);
+          }
+          result.push(value);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.unset`.
+     *
+     * @private
+     * @param {Object} object The object to modify.
+     * @param {Array|string} path The property path to unset.
+     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+     */
+    function baseUnset(object, path) {
+      path = castPath(path, object);
+      object = parent(object, path);
+      return object == null || delete object[toKey(last(path))];
+    }
+
+    /**
+     * The base implementation of `_.update`.
+     *
+     * @private
+     * @param {Object} object The object to modify.
+     * @param {Array|string} path The path of the property to update.
+     * @param {Function} updater The function to produce the updated value.
+     * @param {Function} [customizer] The function to customize path creation.
+     * @returns {Object} Returns `object`.
+     */
+    function baseUpdate(object, path, updater, customizer) {
+      return baseSet(object, path, updater(baseGet(object, path)), customizer);
+    }
+
+    /**
+     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
+     * without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Array} array The array to query.
+     * @param {Function} predicate The function invoked per iteration.
+     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
+     * @param {boolean} [fromRight] Specify iterating from right to left.
+     * @returns {Array} Returns the slice of `array`.
+     */
+    function baseWhile(array, predicate, isDrop, fromRight) {
+      var length = array.length,
+          index = fromRight ? length : -1;
+
+      while ((fromRight ? index-- : ++index < length) &&
+        predicate(array[index], index, array)) {}
+
+      return isDrop
+        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
+        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
+    }
+
+    /**
+     * The base implementation of `wrapperValue` which returns the result of
+     * performing a sequence of actions on the unwrapped `value`, where each
+     * successive action is supplied the return value of the previous.
+     *
+     * @private
+     * @param {*} value The unwrapped value.
+     * @param {Array} actions Actions to perform to resolve the unwrapped value.
+     * @returns {*} Returns the resolved value.
+     */
+    function baseWrapperValue(value, actions) {
+      var result = value;
+      if (result instanceof LazyWrapper) {
+        result = result.value();
+      }
+      return arrayReduce(actions, function(result, action) {
+        return action.func.apply(action.thisArg, arrayPush([result], action.args));
+      }, result);
+    }
+
+    /**
+     * The base implementation of methods like `_.xor`, without support for
+     * iteratee shorthands, that accepts an array of arrays to inspect.
+     *
+     * @private
+     * @param {Array} arrays The arrays to inspect.
+     * @param {Function} [iteratee] The iteratee invoked per element.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns the new array of values.
+     */
+    function baseXor(arrays, iteratee, comparator) {
+      var length = arrays.length;
+      if (length < 2) {
+        return length ? baseUniq(arrays[0]) : [];
+      }
+      var index = -1,
+          result = Array(length);
+
+      while (++index < length) {
+        var array = arrays[index],
+            othIndex = -1;
+
+        while (++othIndex < length) {
+          if (othIndex != index) {
+            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
+          }
+        }
+      }
+      return baseUniq(baseFlatten(result, 1), iteratee, comparator);
+    }
+
+    /**
+     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
+     *
+     * @private
+     * @param {Array} props The property identifiers.
+     * @param {Array} values The property values.
+     * @param {Function} assignFunc The function to assign values.
+     * @returns {Object} Returns the new object.
+     */
+    function baseZipObject(props, values, assignFunc) {
+      var index = -1,
+          length = props.length,
+          valsLength = values.length,
+          result = {};
+
+      while (++index < length) {
+        var value = index < valsLength ? values[index] : undefined;
+        assignFunc(result, props[index], value);
+      }
+      return result;
+    }
+
+    /**
+     * Casts `value` to an empty array if it's not an array like object.
+     *
+     * @private
+     * @param {*} value The value to inspect.
+     * @returns {Array|Object} Returns the cast array-like object.
+     */
+    function castArrayLikeObject(value) {
+      return isArrayLikeObject(value) ? value : [];
+    }
+
+    /**
+     * Casts `value` to `identity` if it's not a function.
+     *
+     * @private
+     * @param {*} value The value to inspect.
+     * @returns {Function} Returns cast function.
+     */
+    function castFunction(value) {
+      return typeof value == 'function' ? value : identity;
+    }
+
+    /**
+     * Casts `value` to a path array if it's not one.
+     *
+     * @private
+     * @param {*} value The value to inspect.
+     * @param {Object} [object] The object to query keys on.
+     * @returns {Array} Returns the cast property path array.
+     */
+    function castPath(value, object) {
+      if (isArray(value)) {
+        return value;
+      }
+      return isKey(value, object) ? [value] : stringToPath(toString(value));
+    }
+
+    /**
+     * A `baseRest` alias which can be replaced with `identity` by module
+     * replacement plugins.
+     *
+     * @private
+     * @type {Function}
+     * @param {Function} func The function to apply a rest parameter to.
+     * @returns {Function} Returns the new function.
+     */
+    var castRest = baseRest;
+
+    /**
+     * Casts `array` to a slice if it's needed.
+     *
+     * @private
+     * @param {Array} array The array to inspect.
+     * @param {number} start The start position.
+     * @param {number} [end=array.length] The end position.
+     * @returns {Array} Returns the cast slice.
+     */
+    function castSlice(array, start, end) {
+      var length = array.length;
+      end = end === undefined ? length : end;
+      return (!start && end >= length) ? array : baseSlice(array, start, end);
+    }
+
+    /**
+     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
+     *
+     * @private
+     * @param {number|Object} id The timer id or timeout object of the timer to clear.
+     */
+    var clearTimeout = ctxClearTimeout || function(id) {
+      return root.clearTimeout(id);
+    };
+
+    /**
+     * Creates a clone of  `buffer`.
+     *
+     * @private
+     * @param {Buffer} buffer The buffer to clone.
+     * @param {boolean} [isDeep] Specify a deep clone.
+     * @returns {Buffer} Returns the cloned buffer.
+     */
+    function cloneBuffer(buffer, isDeep) {
+      if (isDeep) {
+        return buffer.slice();
+      }
+      var length = buffer.length,
+          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
+
+      buffer.copy(result);
+      return result;
+    }
+
+    /**
+     * Creates a clone of `arrayBuffer`.
+     *
+     * @private
+     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
+     * @returns {ArrayBuffer} Returns the cloned array buffer.
+     */
+    function cloneArrayBuffer(arrayBuffer) {
+      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
+      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
+      return result;
+    }
+
+    /**
+     * Creates a clone of `dataView`.
+     *
+     * @private
+     * @param {Object} dataView The data view to clone.
+     * @param {boolean} [isDeep] Specify a deep clone.
+     * @returns {Object} Returns the cloned data view.
+     */
+    function cloneDataView(dataView, isDeep) {
+      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
+      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
+    }
+
+    /**
+     * Creates a clone of `map`.
+     *
+     * @private
+     * @param {Object} map The map to clone.
+     * @param {Function} cloneFunc The function to clone values.
+     * @param {boolean} [isDeep] Specify a deep clone.
+     * @returns {Object} Returns the cloned map.
+     */
+    function cloneMap(map, isDeep, cloneFunc) {
+      var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
+      return arrayReduce(array, addMapEntry, new map.constructor);
+    }
+
+    /**
+     * Creates a clone of `regexp`.
+     *
+     * @private
+     * @param {Object} regexp The regexp to clone.
+     * @returns {Object} Returns the cloned regexp.
+     */
+    function cloneRegExp(regexp) {
+      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
+      result.lastIndex = regexp.lastIndex;
+      return result;
+    }
+
+    /**
+     * Creates a clone of `set`.
+     *
+     * @private
+     * @param {Object} set The set to clone.
+     * @param {Function} cloneFunc The function to clone values.
+     * @param {boolean} [isDeep] Specify a deep clone.
+     * @returns {Object} Returns the cloned set.
+     */
+    function cloneSet(set, isDeep, cloneFunc) {
+      var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
+      return arrayReduce(array, addSetEntry, new set.constructor);
+    }
+
+    /**
+     * Creates a clone of the `symbol` object.
+     *
+     * @private
+     * @param {Object} symbol The symbol object to clone.
+     * @returns {Object} Returns the cloned symbol object.
+     */
+    function cloneSymbol(symbol) {
+      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
+    }
+
+    /**
+     * Creates a clone of `typedArray`.
+     *
+     * @private
+     * @param {Object} typedArray The typed array to clone.
+     * @param {boolean} [isDeep] Specify a deep clone.
+     * @returns {Object} Returns the cloned typed array.
+     */
+    function cloneTypedArray(typedArray, isDeep) {
+      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
+      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
+    }
+
+    /**
+     * Compares values to sort them in ascending order.
+     *
+     * @private
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @returns {number} Returns the sort order indicator for `value`.
+     */
+    function compareAscending(value, other) {
+      if (value !== other) {
+        var valIsDefined = value !== undefined,
+            valIsNull = value === null,
+            valIsReflexive = value === value,
+            valIsSymbol = isSymbol(value);
+
+        var othIsDefined = other !== undefined,
+            othIsNull = other === null,
+            othIsReflexive = other === other,
+            othIsSymbol = isSymbol(other);
+
+        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
+            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
+            (valIsNull && othIsDefined && othIsReflexive) ||
+            (!valIsDefined && othIsReflexive) ||
+            !valIsReflexive) {
+          return 1;
+        }
+        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
+            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
+            (othIsNull && valIsDefined && valIsReflexive) ||
+            (!othIsDefined && valIsReflexive) ||
+            !othIsReflexive) {
+          return -1;
+        }
+      }
+      return 0;
+    }
+
+    /**
+     * Used by `_.orderBy` to compare multiple properties of a value to another
+     * and stable sort them.
+     *
+     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
+     * specify an order of "desc" for descending or "asc" for ascending sort order
+     * of corresponding values.
+     *
+     * @private
+     * @param {Object} object The object to compare.
+     * @param {Object} other The other object to compare.
+     * @param {boolean[]|string[]} orders The order to sort by for each property.
+     * @returns {number} Returns the sort order indicator for `object`.
+     */
+    function compareMultiple(object, other, orders) {
+      var index = -1,
+          objCriteria = object.criteria,
+          othCriteria = other.criteria,
+          length = objCriteria.length,
+          ordersLength = orders.length;
+
+      while (++index < length) {
+        var result = compareAscending(objCriteria[index], othCriteria[index]);
+        if (result) {
+          if (index >= ordersLength) {
+            return result;
+          }
+          var order = orders[index];
+          return result * (order == 'desc' ? -1 : 1);
+        }
+      }
+      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
+      // that causes it, under certain circumstances, to provide the same value for
+      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
+      // for more details.
+      //
+      // This also ensures a stable sort in V8 and other engines.
+      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
+      return object.index - other.index;
+    }
+
+    /**
+     * Creates an array that is the composition of partially applied arguments,
+     * placeholders, and provided arguments into a single array of arguments.
+     *
+     * @private
+     * @param {Array} args The provided arguments.
+     * @param {Array} partials The arguments to prepend to those provided.
+     * @param {Array} holders The `partials` placeholder indexes.
+     * @params {boolean} [isCurried] Specify composing for a curried function.
+     * @returns {Array} Returns the new array of composed arguments.
+     */
+    function composeArgs(args, partials, holders, isCurried) {
+      var argsIndex = -1,
+          argsLength = args.length,
+          holdersLength = holders.length,
+          leftIndex = -1,
+          leftLength = partials.length,
+          rangeLength = nativeMax(argsLength - holdersLength, 0),
+          result = Array(leftLength + rangeLength),
+          isUncurried = !isCurried;
+
+      while (++leftIndex < leftLength) {
+        result[leftIndex] = partials[leftIndex];
+      }
+      while (++argsIndex < holdersLength) {
+        if (isUncurried || argsIndex < argsLength) {
+          result[holders[argsIndex]] = args[argsIndex];
+        }
+      }
+      while (rangeLength--) {
+        result[leftIndex++] = args[argsIndex++];
+      }
+      return result;
+    }
+
+    /**
+     * This function is like `composeArgs` except that the arguments composition
+     * is tailored for `_.partialRight`.
+     *
+     * @private
+     * @param {Array} args The provided arguments.
+     * @param {Array} partials The arguments to append to those provided.
+     * @param {Array} holders The `partials` placeholder indexes.
+     * @params {boolean} [isCurried] Specify composing for a curried function.
+     * @returns {Array} Returns the new array of composed arguments.
+     */
+    function composeArgsRight(args, partials, holders, isCurried) {
+      var argsIndex = -1,
+          argsLength = args.length,
+          holdersIndex = -1,
+          holdersLength = holders.length,
+          rightIndex = -1,
+          rightLength = partials.length,
+          rangeLength = nativeMax(argsLength - holdersLength, 0),
+          result = Array(rangeLength + rightLength),
+          isUncurried = !isCurried;
+
+      while (++argsIndex < rangeLength) {
+        result[argsIndex] = args[argsIndex];
+      }
+      var offset = argsIndex;
+      while (++rightIndex < rightLength) {
+        result[offset + rightIndex] = partials[rightIndex];
+      }
+      while (++holdersIndex < holdersLength) {
+        if (isUncurried || argsIndex < argsLength) {
+          result[offset + holders[holdersIndex]] = args[argsIndex++];
+        }
+      }
+      return result;
+    }
+
+    /**
+     * Copies the values of `source` to `array`.
+     *
+     * @private
+     * @param {Array} source The array to copy values from.
+     * @param {Array} [array=[]] The array to copy values to.
+     * @returns {Array} Returns `array`.
+     */
+    function copyArray(source, array) {
+      var index = -1,
+          length = source.length;
+
+      array || (array = Array(length));
+      while (++index < length) {
+        array[index] = source[index];
+      }
+      return array;
+    }
+
+    /**
+     * Copies properties of `source` to `object`.
+     *
+     * @private
+     * @param {Object} source The object to copy properties from.
+     * @param {Array} props The property identifiers to copy.
+     * @param {Object} [object={}] The object to copy properties to.
+     * @param {Function} [customizer] The function to customize copied values.
+     * @returns {Object} Returns `object`.
+     */
+    function copyObject(source, props, object, customizer) {
+      var isNew = !object;
+      object || (object = {});
+
+      var index = -1,
+          length = props.length;
+
+      while (++index < length) {
+        var key = props[index];
+
+        var newValue = customizer
+          ? customizer(object[key], source[key], key, object, source)
+          : undefined;
+
+        if (newValue === undefined) {
+          newValue = source[key];
+        }
+        if (isNew) {
+          baseAssignValue(object, key, newValue);
+        } else {
+          assignValue(object, key, newValue);
+        }
+      }
+      return object;
+    }
+
+    /**
+     * Copies own symbols of `source` to `object`.
+     *
+     * @private
+     * @param {Object} source The object to copy symbols from.
+     * @param {Object} [object={}] The object to copy symbols to.
+     * @returns {Object} Returns `object`.
+     */
+    function copySymbols(source, object) {
+      return copyObject(source, getSymbols(source), object);
+    }
+
+    /**
+     * Copies own and inherited symbols of `source` to `object`.
+     *
+     * @private
+     * @param {Object} source The object to copy symbols from.
+     * @param {Object} [object={}] The object to copy symbols to.
+     * @returns {Object} Returns `object`.
+     */
+    function copySymbolsIn(source, object) {
+      return copyObject(source, getSymbolsIn(source), object);
+    }
+
+    /**
+     * Creates a function like `_.groupBy`.
+     *
+     * @private
+     * @param {Function} setter The function to set accumulator values.
+     * @param {Function} [initializer] The accumulator object initializer.
+     * @returns {Function} Returns the new aggregator function.
+     */
+    function createAggregator(setter, initializer) {
+      return function(collection, iteratee) {
+        var func = isArray(collection) ? arrayAggregator : baseAggregator,
+            accumulator = initializer ? initializer() : {};
+
+        return func(collection, setter, getIteratee(iteratee, 2), accumulator);
+      };
+    }
+
+    /**
+     * Creates a function like `_.assign`.
+     *
+     * @private
+     * @param {Function} assigner The function to assign values.
+     * @returns {Function} Returns the new assigner function.
+     */
+    function createAssigner(assigner) {
+      return baseRest(function(object, sources) {
+        var index = -1,
+            length = sources.length,
+            customizer = length > 1 ? sources[length - 1] : undefined,
+            guard = length > 2 ? sources[2] : undefined;
+
+        customizer = (assigner.length > 3 && typeof customizer == 'function')
+          ? (length--, customizer)
+          : undefined;
+
+        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
+          customizer = length < 3 ? undefined : customizer;
+          length = 1;
+        }
+        object = Object(object);
+        while (++index < length) {
+          var source = sources[index];
+          if (source) {
+            assigner(object, source, index, customizer);
+          }
+        }
+        return object;
+      });
+    }
+
+    /**
+     * Creates a `baseEach` or `baseEachRight` function.
+     *
+     * @private
+     * @param {Function} eachFunc The function to iterate over a collection.
+     * @param {boolean} [fromRight] Specify iterating from right to left.
+     * @returns {Function} Returns the new base function.
+     */
+    function createBaseEach(eachFunc, fromRight) {
+      return function(collection, iteratee) {
+        if (collection == null) {
+          return collection;
+        }
+        if (!isArrayLike(collection)) {
+          return eachFunc(collection, iteratee);
+        }
+        var length = collection.length,
+            index = fromRight ? length : -1,
+            iterable = Object(collection);
+
+        while ((fromRight ? index-- : ++index < length)) {
+          if (iteratee(iterable[index], index, iterable) === false) {
+            break;
+          }
+        }
+        return collection;
+      };
+    }
+
+    /**
+     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
+     *
+     * @private
+     * @param {boolean} [fromRight] Specify iterating from right to left.
+     * @returns {Function} Returns the new base function.
+     */
+    function createBaseFor(fromRight) {
+      return function(object, iteratee, keysFunc) {
+        var index = -1,
+            iterable = Object(object),
+            props = keysFunc(object),
+            length = props.length;
+
+        while (length--) {
+          var key = props[fromRight ? length : ++index];
+          if (iteratee(iterable[key], key, iterable) === false) {
+            break;
+          }
+        }
+        return object;
+      };
+    }
+
+    /**
+     * Creates a function that wraps `func` to invoke it with the optional `this`
+     * binding of `thisArg`.
+     *
+     * @private
+     * @param {Function} func The function to wrap.
+     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+     * @param {*} [thisArg] The `this` binding of `func`.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createBind(func, bitmask, thisArg) {
+      var isBind = bitmask & WRAP_BIND_FLAG,
+          Ctor = createCtor(func);
+
+      function wrapper() {
+        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+        return fn.apply(isBind ? thisArg : this, arguments);
+      }
+      return wrapper;
+    }
+
+    /**
+     * Creates a function like `_.lowerFirst`.
+     *
+     * @private
+     * @param {string} methodName The name of the `String` case method to use.
+     * @returns {Function} Returns the new case function.
+     */
+    function createCaseFirst(methodName) {
+      return function(string) {
+        string = toString(string);
+
+        var strSymbols = hasUnicode(string)
+          ? stringToArray(string)
+          : undefined;
+
+        var chr = strSymbols
+          ? strSymbols[0]
+          : string.charAt(0);
+
+        var trailing = strSymbols
+          ? castSlice(strSymbols, 1).join('')
+          : string.slice(1);
+
+        return chr[methodName]() + trailing;
+      };
+    }
+
+    /**
+     * Creates a function like `_.camelCase`.
+     *
+     * @private
+     * @param {Function} callback The function to combine each word.
+     * @returns {Function} Returns the new compounder function.
+     */
+    function createCompounder(callback) {
+      return function(string) {
+        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
+      };
+    }
+
+    /**
+     * Creates a function that produces an instance of `Ctor` regardless of
+     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
+     *
+     * @private
+     * @param {Function} Ctor The constructor to wrap.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createCtor(Ctor) {
+      return function() {
+        // Use a `switch` statement to work with class constructors. See
+        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+        // for more details.
+        var args = arguments;
+        switch (args.length) {
+          case 0: return new Ctor;
+          case 1: return new Ctor(args[0]);
+          case 2: return new Ctor(args[0], args[1]);
+          case 3: return new Ctor(args[0], args[1], args[2]);
+          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
+          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
+          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
+          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
+        }
+        var thisBinding = baseCreate(Ctor.prototype),
+            result = Ctor.apply(thisBinding, args);
+
+        // Mimic the constructor's `return` behavior.
+        // See https://es5.github.io/#x13.2.2 for more details.
+        return isObject(result) ? result : thisBinding;
+      };
+    }
+
+    /**
+     * Creates a function that wraps `func` to enable currying.
+     *
+     * @private
+     * @param {Function} func The function to wrap.
+     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+     * @param {number} arity The arity of `func`.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createCurry(func, bitmask, arity) {
+      var Ctor = createCtor(func);
+
+      function wrapper() {
+        var length = arguments.length,
+            args = Array(length),
+            index = length,
+            placeholder = getHolder(wrapper);
+
+        while (index--) {
+          args[index] = arguments[index];
+        }
+        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
+          ? []
+          : replaceHolders(args, placeholder);
+
+        length -= holders.length;
+        if (length < arity) {
+          return createRecurry(
+            func, bitmask, createHybrid, wrapper.placeholder, undefined,
+            args, holders, undefined, undefined, arity - length);
+        }
+        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+        return apply(fn, this, args);
+      }
+      return wrapper;
+    }
+
+    /**
+     * Creates a `_.find` or `_.findLast` function.
+     *
+     * @private
+     * @param {Function} findIndexFunc The function to find the collection index.
+     * @returns {Function} Returns the new find function.
+     */
+    function createFind(findIndexFunc) {
+      return function(collection, predicate, fromIndex) {
+        var iterable = Object(collection);
+        if (!isArrayLike(collection)) {
+          var iteratee = getIteratee(predicate, 3);
+          collection = keys(collection);
+          predicate = function(key) { return iteratee(iterable[key], key, iterable); };
+        }
+        var index = findIndexFunc(collection, predicate, fromIndex);
+        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
+      };
+    }
+
+    /**
+     * Creates a `_.flow` or `_.flowRight` function.
+     *
+     * @private
+     * @param {boolean} [fromRight] Specify iterating from right to left.
+     * @returns {Function} Returns the new flow function.
+     */
+    function createFlow(fromRight) {
+      return flatRest(function(funcs) {
+        var length = funcs.length,
+            index = length,
+            prereq = LodashWrapper.prototype.thru;
+
+        if (fromRight) {
+          funcs.reverse();
+        }
+        while (index--) {
+          var func = funcs[index];
+          if (typeof func != 'function') {
+            throw new TypeError(FUNC_ERROR_TEXT);
+          }
+          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
+            var wrapper = new LodashWrapper([], true);
+          }
+        }
+        index = wrapper ? index : length;
+        while (++index < length) {
+          func = funcs[index];
+
+          var funcName = getFuncName(func),
+              data = funcName == 'wrapper' ? getData(func) : undefined;
+
+          if (data && isLaziable(data[0]) &&
+                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
+                !data[4].length && data[9] == 1
+              ) {
+            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
+          } else {
+            wrapper = (func.length == 1 && isLaziable(func))
+              ? wrapper[funcName]()
+              : wrapper.thru(func);
+          }
+        }
+        return function() {
+          var args = arguments,
+              value = args[0];
+
+          if (wrapper && args.length == 1 && isArray(value)) {
+            return wrapper.plant(value).value();
+          }
+          var index = 0,
+              result = length ? funcs[index].apply(this, args) : value;
+
+          while (++index < length) {
+            result = funcs[index].call(this, result);
+          }
+          return result;
+        };
+      });
+    }
+
+    /**
+     * Creates a function that wraps `func` to invoke it with optional `this`
+     * binding of `thisArg`, partial application, and currying.
+     *
+     * @private
+     * @param {Function|string} func The function or method name to wrap.
+     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+     * @param {*} [thisArg] The `this` binding of `func`.
+     * @param {Array} [partials] The arguments to prepend to those provided to
+     *  the new function.
+     * @param {Array} [holders] The `partials` placeholder indexes.
+     * @param {Array} [partialsRight] The arguments to append to those provided
+     *  to the new function.
+     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
+     * @param {Array} [argPos] The argument positions of the new function.
+     * @param {number} [ary] The arity cap of `func`.
+     * @param {number} [arity] The arity of `func`.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
+      var isAry = bitmask & WRAP_ARY_FLAG,
+          isBind = bitmask & WRAP_BIND_FLAG,
+          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
+          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
+          isFlip = bitmask & WRAP_FLIP_FLAG,
+          Ctor = isBindKey ? undefined : createCtor(func);
+
+      function wrapper() {
+        var length = arguments.length,
+            args = Array(length),
+            index = length;
+
+        while (index--) {
+          args[index] = arguments[index];
+        }
+        if (isCurried) {
+          var placeholder = getHolder(wrapper),
+              holdersCount = countHolders(args, placeholder);
+        }
+        if (partials) {
+          args = composeArgs(args, partials, holders, isCurried);
+        }
+        if (partialsRight) {
+          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
+        }
+        length -= holdersCount;
+        if (isCurried && length < arity) {
+          var newHolders = replaceHolders(args, placeholder);
+          return createRecurry(
+            func, bitmask, createHybrid, wrapper.placeholder, thisArg,
+            args, newHolders, argPos, ary, arity - length
+          );
+        }
+        var thisBinding = isBind ? thisArg : this,
+            fn = isBindKey ? thisBinding[func] : func;
+
+        length = args.length;
+        if (argPos) {
+          args = reorder(args, argPos);
+        } else if (isFlip && length > 1) {
+          args.reverse();
+        }
+        if (isAry && ary < length) {
+          args.length = ary;
+        }
+        if (this && this !== root && this instanceof wrapper) {
+          fn = Ctor || createCtor(fn);
+        }
+        return fn.apply(thisBinding, args);
+      }
+      return wrapper;
+    }
+
+    /**
+     * Creates a function like `_.invertBy`.
+     *
+     * @private
+     * @param {Function} setter The function to set accumulator values.
+     * @param {Function} toIteratee The function to resolve iteratees.
+     * @returns {Function} Returns the new inverter function.
+     */
+    function createInverter(setter, toIteratee) {
+      return function(object, iteratee) {
+        return baseInverter(object, setter, toIteratee(iteratee), {});
+      };
+    }
+
+    /**
+     * Creates a function that performs a mathematical operation on two values.
+     *
+     * @private
+     * @param {Function} operator The function to perform the operation.
+     * @param {number} [defaultValue] The value used for `undefined` arguments.
+     * @returns {Function} Returns the new mathematical operation function.
+     */
+    function createMathOperation(operator, defaultValue) {
+      return function(value, other) {
+        var result;
+        if (value === undefined && other === undefined) {
+          return defaultValue;
+        }
+        if (value !== undefined) {
+          result = value;
+        }
+        if (other !== undefined) {
+          if (result === undefined) {
+            return other;
+          }
+          if (typeof value == 'string' || typeof other == 'string') {
+            value = baseToString(value);
+            other = baseToString(other);
+          } else {
+            value = baseToNumber(value);
+            other = baseToNumber(other);
+          }
+          result = operator(value, other);
+        }
+        return result;
+      };
+    }
+
+    /**
+     * Creates a function like `_.over`.
+     *
+     * @private
+     * @param {Function} arrayFunc The function to iterate over iteratees.
+     * @returns {Function} Returns the new over function.
+     */
+    function createOver(arrayFunc) {
+      return flatRest(function(iteratees) {
+        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
+        return baseRest(function(args) {
+          var thisArg = this;
+          return arrayFunc(iteratees, function(iteratee) {
+            return apply(iteratee, thisArg, args);
+          });
+        });
+      });
+    }
+
+    /**
+     * Creates the padding for `string` based on `length`. The `chars` string
+     * is truncated if the number of characters exceeds `length`.
+     *
+     * @private
+     * @param {number} length The padding length.
+     * @param {string} [chars=' '] The string used as padding.
+     * @returns {string} Returns the padding for `string`.
+     */
+    function createPadding(length, chars) {
+      chars = chars === undefined ? ' ' : baseToString(chars);
+
+      var charsLength = chars.length;
+      if (charsLength < 2) {
+        return charsLength ? baseRepeat(chars, length) : chars;
+      }
+      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
+      return hasUnicode(chars)
+        ? castSlice(stringToArray(result), 0, length).join('')
+        : result.slice(0, length);
+    }
+
+    /**
+     * Creates a function that wraps `func` to invoke it with the `this` binding
+     * of `thisArg` and `partials` prepended to the arguments it receives.
+     *
+     * @private
+     * @param {Function} func The function to wrap.
+     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+     * @param {*} thisArg The `this` binding of `func`.
+     * @param {Array} partials The arguments to prepend to those provided to
+     *  the new function.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createPartial(func, bitmask, thisArg, partials) {
+      var isBind = bitmask & WRAP_BIND_FLAG,
+          Ctor = createCtor(func);
+
+      function wrapper() {
+        var argsIndex = -1,
+            argsLength = arguments.length,
+            leftIndex = -1,
+            leftLength = partials.length,
+            args = Array(leftLength + argsLength),
+            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+
+        while (++leftIndex < leftLength) {
+          args[leftIndex] = partials[leftIndex];
+        }
+        while (argsLength--) {
+          args[leftIndex++] = arguments[++argsIndex];
+        }
+        return apply(fn, isBind ? thisArg : this, args);
+      }
+      return wrapper;
+    }
+
+    /**
+     * Creates a `_.range` or `_.rangeRight` function.
+     *
+     * @private
+     * @param {boolean} [fromRight] Specify iterating from right to left.
+     * @returns {Function} Returns the new range function.
+     */
+    function createRange(fromRight) {
+      return function(start, end, step) {
+        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
+          end = step = undefined;
+        }
+        // Ensure the sign of `-0` is preserved.
+        start = toFinite(start);
+        if (end === undefined) {
+          end = start;
+          start = 0;
+        } else {
+          end = toFinite(end);
+        }
+        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
+        return baseRange(start, end, step, fromRight);
+      };
+    }
+
+    /**
+     * Creates a function that performs a relational operation on two values.
+     *
+     * @private
+     * @param {Function} operator The function to perform the operation.
+     * @returns {Function} Returns the new relational operation function.
+     */
+    function createRelationalOperation(operator) {
+      return function(value, other) {
+        if (!(typeof value == 'string' && typeof other == 'string')) {
+          value = toNumber(value);
+          other = toNumber(other);
+        }
+        return operator(value, other);
+      };
+    }
+
+    /**
+     * Creates a function that wraps `func` to continue currying.
+     *
+     * @private
+     * @param {Function} func The function to wrap.
+     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+     * @param {Function} wrapFunc The function to create the `func` wrapper.
+     * @param {*} placeholder The placeholder value.
+     * @param {*} [thisArg] The `this` binding of `func`.
+     * @param {Array} [partials] The arguments to prepend to those provided to
+     *  the new function.
+     * @param {Array} [holders] The `partials` placeholder indexes.
+     * @param {Array} [argPos] The argument positions of the new function.
+     * @param {number} [ary] The arity cap of `func`.
+     * @param {number} [arity] The arity of `func`.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
+      var isCurry = bitmask & WRAP_CURRY_FLAG,
+          newHolders = isCurry ? holders : undefined,
+          newHoldersRight = isCurry ? undefined : holders,
+          newPartials = isCurry ? partials : undefined,
+          newPartialsRight = isCurry ? undefined : partials;
+
+      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
+      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
+
+      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
+        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
+      }
+      var newData = [
+        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
+        newHoldersRight, argPos, ary, arity
+      ];
+
+      var result = wrapFunc.apply(undefined, newData);
+      if (isLaziable(func)) {
+        setData(result, newData);
+      }
+      result.placeholder = placeholder;
+      return setWrapToString(result, func, bitmask);
+    }
+
+    /**
+     * Creates a function like `_.round`.
+     *
+     * @private
+     * @param {string} methodName The name of the `Math` method to use when rounding.
+     * @returns {Function} Returns the new round function.
+     */
+    function createRound(methodName) {
+      var func = Math[methodName];
+      return function(number, precision) {
+        number = toNumber(number);
+        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
+        if (precision) {
+          // Shift with exponential notation to avoid floating-point issues.
+          // See [MDN](https://mdn.io/round#Examples) for more details.
+          var pair = (toString(number) + 'e').split('e'),
+              value = func(pair[0] + 'e' + (+pair[1] + precision));
+
+          pair = (toString(value) + 'e').split('e');
+          return +(pair[0] + 'e' + (+pair[1] - precision));
+        }
+        return func(number);
+      };
+    }
+
+    /**
+     * Creates a set object of `values`.
+     *
+     * @private
+     * @param {Array} values The values to add to the set.
+     * @returns {Object} Returns the new set.
+     */
+    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
+      return new Set(values);
+    };
+
+    /**
+     * Creates a `_.toPairs` or `_.toPairsIn` function.
+     *
+     * @private
+     * @param {Function} keysFunc The function to get the keys of a given object.
+     * @returns {Function} Returns the new pairs function.
+     */
+    function createToPairs(keysFunc) {
+      return function(object) {
+        var tag = getTag(object);
+        if (tag == mapTag) {
+          return mapToArray(object);
+        }
+        if (tag == setTag) {
+          return setToPairs(object);
+        }
+        return baseToPairs(object, keysFunc(object));
+      };
+    }
+
+    /**
+     * Creates a function that either curries or invokes `func` with optional
+     * `this` binding and partially applied arguments.
+     *
+     * @private
+     * @param {Function|string} func The function or method name to wrap.
+     * @param {number} bitmask The bitmask flags.
+     *    1 - `_.bind`
+     *    2 - `_.bindKey`
+     *    4 - `_.curry` or `_.curryRight` of a bound function
+     *    8 - `_.curry`
+     *   16 - `_.curryRight`
+     *   32 - `_.partial`
+     *   64 - `_.partialRight`
+     *  128 - `_.rearg`
+     *  256 - `_.ary`
+     *  512 - `_.flip`
+     * @param {*} [thisArg] The `this` binding of `func`.
+     * @param {Array} [partials] The arguments to be partially applied.
+     * @param {Array} [holders] The `partials` placeholder indexes.
+     * @param {Array} [argPos] The argument positions of the new function.
+     * @param {number} [ary] The arity cap of `func`.
+     * @param {number} [arity] The arity of `func`.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
+      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
+      if (!isBindKey && typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      var length = partials ? partials.length : 0;
+      if (!length) {
+        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
+        partials = holders = undefined;
+      }
+      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
+      arity = arity === undefined ? arity : toInteger(arity);
+      length -= holders ? holders.length : 0;
+
+      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
+        var partialsRight = partials,
+            holdersRight = holders;
+
+        partials = holders = undefined;
+      }
+      var data = isBindKey ? undefined : getData(func);
+
+      var newData = [
+        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
+        argPos, ary, arity
+      ];
+
+      if (data) {
+        mergeData(newData, data);
+      }
+      func = newData[0];
+      bitmask = newData[1];
+      thisArg = newData[2];
+      partials = newData[3];
+      holders = newData[4];
+      arity = newData[9] = newData[9] === undefined
+        ? (isBindKey ? 0 : func.length)
+        : nativeMax(newData[9] - length, 0);
+
+      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
+        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
+      }
+      if (!bitmask || bitmask == WRAP_BIND_FLAG) {
+        var result = createBind(func, bitmask, thisArg);
+      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
+        result = createCurry(func, bitmask, arity);
+      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
+        result = createPartial(func, bitmask, thisArg, partials);
+      } else {
+        result = createHybrid.apply(undefined, newData);
+      }
+      var setter = data ? baseSetData : setData;
+      return setWrapToString(setter(result, newData), func, bitmask);
+    }
+
+    /**
+     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
+     * of source objects to the destination object for all destination properties
+     * that resolve to `undefined`.
+     *
+     * @private
+     * @param {*} objValue The destination value.
+     * @param {*} srcValue The source value.
+     * @param {string} key The key of the property to assign.
+     * @param {Object} object The parent object of `objValue`.
+     * @returns {*} Returns the value to assign.
+     */
+    function customDefaultsAssignIn(objValue, srcValue, key, object) {
+      if (objValue === undefined ||
+          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
+        return srcValue;
+      }
+      return objValue;
+    }
+
+    /**
+     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
+     * objects into destination objects that are passed thru.
+     *
+     * @private
+     * @param {*} objValue The destination value.
+     * @param {*} srcValue The source value.
+     * @param {string} key The key of the property to merge.
+     * @param {Object} object The parent object of `objValue`.
+     * @param {Object} source The parent object of `srcValue`.
+     * @param {Object} [stack] Tracks traversed source values and their merged
+     *  counterparts.
+     * @returns {*} Returns the value to assign.
+     */
+    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
+      if (isObject(objValue) && isObject(srcValue)) {
+        // Recursively merge objects and arrays (susceptible to call stack limits).
+        stack.set(srcValue, objValue);
+        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
+        stack['delete'](srcValue);
+      }
+      return objValue;
+    }
+
+    /**
+     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
+     * objects.
+     *
+     * @private
+     * @param {*} value The value to inspect.
+     * @param {string} key The key of the property to inspect.
+     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
+     */
+    function customOmitClone(value) {
+      return isPlainObject(value) ? undefined : value;
+    }
+
+    /**
+     * A specialized version of `baseIsEqualDeep` for arrays with support for
+     * partial deep comparisons.
+     *
+     * @private
+     * @param {Array} array The array to compare.
+     * @param {Array} other The other array to compare.
+     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {Function} equalFunc The function to determine equivalents of values.
+     * @param {Object} stack Tracks traversed `array` and `other` objects.
+     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+     */
+    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
+      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
+          arrLength = array.length,
+          othLength = other.length;
+
+      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
+        return false;
+      }
+      // Assume cyclic values are equal.
+      var stacked = stack.get(array);
+      if (stacked && stack.get(other)) {
+        return stacked == other;
+      }
+      var index = -1,
+          result = true,
+          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
+
+      stack.set(array, other);
+      stack.set(other, array);
+
+      // Ignore non-index properties.
+      while (++index < arrLength) {
+        var arrValue = array[index],
+            othValue = other[index];
+
+        if (customizer) {
+          var compared = isPartial
+            ? customizer(othValue, arrValue, index, other, array, stack)
+            : customizer(arrValue, othValue, index, array, other, stack);
+        }
+        if (compared !== undefined) {
+          if (compared) {
+            continue;
+          }
+          result = false;
+          break;
+        }
+        // Recursively compare arrays (susceptible to call stack limits).
+        if (seen) {
+          if (!arraySome(other, function(othValue, othIndex) {
+                if (!cacheHas(seen, othIndex) &&
+                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
+                  return seen.push(othIndex);
+                }
+              })) {
+            result = false;
+            break;
+          }
+        } else if (!(
+              arrValue === othValue ||
+                equalFunc(arrValue, othValue, bitmask, customizer, stack)
+            )) {
+          result = false;
+          break;
+        }
+      }
+      stack['delete'](array);
+      stack['delete'](other);
+      return result;
+    }
+
+    /**
+     * A specialized version of `baseIsEqualDeep` for comparing objects of
+     * the same `toStringTag`.
+     *
+     * **Note:** This function only supports comparing values with tags of
+     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+     *
+     * @private
+     * @param {Object} object The object to compare.
+     * @param {Object} other The other object to compare.
+     * @param {string} tag The `toStringTag` of the objects to compare.
+     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {Function} equalFunc The function to determine equivalents of values.
+     * @param {Object} stack Tracks traversed `object` and `other` objects.
+     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+     */
+    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
+      switch (tag) {
+        case dataViewTag:
+          if ((object.byteLength != other.byteLength) ||
+              (object.byteOffset != other.byteOffset)) {
+            return false;
+          }
+          object = object.buffer;
+          other = other.buffer;
+
+        case arrayBufferTag:
+          if ((object.byteLength != other.byteLength) ||
+              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
+            return false;
+          }
+          return true;
+
+        case boolTag:
+        case dateTag:
+        case numberTag:
+          // Coerce booleans to `1` or `0` and dates to milliseconds.
+          // Invalid dates are coerced to `NaN`.
+          return eq(+object, +other);
+
+        case errorTag:
+          return object.name == other.name && object.message == other.message;
+
+        case regexpTag:
+        case stringTag:
+          // Coerce regexes to strings and treat strings, primitives and objects,
+          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
+          // for more details.
+          return object == (other + '');
+
+        case mapTag:
+          var convert = mapToArray;
+
+        case setTag:
+          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
+          convert || (convert = setToArray);
+
+          if (object.size != other.size && !isPartial) {
+            return false;
+          }
+          // Assume cyclic values are equal.
+          var stacked = stack.get(object);
+          if (stacked) {
+            return stacked == other;
+          }
+          bitmask |= COMPARE_UNORDERED_FLAG;
+
+          // Recursively compare objects (susceptible to call stack limits).
+          stack.set(object, other);
+          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
+          stack['delete'](object);
+          return result;
+
+        case symbolTag:
+          if (symbolValueOf) {
+            return symbolValueOf.call(object) == symbolValueOf.call(other);
+          }
+      }
+      return false;
+    }
+
+    /**
+     * A specialized version of `baseIsEqualDeep` for objects with support for
+     * partial deep comparisons.
+     *
+     * @private
+     * @param {Object} object The object to compare.
+     * @param {Object} other The other object to compare.
+     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {Function} equalFunc The function to determine equivalents of values.
+     * @param {Object} stack Tracks traversed `object` and `other` objects.
+     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+     */
+    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
+      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
+          objProps = getAllKeys(object),
+          objLength = objProps.length,
+          othProps = getAllKeys(other),
+          othLength = othProps.length;
+
+      if (objLength != othLength && !isPartial) {
+        return false;
+      }
+      var index = objLength;
+      while (index--) {
+        var key = objProps[index];
+        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
+          return false;
+        }
+      }
+      // Assume cyclic values are equal.
+      var stacked = stack.get(object);
+      if (stacked && stack.get(other)) {
+        return stacked == other;
+      }
+      var result = true;
+      stack.set(object, other);
+      stack.set(other, object);
+
+      var skipCtor = isPartial;
+      while (++index < objLength) {
+        key = objProps[index];
+        var objValue = object[key],
+            othValue = other[key];
+
+        if (customizer) {
+          var compared = isPartial
+            ? customizer(othValue, objValue, key, other, object, stack)
+            : customizer(objValue, othValue, key, object, other, stack);
+        }
+        // Recursively compare objects (susceptible to call stack limits).
+        if (!(compared === undefined
+              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
+              : compared
+            )) {
+          result = false;
+          break;
+        }
+        skipCtor || (skipCtor = key == 'constructor');
+      }
+      if (result && !skipCtor) {
+        var objCtor = object.constructor,
+            othCtor = other.constructor;
+
+        // Non `Object` object instances with different constructors are not equal.
+        if (objCtor != othCtor &&
+            ('constructor' in object && 'constructor' in other) &&
+            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
+              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
+          result = false;
+        }
+      }
+      stack['delete'](object);
+      stack['delete'](other);
+      return result;
+    }
+
+    /**
+     * A specialized version of `baseRest` which flattens the rest array.
+     *
+     * @private
+     * @param {Function} func The function to apply a rest parameter to.
+     * @returns {Function} Returns the new function.
+     */
+    function flatRest(func) {
+      return setToString(overRest(func, undefined, flatten), func + '');
+    }
+
+    /**
+     * Creates an array of own enumerable property names and symbols of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names and symbols.
+     */
+    function getAllKeys(object) {
+      return baseGetAllKeys(object, keys, getSymbols);
+    }
+
+    /**
+     * Creates an array of own and inherited enumerable property names and
+     * symbols of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names and symbols.
+     */
+    function getAllKeysIn(object) {
+      return baseGetAllKeys(object, keysIn, getSymbolsIn);
+    }
+
+    /**
+     * Gets metadata for `func`.
+     *
+     * @private
+     * @param {Function} func The function to query.
+     * @returns {*} Returns the metadata for `func`.
+     */
+    var getData = !metaMap ? noop : function(func) {
+      return metaMap.get(func);
+    };
+
+    /**
+     * Gets the name of `func`.
+     *
+     * @private
+     * @param {Function} func The function to query.
+     * @returns {string} Returns the function name.
+     */
+    function getFuncName(func) {
+      var result = (func.name + ''),
+          array = realNames[result],
+          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
+
+      while (length--) {
+        var data = array[length],
+            otherFunc = data.func;
+        if (otherFunc == null || otherFunc == func) {
+          return data.name;
+        }
+      }
+      return result;
+    }
+
+    /**
+     * Gets the argument placeholder value for `func`.
+     *
+     * @private
+     * @param {Function} func The function to inspect.
+     * @returns {*} Returns the placeholder value.
+     */
+    function getHolder(func) {
+      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
+      return object.placeholder;
+    }
+
+    /**
+     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
+     * this function returns the custom method, otherwise it returns `baseIteratee`.
+     * If arguments are provided, the chosen function is invoked with them and
+     * its result is returned.
+     *
+     * @private
+     * @param {*} [value] The value to convert to an iteratee.
+     * @param {number} [arity] The arity of the created iteratee.
+     * @returns {Function} Returns the chosen function or its result.
+     */
+    function getIteratee() {
+      var result = lodash.iteratee || iteratee;
+      result = result === iteratee ? baseIteratee : result;
+      return arguments.length ? result(arguments[0], arguments[1]) : result;
+    }
+
+    /**
+     * Gets the data for `map`.
+     *
+     * @private
+     * @param {Object} map The map to query.
+     * @param {string} key The reference key.
+     * @returns {*} Returns the map data.
+     */
+    function getMapData(map, key) {
+      var data = map.__data__;
+      return isKeyable(key)
+        ? data[typeof key == 'string' ? 'string' : 'hash']
+        : data.map;
+    }
+
+    /**
+     * Gets the property names, values, and compare flags of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the match data of `object`.
+     */
+    function getMatchData(object) {
+      var result = keys(object),
+          length = result.length;
+
+      while (length--) {
+        var key = result[length],
+            value = object[key];
+
+        result[length] = [key, value, isStrictComparable(value)];
+      }
+      return result;
+    }
+
+    /**
+     * Gets the native function at `key` of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @param {string} key The key of the method to get.
+     * @returns {*} Returns the function if it's native, else `undefined`.
+     */
+    function getNative(object, key) {
+      var value = getValue(object, key);
+      return baseIsNative(value) ? value : undefined;
+    }
+
+    /**
+     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
+     *
+     * @private
+     * @param {*} value The value to query.
+     * @returns {string} Returns the raw `toStringTag`.
+     */
+    function getRawTag(value) {
+      var isOwn = hasOwnProperty.call(value, symToStringTag),
+          tag = value[symToStringTag];
+
+      try {
+        value[symToStringTag] = undefined;
+        var unmasked = true;
+      } catch (e) {}
+
+      var result = nativeObjectToString.call(value);
+      if (unmasked) {
+        if (isOwn) {
+          value[symToStringTag] = tag;
+        } else {
+          delete value[symToStringTag];
+        }
+      }
+      return result;
+    }
+
+    /**
+     * Creates an array of the own enumerable symbols of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of symbols.
+     */
+    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
+      if (object == null) {
+        return [];
+      }
+      object = Object(object);
+      return arrayFilter(nativeGetSymbols(object), function(symbol) {
+        return propertyIsEnumerable.call(object, symbol);
+      });
+    };
+
+    /**
+     * Creates an array of the own and inherited enumerable symbols of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of symbols.
+     */
+    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
+      var result = [];
+      while (object) {
+        arrayPush(result, getSymbols(object));
+        object = getPrototype(object);
+      }
+      return result;
+    };
+
+    /**
+     * Gets the `toStringTag` of `value`.
+     *
+     * @private
+     * @param {*} value The value to query.
+     * @returns {string} Returns the `toStringTag`.
+     */
+    var getTag = baseGetTag;
+
+    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
+    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
+        (Map && getTag(new Map) != mapTag) ||
+        (Promise && getTag(Promise.resolve()) != promiseTag) ||
+        (Set && getTag(new Set) != setTag) ||
+        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
+      getTag = function(value) {
+        var result = baseGetTag(value),
+            Ctor = result == objectTag ? value.constructor : undefined,
+            ctorString = Ctor ? toSource(Ctor) : '';
+
+        if (ctorString) {
+          switch (ctorString) {
+            case dataViewCtorString: return dataViewTag;
+            case mapCtorString: return mapTag;
+            case promiseCtorString: return promiseTag;
+            case setCtorString: return setTag;
+            case weakMapCtorString: return weakMapTag;
+          }
+        }
+        return result;
+      };
+    }
+
+    /**
+     * Gets the view, applying any `transforms` to the `start` and `end` positions.
+     *
+     * @private
+     * @param {number} start The start of the view.
+     * @param {number} end The end of the view.
+     * @param {Array} transforms The transformations to apply to the view.
+     * @returns {Object} Returns an object containing the `start` and `end`
+     *  positions of the view.
+     */
+    function getView(start, end, transforms) {
+      var index = -1,
+          length = transforms.length;
+
+      while (++index < length) {
+        var data = transforms[index],
+            size = data.size;
+
+        switch (data.type) {
+          case 'drop':      start += size; break;
+          case 'dropRight': end -= size; break;
+          case 'take':      end = nativeMin(end, start + size); break;
+          case 'takeRight': start = nativeMax(start, end - size); break;
+        }
+      }
+      return { 'start': start, 'end': end };
+    }
+
+    /**
+     * Extracts wrapper details from the `source` body comment.
+     *
+     * @private
+     * @param {string} source The source to inspect.
+     * @returns {Array} Returns the wrapper details.
+     */
+    function getWrapDetails(source) {
+      var match = source.match(reWrapDetails);
+      return match ? match[1].split(reSplitDetails) : [];
+    }
+
+    /**
+     * Checks if `path` exists on `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @param {Array|string} path The path to check.
+     * @param {Function} hasFunc The function to check properties.
+     * @returns {boolean} Returns `true` if `path` exists, else `false`.
+     */
+    function hasPath(object, path, hasFunc) {
+      path = castPath(path, object);
+
+      var index = -1,
+          length = path.length,
+          result = false;
+
+      while (++index < length) {
+        var key = toKey(path[index]);
+        if (!(result = object != null && hasFunc(object, key))) {
+          break;
+        }
+        object = object[key];
+      }
+      if (result || ++index != length) {
+        return result;
+      }
+      length = object == null ? 0 : object.length;
+      return !!length && isLength(length) && isIndex(key, length) &&
+        (isArray(object) || isArguments(object));
+    }
+
+    /**
+     * Initializes an array clone.
+     *
+     * @private
+     * @param {Array} array The array to clone.
+     * @returns {Array} Returns the initialized clone.
+     */
+    function initCloneArray(array) {
+      var length = array.length,
+          result = array.constructor(length);
+
+      // Add properties assigned by `RegExp#exec`.
+      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
+        result.index = array.index;
+        result.input = array.input;
+      }
+      return result;
+    }
+
+    /**
+     * Initializes an object clone.
+     *
+     * @private
+     * @param {Object} object The object to clone.
+     * @returns {Object} Returns the initialized clone.
+     */
+    function initCloneObject(object) {
+      return (typeof object.constructor == 'function' && !isPrototype(object))
+        ? baseCreate(getPrototype(object))
+        : {};
+    }
+
+    /**
+     * Initializes an object clone based on its `toStringTag`.
+     *
+     * **Note:** This function only supports cloning values with tags of
+     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+     *
+     * @private
+     * @param {Object} object The object to clone.
+     * @param {string} tag The `toStringTag` of the object to clone.
+     * @param {Function} cloneFunc The function to clone values.
+     * @param {boolean} [isDeep] Specify a deep clone.
+     * @returns {Object} Returns the initialized clone.
+     */
+    function initCloneByTag(object, tag, cloneFunc, isDeep) {
+      var Ctor = object.constructor;
+      switch (tag) {
+        case arrayBufferTag:
+          return cloneArrayBuffer(object);
+
+        case boolTag:
+        case dateTag:
+          return new Ctor(+object);
+
+        case dataViewTag:
+          return cloneDataView(object, isDeep);
+
+        case float32Tag: case float64Tag:
+        case int8Tag: case int16Tag: case int32Tag:
+        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
+          return cloneTypedArray(object, isDeep);
+
+        case mapTag:
+          return cloneMap(object, isDeep, cloneFunc);
+
+        case numberTag:
+        case stringTag:
+          return new Ctor(object);
+
+        case regexpTag:
+          return cloneRegExp(object);
+
+        case setTag:
+          return cloneSet(object, isDeep, cloneFunc);
+
+        case symbolTag:
+          return cloneSymbol(object);
+      }
+    }
+
+    /**
+     * Inserts wrapper `details` in a comment at the top of the `source` body.
+     *
+     * @private
+     * @param {string} source The source to modify.
+     * @returns {Array} details The details to insert.
+     * @returns {string} Returns the modified source.
+     */
+    function insertWrapDetails(source, details) {
+      var length = details.length;
+      if (!length) {
+        return source;
+      }
+      var lastIndex = length - 1;
+      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
+      details = details.join(length > 2 ? ', ' : ' ');
+      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
+    }
+
+    /**
+     * Checks if `value` is a flattenable `arguments` object or array.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
+     */
+    function isFlattenable(value) {
+      return isArray(value) || isArguments(value) ||
+        !!(spreadableSymbol && value && value[spreadableSymbol]);
+    }
+
+    /**
+     * Checks if `value` is a valid array-like index.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+     */
+    function isIndex(value, length) {
+      length = length == null ? MAX_SAFE_INTEGER : length;
+      return !!length &&
+        (typeof value == 'number' || reIsUint.test(value)) &&
+        (value > -1 && value % 1 == 0 && value < length);
+    }
+
+    /**
+     * Checks if the given arguments are from an iteratee call.
+     *
+     * @private
+     * @param {*} value The potential iteratee value argument.
+     * @param {*} index The potential iteratee index or key argument.
+     * @param {*} object The potential iteratee object argument.
+     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
+     *  else `false`.
+     */
+    function isIterateeCall(value, index, object) {
+      if (!isObject(object)) {
+        return false;
+      }
+      var type = typeof index;
+      if (type == 'number'
+            ? (isArrayLike(object) && isIndex(index, object.length))
+            : (type == 'string' && index in object)
+          ) {
+        return eq(object[index], value);
+      }
+      return false;
+    }
+
+    /**
+     * Checks if `value` is a property name and not a property path.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @param {Object} [object] The object to query keys on.
+     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+     */
+    function isKey(value, object) {
+      if (isArray(value)) {
+        return false;
+      }
+      var type = typeof value;
+      if (type == 'number' || type == 'symbol' || type == 'boolean' ||
+          value == null || isSymbol(value)) {
+        return true;
+      }
+      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+        (object != null && value in Object(object));
+    }
+
+    /**
+     * Checks if `value` is suitable for use as unique object key.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
+     */
+    function isKeyable(value) {
+      var type = typeof value;
+      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
+        ? (value !== '__proto__')
+        : (value === null);
+    }
+
+    /**
+     * Checks if `func` has a lazy counterpart.
+     *
+     * @private
+     * @param {Function} func The function to check.
+     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
+     *  else `false`.
+     */
+    function isLaziable(func) {
+      var funcName = getFuncName(func),
+          other = lodash[funcName];
+
+      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
+        return false;
+      }
+      if (func === other) {
+        return true;
+      }
+      var data = getData(other);
+      return !!data && func === data[0];
+    }
+
+    /**
+     * Checks if `func` has its source masked.
+     *
+     * @private
+     * @param {Function} func The function to check.
+     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
+     */
+    function isMasked(func) {
+      return !!maskSrcKey && (maskSrcKey in func);
+    }
+
+    /**
+     * Checks if `func` is capable of being masked.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
+     */
+    var isMaskable = coreJsData ? isFunction : stubFalse;
+
+    /**
+     * Checks if `value` is likely a prototype object.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
+     */
+    function isPrototype(value) {
+      var Ctor = value && value.constructor,
+          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
+
+      return value === proto;
+    }
+
+    /**
+     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` if suitable for strict
+     *  equality comparisons, else `false`.
+     */
+    function isStrictComparable(value) {
+      return value === value && !isObject(value);
+    }
+
+    /**
+     * A specialized version of `matchesProperty` for source values suitable
+     * for strict equality comparisons, i.e. `===`.
+     *
+     * @private
+     * @param {string} key The key of the property to get.
+     * @param {*} srcValue The value to match.
+     * @returns {Function} Returns the new spec function.
+     */
+    function matchesStrictComparable(key, srcValue) {
+      return function(object) {
+        if (object == null) {
+          return false;
+        }
+        return object[key] === srcValue &&
+          (srcValue !== undefined || (key in Object(object)));
+      };
+    }
+
+    /**
+     * A specialized version of `_.memoize` which clears the memoized function's
+     * cache when it exceeds `MAX_MEMOIZE_SIZE`.
+     *
+     * @private
+     * @param {Function} func The function to have its output memoized.
+     * @returns {Function} Returns the new memoized function.
+     */
+    function memoizeCapped(func) {
+      var result = memoize(func, function(key) {
+        if (cache.size === MAX_MEMOIZE_SIZE) {
+          cache.clear();
+        }
+        return key;
+      });
+
+      var cache = result.cache;
+      return result;
+    }
+
+    /**
+     * Merges the function metadata of `source` into `data`.
+     *
+     * Merging metadata reduces the number of wrappers used to invoke a function.
+     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
+     * may be applied regardless of execution order. Methods like `_.ary` and
+     * `_.rearg` modify function arguments, making the order in which they are
+     * executed important, preventing the merging of metadata. However, we make
+     * an exception for a safe combined case where curried functions have `_.ary`
+     * and or `_.rearg` applied.
+     *
+     * @private
+     * @param {Array} data The destination metadata.
+     * @param {Array} source The source metadata.
+     * @returns {Array} Returns `data`.
+     */
+    function mergeData(data, source) {
+      var bitmask = data[1],
+          srcBitmask = source[1],
+          newBitmask = bitmask | srcBitmask,
+          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
+
+      var isCombo =
+        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
+        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
+        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
+
+      // Exit early if metadata can't be merged.
+      if (!(isCommon || isCombo)) {
+        return data;
+      }
+      // Use source `thisArg` if available.
+      if (srcBitmask & WRAP_BIND_FLAG) {
+        data[2] = source[2];
+        // Set when currying a bound function.
+        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
+      }
+      // Compose partial arguments.
+      var value = source[3];
+      if (value) {
+        var partials = data[3];
+        data[3] = partials ? composeArgs(partials, value, source[4]) : value;
+        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
+      }
+      // Compose partial right arguments.
+      value = source[5];
+      if (value) {
+        partials = data[5];
+        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
+        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
+      }
+      // Use source `argPos` if available.
+      value = source[7];
+      if (value) {
+        data[7] = value;
+      }
+      // Use source `ary` if it's smaller.
+      if (srcBitmask & WRAP_ARY_FLAG) {
+        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
+      }
+      // Use source `arity` if one is not provided.
+      if (data[9] == null) {
+        data[9] = source[9];
+      }
+      // Use source `func` and merge bitmasks.
+      data[0] = source[0];
+      data[1] = newBitmask;
+
+      return data;
+    }
+
+    /**
+     * This function is like
+     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+     * except that it includes inherited enumerable properties.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names.
+     */
+    function nativeKeysIn(object) {
+      var result = [];
+      if (object != null) {
+        for (var key in Object(object)) {
+          result.push(key);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * Converts `value` to a string using `Object.prototype.toString`.
+     *
+     * @private
+     * @param {*} value The value to convert.
+     * @returns {string} Returns the converted string.
+     */
+    function objectToString(value) {
+      return nativeObjectToString.call(value);
+    }
+
+    /**
+     * A specialized version of `baseRest` which transforms the rest array.
+     *
+     * @private
+     * @param {Function} func The function to apply a rest parameter to.
+     * @param {number} [start=func.length-1] The start position of the rest parameter.
+     * @param {Function} transform The rest array transform.
+     * @returns {Function} Returns the new function.
+     */
+    function overRest(func, start, transform) {
+      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
+      return function() {
+        var args = arguments,
+            index = -1,
+            length = nativeMax(args.length - start, 0),
+            array = Array(length);
+
+        while (++index < length) {
+          array[index] = args[start + index];
+        }
+        index = -1;
+        var otherArgs = Array(start + 1);
+        while (++index < start) {
+          otherArgs[index] = args[index];
+        }
+        otherArgs[start] = transform(array);
+        return apply(func, this, otherArgs);
+      };
+    }
+
+    /**
+     * Gets the parent value at `path` of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @param {Array} path The path to get the parent value of.
+     * @returns {*} Returns the parent value.
+     */
+    function parent(object, path) {
+      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
+    }
+
+    /**
+     * Reorder `array` according to the specified indexes where the element at
+     * the first index is assigned as the first element, the element at
+     * the second index is assigned as the second element, and so on.
+     *
+     * @private
+     * @param {Array} array The array to reorder.
+     * @param {Array} indexes The arranged array indexes.
+     * @returns {Array} Returns `array`.
+     */
+    function reorder(array, indexes) {
+      var arrLength = array.length,
+          length = nativeMin(indexes.length, arrLength),
+          oldArray = copyArray(array);
+
+      while (length--) {
+        var index = indexes[length];
+        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
+      }
+      return array;
+    }
+
+    /**
+     * Sets metadata for `func`.
+     *
+     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
+     * period of time, it will trip its breaker and transition to an identity
+     * function to avoid garbage collection pauses in V8. See
+     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
+     * for more details.
+     *
+     * @private
+     * @param {Function} func The function to associate metadata with.
+     * @param {*} data The metadata.
+     * @returns {Function} Returns `func`.
+     */
+    var setData = shortOut(baseSetData);
+
+    /**
+     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
+     *
+     * @private
+     * @param {Function} func The function to delay.
+     * @param {number} wait The number of milliseconds to delay invocation.
+     * @returns {number|Object} Returns the timer id or timeout object.
+     */
+    var setTimeout = ctxSetTimeout || function(func, wait) {
+      return root.setTimeout(func, wait);
+    };
+
+    /**
+     * Sets the `toString` method of `func` to return `string`.
+     *
+     * @private
+     * @param {Function} func The function to modify.
+     * @param {Function} string The `toString` result.
+     * @returns {Function} Returns `func`.
+     */
+    var setToString = shortOut(baseSetToString);
+
+    /**
+     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
+     * with wrapper details in a comment at the top of the source body.
+     *
+     * @private
+     * @param {Function} wrapper The function to modify.
+     * @param {Function} reference The reference function.
+     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+     * @returns {Function} Returns `wrapper`.
+     */
+    function setWrapToString(wrapper, reference, bitmask) {
+      var source = (reference + '');
+      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
+    }
+
+    /**
+     * Creates a function that'll short out and invoke `identity` instead
+     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
+     * milliseconds.
+     *
+     * @private
+     * @param {Function} func The function to restrict.
+     * @returns {Function} Returns the new shortable function.
+     */
+    function shortOut(func) {
+      var count = 0,
+          lastCalled = 0;
+
+      return function() {
+        var stamp = nativeNow(),
+            remaining = HOT_SPAN - (stamp - lastCalled);
+
+        lastCalled = stamp;
+        if (remaining > 0) {
+          if (++count >= HOT_COUNT) {
+            return arguments[0];
+          }
+        } else {
+          count = 0;
+        }
+        return func.apply(undefined, arguments);
+      };
+    }
+
+    /**
+     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
+     *
+     * @private
+     * @param {Array} array The array to shuffle.
+     * @param {number} [size=array.length] The size of `array`.
+     * @returns {Array} Returns `array`.
+     */
+    function shuffleSelf(array, size) {
+      var index = -1,
+          length = array.length,
+          lastIndex = length - 1;
+
+      size = size === undefined ? length : size;
+      while (++index < size) {
+        var rand = baseRandom(index, lastIndex),
+            value = array[rand];
+
+        array[rand] = array[index];
+        array[index] = value;
+      }
+      array.length = size;
+      return array;
+    }
+
+    /**
+     * Converts `string` to a property path array.
+     *
+     * @private
+     * @param {string} string The string to convert.
+     * @returns {Array} Returns the property path array.
+     */
+    var stringToPath = memoizeCapped(function(string) {
+      var result = [];
+      if (reLeadingDot.test(string)) {
+        result.push('');
+      }
+      string.replace(rePropName, function(match, number, quote, string) {
+        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
+      });
+      return result;
+    });
+
+    /**
+     * Converts `value` to a string key if it's not a string or symbol.
+     *
+     * @private
+     * @param {*} value The value to inspect.
+     * @returns {string|symbol} Returns the key.
+     */
+    function toKey(value) {
+      if (typeof value == 'string' || isSymbol(value)) {
+        return value;
+      }
+      var result = (value + '');
+      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+    }
+
+    /**
+     * Converts `func` to its source code.
+     *
+     * @private
+     * @param {Function} func The function to convert.
+     * @returns {string} Returns the source code.
+     */
+    function toSource(func) {
+      if (func != null) {
+        try {
+          return funcToString.call(func);
+        } catch (e) {}
+        try {
+          return (func + '');
+        } catch (e) {}
+      }
+      return '';
+    }
+
+    /**
+     * Updates wrapper `details` based on `bitmask` flags.
+     *
+     * @private
+     * @returns {Array} details The details to modify.
+     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
+     * @returns {Array} Returns `details`.
+     */
+    function updateWrapDetails(details, bitmask) {
+      arrayEach(wrapFlags, function(pair) {
+        var value = '_.' + pair[0];
+        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
+          details.push(value);
+        }
+      });
+      return details.sort();
+    }
+
+    /**
+     * Creates a clone of `wrapper`.
+     *
+     * @private
+     * @param {Object} wrapper The wrapper to clone.
+     * @returns {Object} Returns the cloned wrapper.
+     */
+    function wrapperClone(wrapper) {
+      if (wrapper instanceof LazyWrapper) {
+        return wrapper.clone();
+      }
+      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
+      result.__actions__ = copyArray(wrapper.__actions__);
+      result.__index__  = wrapper.__index__;
+      result.__values__ = wrapper.__values__;
+      return result;
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates an array of elements split into groups the length of `size`.
+     * If `array` can't be split evenly, the final chunk will be the remaining
+     * elements.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to process.
+     * @param {number} [size=1] The length of each chunk
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Array} Returns the new array of chunks.
+     * @example
+     *
+     * _.chunk(['a', 'b', 'c', 'd'], 2);
+     * // => [['a', 'b'], ['c', 'd']]
+     *
+     * _.chunk(['a', 'b', 'c', 'd'], 3);
+     * // => [['a', 'b', 'c'], ['d']]
+     */
+    function chunk(array, size, guard) {
+      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
+        size = 1;
+      } else {
+        size = nativeMax(toInteger(size), 0);
+      }
+      var length = array == null ? 0 : array.length;
+      if (!length || size < 1) {
+        return [];
+      }
+      var index = 0,
+          resIndex = 0,
+          result = Array(nativeCeil(length / size));
+
+      while (index < length) {
+        result[resIndex++] = baseSlice(array, index, (index += size));
+      }
+      return result;
+    }
+
+    /**
+     * Creates an array with all falsey values removed. The values `false`, `null`,
+     * `0`, `""`, `undefined`, and `NaN` are falsey.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to compact.
+     * @returns {Array} Returns the new array of filtered values.
+     * @example
+     *
+     * _.compact([0, 1, false, 2, '', 3]);
+     * // => [1, 2, 3]
+     */
+    function compact(array) {
+      var index = -1,
+          length = array == null ? 0 : array.length,
+          resIndex = 0,
+          result = [];
+
+      while (++index < length) {
+        var value = array[index];
+        if (value) {
+          result[resIndex++] = value;
+        }
+      }
+      return result;
+    }
+
+    /**
+     * Creates a new array concatenating `array` with any additional arrays
+     * and/or values.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to concatenate.
+     * @param {...*} [values] The values to concatenate.
+     * @returns {Array} Returns the new concatenated array.
+     * @example
+     *
+     * var array = [1];
+     * var other = _.concat(array, 2, [3], [[4]]);
+     *
+     * console.log(other);
+     * // => [1, 2, 3, [4]]
+     *
+     * console.log(array);
+     * // => [1]
+     */
+    function concat() {
+      var length = arguments.length;
+      if (!length) {
+        return [];
+      }
+      var args = Array(length - 1),
+          array = arguments[0],
+          index = length;
+
+      while (index--) {
+        args[index - 1] = arguments[index];
+      }
+      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
+    }
+
+    /**
+     * Creates an array of `array` values not included in the other given arrays
+     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * for equality comparisons. The order and references of result values are
+     * determined by the first array.
+     *
+     * **Note:** Unlike `_.pullAll`, this method returns a new array.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {...Array} [values] The values to exclude.
+     * @returns {Array} Returns the new array of filtered values.
+     * @see _.without, _.xor
+     * @example
+     *
+     * _.difference([2, 1], [2, 3]);
+     * // => [1]
+     */
+    var difference = baseRest(function(array, values) {
+      return isArrayLikeObject(array)
+        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
+        : [];
+    });
+
+    /**
+     * This method is like `_.difference` except that it accepts `iteratee` which
+     * is invoked for each element of `array` and `values` to generate the criterion
+     * by which they're compared. The order and references of result values are
+     * determined by the first array. The iteratee is invoked with one argument:
+     * (value).
+     *
+     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {...Array} [values] The values to exclude.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {Array} Returns the new array of filtered values.
+     * @example
+     *
+     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+     * // => [1.2]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
+     * // => [{ 'x': 2 }]
+     */
+    var differenceBy = baseRest(function(array, values) {
+      var iteratee = last(values);
+      if (isArrayLikeObject(iteratee)) {
+        iteratee = undefined;
+      }
+      return isArrayLikeObject(array)
+        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
+        : [];
+    });
+
+    /**
+     * This method is like `_.difference` except that it accepts `comparator`
+     * which is invoked to compare elements of `array` to `values`. The order and
+     * references of result values are determined by the first array. The comparator
+     * is invoked with two arguments: (arrVal, othVal).
+     *
+     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {...Array} [values] The values to exclude.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns the new array of filtered values.
+     * @example
+     *
+     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+     *
+     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
+     * // => [{ 'x': 2, 'y': 1 }]
+     */
+    var differenceWith = baseRest(function(array, values) {
+      var comparator = last(values);
+      if (isArrayLikeObject(comparator)) {
+        comparator = undefined;
+      }
+      return isArrayLikeObject(array)
+        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
+        : [];
+    });
+
+    /**
+     * Creates a slice of `array` with `n` elements dropped from the beginning.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.5.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @param {number} [n=1] The number of elements to drop.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * _.drop([1, 2, 3]);
+     * // => [2, 3]
+     *
+     * _.drop([1, 2, 3], 2);
+     * // => [3]
+     *
+     * _.drop([1, 2, 3], 5);
+     * // => []
+     *
+     * _.drop([1, 2, 3], 0);
+     * // => [1, 2, 3]
+     */
+    function drop(array, n, guard) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return [];
+      }
+      n = (guard || n === undefined) ? 1 : toInteger(n);
+      return baseSlice(array, n < 0 ? 0 : n, length);
+    }
+
+    /**
+     * Creates a slice of `array` with `n` elements dropped from the end.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @param {number} [n=1] The number of elements to drop.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * _.dropRight([1, 2, 3]);
+     * // => [1, 2]
+     *
+     * _.dropRight([1, 2, 3], 2);
+     * // => [1]
+     *
+     * _.dropRight([1, 2, 3], 5);
+     * // => []
+     *
+     * _.dropRight([1, 2, 3], 0);
+     * // => [1, 2, 3]
+     */
+    function dropRight(array, n, guard) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return [];
+      }
+      n = (guard || n === undefined) ? 1 : toInteger(n);
+      n = length - n;
+      return baseSlice(array, 0, n < 0 ? 0 : n);
+    }
+
+    /**
+     * Creates a slice of `array` excluding elements dropped from the end.
+     * Elements are dropped until `predicate` returns falsey. The predicate is
+     * invoked with three arguments: (value, index, array).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney',  'active': true },
+     *   { 'user': 'fred',    'active': false },
+     *   { 'user': 'pebbles', 'active': false }
+     * ];
+     *
+     * _.dropRightWhile(users, function(o) { return !o.active; });
+     * // => objects for ['barney']
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
+     * // => objects for ['barney', 'fred']
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.dropRightWhile(users, ['active', false]);
+     * // => objects for ['barney']
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.dropRightWhile(users, 'active');
+     * // => objects for ['barney', 'fred', 'pebbles']
+     */
+    function dropRightWhile(array, predicate) {
+      return (array && array.length)
+        ? baseWhile(array, getIteratee(predicate, 3), true, true)
+        : [];
+    }
+
+    /**
+     * Creates a slice of `array` excluding elements dropped from the beginning.
+     * Elements are dropped until `predicate` returns falsey. The predicate is
+     * invoked with three arguments: (value, index, array).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney',  'active': false },
+     *   { 'user': 'fred',    'active': false },
+     *   { 'user': 'pebbles', 'active': true }
+     * ];
+     *
+     * _.dropWhile(users, function(o) { return !o.active; });
+     * // => objects for ['pebbles']
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.dropWhile(users, { 'user': 'barney', 'active': false });
+     * // => objects for ['fred', 'pebbles']
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.dropWhile(users, ['active', false]);
+     * // => objects for ['pebbles']
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.dropWhile(users, 'active');
+     * // => objects for ['barney', 'fred', 'pebbles']
+     */
+    function dropWhile(array, predicate) {
+      return (array && array.length)
+        ? baseWhile(array, getIteratee(predicate, 3), true)
+        : [];
+    }
+
+    /**
+     * Fills elements of `array` with `value` from `start` up to, but not
+     * including, `end`.
+     *
+     * **Note:** This method mutates `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.2.0
+     * @category Array
+     * @param {Array} array The array to fill.
+     * @param {*} value The value to fill `array` with.
+     * @param {number} [start=0] The start position.
+     * @param {number} [end=array.length] The end position.
+     * @returns {Array} Returns `array`.
+     * @example
+     *
+     * var array = [1, 2, 3];
+     *
+     * _.fill(array, 'a');
+     * console.log(array);
+     * // => ['a', 'a', 'a']
+     *
+     * _.fill(Array(3), 2);
+     * // => [2, 2, 2]
+     *
+     * _.fill([4, 6, 8, 10], '*', 1, 3);
+     * // => [4, '*', '*', 10]
+     */
+    function fill(array, value, start, end) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return [];
+      }
+      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
+        start = 0;
+        end = length;
+      }
+      return baseFill(array, value, start, end);
+    }
+
+    /**
+     * This method is like `_.find` except that it returns the index of the first
+     * element `predicate` returns truthy for instead of the element itself.
+     *
+     * @static
+     * @memberOf _
+     * @since 1.1.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @param {number} [fromIndex=0] The index to search from.
+     * @returns {number} Returns the index of the found element, else `-1`.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney',  'active': false },
+     *   { 'user': 'fred',    'active': false },
+     *   { 'user': 'pebbles', 'active': true }
+     * ];
+     *
+     * _.findIndex(users, function(o) { return o.user == 'barney'; });
+     * // => 0
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.findIndex(users, { 'user': 'fred', 'active': false });
+     * // => 1
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.findIndex(users, ['active', false]);
+     * // => 0
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.findIndex(users, 'active');
+     * // => 2
+     */
+    function findIndex(array, predicate, fromIndex) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return -1;
+      }
+      var index = fromIndex == null ? 0 : toInteger(fromIndex);
+      if (index < 0) {
+        index = nativeMax(length + index, 0);
+      }
+      return baseFindIndex(array, getIteratee(predicate, 3), index);
+    }
+
+    /**
+     * This method is like `_.findIndex` except that it iterates over elements
+     * of `collection` from right to left.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @param {number} [fromIndex=array.length-1] The index to search from.
+     * @returns {number} Returns the index of the found element, else `-1`.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney',  'active': true },
+     *   { 'user': 'fred',    'active': false },
+     *   { 'user': 'pebbles', 'active': false }
+     * ];
+     *
+     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
+     * // => 2
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
+     * // => 0
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.findLastIndex(users, ['active', false]);
+     * // => 2
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.findLastIndex(users, 'active');
+     * // => 0
+     */
+    function findLastIndex(array, predicate, fromIndex) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return -1;
+      }
+      var index = length - 1;
+      if (fromIndex !== undefined) {
+        index = toInteger(fromIndex);
+        index = fromIndex < 0
+          ? nativeMax(length + index, 0)
+          : nativeMin(index, length - 1);
+      }
+      return baseFindIndex(array, getIteratee(predicate, 3), index, true);
+    }
+
+    /**
+     * Flattens `array` a single level deep.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to flatten.
+     * @returns {Array} Returns the new flattened array.
+     * @example
+     *
+     * _.flatten([1, [2, [3, [4]], 5]]);
+     * // => [1, 2, [3, [4]], 5]
+     */
+    function flatten(array) {
+      var length = array == null ? 0 : array.length;
+      return length ? baseFlatten(array, 1) : [];
+    }
+
+    /**
+     * Recursively flattens `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to flatten.
+     * @returns {Array} Returns the new flattened array.
+     * @example
+     *
+     * _.flattenDeep([1, [2, [3, [4]], 5]]);
+     * // => [1, 2, 3, 4, 5]
+     */
+    function flattenDeep(array) {
+      var length = array == null ? 0 : array.length;
+      return length ? baseFlatten(array, INFINITY) : [];
+    }
+
+    /**
+     * Recursively flatten `array` up to `depth` times.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.4.0
+     * @category Array
+     * @param {Array} array The array to flatten.
+     * @param {number} [depth=1] The maximum recursion depth.
+     * @returns {Array} Returns the new flattened array.
+     * @example
+     *
+     * var array = [1, [2, [3, [4]], 5]];
+     *
+     * _.flattenDepth(array, 1);
+     * // => [1, 2, [3, [4]], 5]
+     *
+     * _.flattenDepth(array, 2);
+     * // => [1, 2, 3, [4], 5]
+     */
+    function flattenDepth(array, depth) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return [];
+      }
+      depth = depth === undefined ? 1 : toInteger(depth);
+      return baseFlatten(array, depth);
+    }
+
+    /**
+     * The inverse of `_.toPairs`; this method returns an object composed
+     * from key-value `pairs`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} pairs The key-value pairs.
+     * @returns {Object} Returns the new object.
+     * @example
+     *
+     * _.fromPairs([['a', 1], ['b', 2]]);
+     * // => { 'a': 1, 'b': 2 }
+     */
+    function fromPairs(pairs) {
+      var index = -1,
+          length = pairs == null ? 0 : pairs.length,
+          result = {};
+
+      while (++index < length) {
+        var pair = pairs[index];
+        result[pair[0]] = pair[1];
+      }
+      return result;
+    }
+
+    /**
+     * Gets the first element of `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @alias first
+     * @category Array
+     * @param {Array} array The array to query.
+     * @returns {*} Returns the first element of `array`.
+     * @example
+     *
+     * _.head([1, 2, 3]);
+     * // => 1
+     *
+     * _.head([]);
+     * // => undefined
+     */
+    function head(array) {
+      return (array && array.length) ? array[0] : undefined;
+    }
+
+    /**
+     * Gets the index at which the first occurrence of `value` is found in `array`
+     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * for equality comparisons. If `fromIndex` is negative, it's used as the
+     * offset from the end of `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {*} value The value to search for.
+     * @param {number} [fromIndex=0] The index to search from.
+     * @returns {number} Returns the index of the matched value, else `-1`.
+     * @example
+     *
+     * _.indexOf([1, 2, 1, 2], 2);
+     * // => 1
+     *
+     * // Search from the `fromIndex`.
+     * _.indexOf([1, 2, 1, 2], 2, 2);
+     * // => 3
+     */
+    function indexOf(array, value, fromIndex) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return -1;
+      }
+      var index = fromIndex == null ? 0 : toInteger(fromIndex);
+      if (index < 0) {
+        index = nativeMax(length + index, 0);
+      }
+      return baseIndexOf(array, value, index);
+    }
+
+    /**
+     * Gets all but the last element of `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * _.initial([1, 2, 3]);
+     * // => [1, 2]
+     */
+    function initial(array) {
+      var length = array == null ? 0 : array.length;
+      return length ? baseSlice(array, 0, -1) : [];
+    }
+
+    /**
+     * Creates an array of unique values that are included in all given arrays
+     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * for equality comparisons. The order and references of result values are
+     * determined by the first array.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @returns {Array} Returns the new array of intersecting values.
+     * @example
+     *
+     * _.intersection([2, 1], [2, 3]);
+     * // => [2]
+     */
+    var intersection = baseRest(function(arrays) {
+      var mapped = arrayMap(arrays, castArrayLikeObject);
+      return (mapped.length && mapped[0] === arrays[0])
+        ? baseIntersection(mapped)
+        : [];
+    });
+
+    /**
+     * This method is like `_.intersection` except that it accepts `iteratee`
+     * which is invoked for each element of each `arrays` to generate the criterion
+     * by which they're compared. The order and references of result values are
+     * determined by the first array. The iteratee is invoked with one argument:
+     * (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {Array} Returns the new array of intersecting values.
+     * @example
+     *
+     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+     * // => [2.1]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 1 }]
+     */
+    var intersectionBy = baseRest(function(arrays) {
+      var iteratee = last(arrays),
+          mapped = arrayMap(arrays, castArrayLikeObject);
+
+      if (iteratee === last(mapped)) {
+        iteratee = undefined;
+      } else {
+        mapped.pop();
+      }
+      return (mapped.length && mapped[0] === arrays[0])
+        ? baseIntersection(mapped, getIteratee(iteratee, 2))
+        : [];
+    });
+
+    /**
+     * This method is like `_.intersection` except that it accepts `comparator`
+     * which is invoked to compare elements of `arrays`. The order and references
+     * of result values are determined by the first array. The comparator is
+     * invoked with two arguments: (arrVal, othVal).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns the new array of intersecting values.
+     * @example
+     *
+     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+     *
+     * _.intersectionWith(objects, others, _.isEqual);
+     * // => [{ 'x': 1, 'y': 2 }]
+     */
+    var intersectionWith = baseRest(function(arrays) {
+      var comparator = last(arrays),
+          mapped = arrayMap(arrays, castArrayLikeObject);
+
+      comparator = typeof comparator == 'function' ? comparator : undefined;
+      if (comparator) {
+        mapped.pop();
+      }
+      return (mapped.length && mapped[0] === arrays[0])
+        ? baseIntersection(mapped, undefined, comparator)
+        : [];
+    });
+
+    /**
+     * Converts all elements in `array` into a string separated by `separator`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to convert.
+     * @param {string} [separator=','] The element separator.
+     * @returns {string} Returns the joined string.
+     * @example
+     *
+     * _.join(['a', 'b', 'c'], '~');
+     * // => 'a~b~c'
+     */
+    function join(array, separator) {
+      return array == null ? '' : nativeJoin.call(array, separator);
+    }
+
+    /**
+     * Gets the last element of `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @returns {*} Returns the last element of `array`.
+     * @example
+     *
+     * _.last([1, 2, 3]);
+     * // => 3
+     */
+    function last(array) {
+      var length = array == null ? 0 : array.length;
+      return length ? array[length - 1] : undefined;
+    }
+
+    /**
+     * This method is like `_.indexOf` except that it iterates over elements of
+     * `array` from right to left.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {*} value The value to search for.
+     * @param {number} [fromIndex=array.length-1] The index to search from.
+     * @returns {number} Returns the index of the matched value, else `-1`.
+     * @example
+     *
+     * _.lastIndexOf([1, 2, 1, 2], 2);
+     * // => 3
+     *
+     * // Search from the `fromIndex`.
+     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
+     * // => 1
+     */
+    function lastIndexOf(array, value, fromIndex) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return -1;
+      }
+      var index = length;
+      if (fromIndex !== undefined) {
+        index = toInteger(fromIndex);
+        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
+      }
+      return value === value
+        ? strictLastIndexOf(array, value, index)
+        : baseFindIndex(array, baseIsNaN, index, true);
+    }
+
+    /**
+     * Gets the element at index `n` of `array`. If `n` is negative, the nth
+     * element from the end is returned.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.11.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @param {number} [n=0] The index of the element to return.
+     * @returns {*} Returns the nth element of `array`.
+     * @example
+     *
+     * var array = ['a', 'b', 'c', 'd'];
+     *
+     * _.nth(array, 1);
+     * // => 'b'
+     *
+     * _.nth(array, -2);
+     * // => 'c';
+     */
+    function nth(array, n) {
+      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
+    }
+
+    /**
+     * Removes all given values from `array` using
+     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * for equality comparisons.
+     *
+     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
+     * to remove elements from an array by predicate.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @category Array
+     * @param {Array} array The array to modify.
+     * @param {...*} [values] The values to remove.
+     * @returns {Array} Returns `array`.
+     * @example
+     *
+     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
+     *
+     * _.pull(array, 'a', 'c');
+     * console.log(array);
+     * // => ['b', 'b']
+     */
+    var pull = baseRest(pullAll);
+
+    /**
+     * This method is like `_.pull` except that it accepts an array of values to remove.
+     *
+     * **Note:** Unlike `_.difference`, this method mutates `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to modify.
+     * @param {Array} values The values to remove.
+     * @returns {Array} Returns `array`.
+     * @example
+     *
+     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
+     *
+     * _.pullAll(array, ['a', 'c']);
+     * console.log(array);
+     * // => ['b', 'b']
+     */
+    function pullAll(array, values) {
+      return (array && array.length && values && values.length)
+        ? basePullAll(array, values)
+        : array;
+    }
+
+    /**
+     * This method is like `_.pullAll` except that it accepts `iteratee` which is
+     * invoked for each element of `array` and `values` to generate the criterion
+     * by which they're compared. The iteratee is invoked with one argument: (value).
+     *
+     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to modify.
+     * @param {Array} values The values to remove.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {Array} Returns `array`.
+     * @example
+     *
+     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
+     *
+     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
+     * console.log(array);
+     * // => [{ 'x': 2 }]
+     */
+    function pullAllBy(array, values, iteratee) {
+      return (array && array.length && values && values.length)
+        ? basePullAll(array, values, getIteratee(iteratee, 2))
+        : array;
+    }
+
+    /**
+     * This method is like `_.pullAll` except that it accepts `comparator` which
+     * is invoked to compare elements of `array` to `values`. The comparator is
+     * invoked with two arguments: (arrVal, othVal).
+     *
+     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.6.0
+     * @category Array
+     * @param {Array} array The array to modify.
+     * @param {Array} values The values to remove.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns `array`.
+     * @example
+     *
+     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
+     *
+     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
+     * console.log(array);
+     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
+     */
+    function pullAllWith(array, values, comparator) {
+      return (array && array.length && values && values.length)
+        ? basePullAll(array, values, undefined, comparator)
+        : array;
+    }
+
+    /**
+     * Removes elements from `array` corresponding to `indexes` and returns an
+     * array of removed elements.
+     *
+     * **Note:** Unlike `_.at`, this method mutates `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to modify.
+     * @param {...(number|number[])} [indexes] The indexes of elements to remove.
+     * @returns {Array} Returns the new array of removed elements.
+     * @example
+     *
+     * var array = ['a', 'b', 'c', 'd'];
+     * var pulled = _.pullAt(array, [1, 3]);
+     *
+     * console.log(array);
+     * // => ['a', 'c']
+     *
+     * console.log(pulled);
+     * // => ['b', 'd']
+     */
+    var pullAt = flatRest(function(array, indexes) {
+      var length = array == null ? 0 : array.length,
+          result = baseAt(array, indexes);
+
+      basePullAt(array, arrayMap(indexes, function(index) {
+        return isIndex(index, length) ? +index : index;
+      }).sort(compareAscending));
+
+      return result;
+    });
+
+    /**
+     * Removes all elements from `array` that `predicate` returns truthy for
+     * and returns an array of the removed elements. The predicate is invoked
+     * with three arguments: (value, index, array).
+     *
+     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
+     * to pull elements from an array by value.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @category Array
+     * @param {Array} array The array to modify.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the new array of removed elements.
+     * @example
+     *
+     * var array = [1, 2, 3, 4];
+     * var evens = _.remove(array, function(n) {
+     *   return n % 2 == 0;
+     * });
+     *
+     * console.log(array);
+     * // => [1, 3]
+     *
+     * console.log(evens);
+     * // => [2, 4]
+     */
+    function remove(array, predicate) {
+      var result = [];
+      if (!(array && array.length)) {
+        return result;
+      }
+      var index = -1,
+          indexes = [],
+          length = array.length;
+
+      predicate = getIteratee(predicate, 3);
+      while (++index < length) {
+        var value = array[index];
+        if (predicate(value, index, array)) {
+          result.push(value);
+          indexes.push(index);
+        }
+      }
+      basePullAt(array, indexes);
+      return result;
+    }
+
+    /**
+     * Reverses `array` so that the first element becomes the last, the second
+     * element becomes the second to last, and so on.
+     *
+     * **Note:** This method mutates `array` and is based on
+     * [`Array#reverse`](https://mdn.io/Array/reverse).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to modify.
+     * @returns {Array} Returns `array`.
+     * @example
+     *
+     * var array = [1, 2, 3];
+     *
+     * _.reverse(array);
+     * // => [3, 2, 1]
+     *
+     * console.log(array);
+     * // => [3, 2, 1]
+     */
+    function reverse(array) {
+      return array == null ? array : nativeReverse.call(array);
+    }
+
+    /**
+     * Creates a slice of `array` from `start` up to, but not including, `end`.
+     *
+     * **Note:** This method is used instead of
+     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
+     * returned.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to slice.
+     * @param {number} [start=0] The start position.
+     * @param {number} [end=array.length] The end position.
+     * @returns {Array} Returns the slice of `array`.
+     */
+    function slice(array, start, end) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return [];
+      }
+      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
+        start = 0;
+        end = length;
+      }
+      else {
+        start = start == null ? 0 : toInteger(start);
+        end = end === undefined ? length : toInteger(end);
+      }
+      return baseSlice(array, start, end);
+    }
+
+    /**
+     * Uses a binary search to determine the lowest index at which `value`
+     * should be inserted into `array` in order to maintain its sort order.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The sorted array to inspect.
+     * @param {*} value The value to evaluate.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     * @example
+     *
+     * _.sortedIndex([30, 50], 40);
+     * // => 1
+     */
+    function sortedIndex(array, value) {
+      return baseSortedIndex(array, value);
+    }
+
+    /**
+     * This method is like `_.sortedIndex` except that it accepts `iteratee`
+     * which is invoked for `value` and each element of `array` to compute their
+     * sort ranking. The iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The sorted array to inspect.
+     * @param {*} value The value to evaluate.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     * @example
+     *
+     * var objects = [{ 'x': 4 }, { 'x': 5 }];
+     *
+     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
+     * // => 0
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
+     * // => 0
+     */
+    function sortedIndexBy(array, value, iteratee) {
+      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
+    }
+
+    /**
+     * This method is like `_.indexOf` except that it performs a binary
+     * search on a sorted `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {*} value The value to search for.
+     * @returns {number} Returns the index of the matched value, else `-1`.
+     * @example
+     *
+     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
+     * // => 1
+     */
+    function sortedIndexOf(array, value) {
+      var length = array == null ? 0 : array.length;
+      if (length) {
+        var index = baseSortedIndex(array, value);
+        if (index < length && eq(array[index], value)) {
+          return index;
+        }
+      }
+      return -1;
+    }
+
+    /**
+     * This method is like `_.sortedIndex` except that it returns the highest
+     * index at which `value` should be inserted into `array` in order to
+     * maintain its sort order.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The sorted array to inspect.
+     * @param {*} value The value to evaluate.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     * @example
+     *
+     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
+     * // => 4
+     */
+    function sortedLastIndex(array, value) {
+      return baseSortedIndex(array, value, true);
+    }
+
+    /**
+     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
+     * which is invoked for `value` and each element of `array` to compute their
+     * sort ranking. The iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The sorted array to inspect.
+     * @param {*} value The value to evaluate.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     * @example
+     *
+     * var objects = [{ 'x': 4 }, { 'x': 5 }];
+     *
+     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
+     * // => 1
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
+     * // => 1
+     */
+    function sortedLastIndexBy(array, value, iteratee) {
+      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
+    }
+
+    /**
+     * This method is like `_.lastIndexOf` except that it performs a binary
+     * search on a sorted `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {*} value The value to search for.
+     * @returns {number} Returns the index of the matched value, else `-1`.
+     * @example
+     *
+     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
+     * // => 3
+     */
+    function sortedLastIndexOf(array, value) {
+      var length = array == null ? 0 : array.length;
+      if (length) {
+        var index = baseSortedIndex(array, value, true) - 1;
+        if (eq(array[index], value)) {
+          return index;
+        }
+      }
+      return -1;
+    }
+
+    /**
+     * This method is like `_.uniq` except that it's designed and optimized
+     * for sorted arrays.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @returns {Array} Returns the new duplicate free array.
+     * @example
+     *
+     * _.sortedUniq([1, 1, 2]);
+     * // => [1, 2]
+     */
+    function sortedUniq(array) {
+      return (array && array.length)
+        ? baseSortedUniq(array)
+        : [];
+    }
+
+    /**
+     * This method is like `_.uniqBy` except that it's designed and optimized
+     * for sorted arrays.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {Function} [iteratee] The iteratee invoked per element.
+     * @returns {Array} Returns the new duplicate free array.
+     * @example
+     *
+     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
+     * // => [1.1, 2.3]
+     */
+    function sortedUniqBy(array, iteratee) {
+      return (array && array.length)
+        ? baseSortedUniq(array, getIteratee(iteratee, 2))
+        : [];
+    }
+
+    /**
+     * Gets all but the first element of `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * _.tail([1, 2, 3]);
+     * // => [2, 3]
+     */
+    function tail(array) {
+      var length = array == null ? 0 : array.length;
+      return length ? baseSlice(array, 1, length) : [];
+    }
+
+    /**
+     * Creates a slice of `array` with `n` elements taken from the beginning.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @param {number} [n=1] The number of elements to take.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * _.take([1, 2, 3]);
+     * // => [1]
+     *
+     * _.take([1, 2, 3], 2);
+     * // => [1, 2]
+     *
+     * _.take([1, 2, 3], 5);
+     * // => [1, 2, 3]
+     *
+     * _.take([1, 2, 3], 0);
+     * // => []
+     */
+    function take(array, n, guard) {
+      if (!(array && array.length)) {
+        return [];
+      }
+      n = (guard || n === undefined) ? 1 : toInteger(n);
+      return baseSlice(array, 0, n < 0 ? 0 : n);
+    }
+
+    /**
+     * Creates a slice of `array` with `n` elements taken from the end.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @param {number} [n=1] The number of elements to take.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * _.takeRight([1, 2, 3]);
+     * // => [3]
+     *
+     * _.takeRight([1, 2, 3], 2);
+     * // => [2, 3]
+     *
+     * _.takeRight([1, 2, 3], 5);
+     * // => [1, 2, 3]
+     *
+     * _.takeRight([1, 2, 3], 0);
+     * // => []
+     */
+    function takeRight(array, n, guard) {
+      var length = array == null ? 0 : array.length;
+      if (!length) {
+        return [];
+      }
+      n = (guard || n === undefined) ? 1 : toInteger(n);
+      n = length - n;
+      return baseSlice(array, n < 0 ? 0 : n, length);
+    }
+
+    /**
+     * Creates a slice of `array` with elements taken from the end. Elements are
+     * taken until `predicate` returns falsey. The predicate is invoked with
+     * three arguments: (value, index, array).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney',  'active': true },
+     *   { 'user': 'fred',    'active': false },
+     *   { 'user': 'pebbles', 'active': false }
+     * ];
+     *
+     * _.takeRightWhile(users, function(o) { return !o.active; });
+     * // => objects for ['fred', 'pebbles']
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
+     * // => objects for ['pebbles']
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.takeRightWhile(users, ['active', false]);
+     * // => objects for ['fred', 'pebbles']
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.takeRightWhile(users, 'active');
+     * // => []
+     */
+    function takeRightWhile(array, predicate) {
+      return (array && array.length)
+        ? baseWhile(array, getIteratee(predicate, 3), false, true)
+        : [];
+    }
+
+    /**
+     * Creates a slice of `array` with elements taken from the beginning. Elements
+     * are taken until `predicate` returns falsey. The predicate is invoked with
+     * three arguments: (value, index, array).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Array
+     * @param {Array} array The array to query.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the slice of `array`.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney',  'active': false },
+     *   { 'user': 'fred',    'active': false },
+     *   { 'user': 'pebbles', 'active': true }
+     * ];
+     *
+     * _.takeWhile(users, function(o) { return !o.active; });
+     * // => objects for ['barney', 'fred']
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.takeWhile(users, { 'user': 'barney', 'active': false });
+     * // => objects for ['barney']
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.takeWhile(users, ['active', false]);
+     * // => objects for ['barney', 'fred']
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.takeWhile(users, 'active');
+     * // => []
+     */
+    function takeWhile(array, predicate) {
+      return (array && array.length)
+        ? baseWhile(array, getIteratee(predicate, 3))
+        : [];
+    }
+
+    /**
+     * Creates an array of unique values, in order, from all given arrays using
+     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * for equality comparisons.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @returns {Array} Returns the new array of combined values.
+     * @example
+     *
+     * _.union([2], [1, 2]);
+     * // => [2, 1]
+     */
+    var union = baseRest(function(arrays) {
+      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
+    });
+
+    /**
+     * This method is like `_.union` except that it accepts `iteratee` which is
+     * invoked for each element of each `arrays` to generate the criterion by
+     * which uniqueness is computed. Result values are chosen from the first
+     * array in which the value occurs. The iteratee is invoked with one argument:
+     * (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {Array} Returns the new array of combined values.
+     * @example
+     *
+     * _.unionBy([2.1], [1.2, 2.3], Math.floor);
+     * // => [2.1, 1.2]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 1 }, { 'x': 2 }]
+     */
+    var unionBy = baseRest(function(arrays) {
+      var iteratee = last(arrays);
+      if (isArrayLikeObject(iteratee)) {
+        iteratee = undefined;
+      }
+      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
+    });
+
+    /**
+     * This method is like `_.union` except that it accepts `comparator` which
+     * is invoked to compare elements of `arrays`. Result values are chosen from
+     * the first array in which the value occurs. The comparator is invoked
+     * with two arguments: (arrVal, othVal).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns the new array of combined values.
+     * @example
+     *
+     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+     *
+     * _.unionWith(objects, others, _.isEqual);
+     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+     */
+    var unionWith = baseRest(function(arrays) {
+      var comparator = last(arrays);
+      comparator = typeof comparator == 'function' ? comparator : undefined;
+      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
+    });
+
+    /**
+     * Creates a duplicate-free version of an array, using
+     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * for equality comparisons, in which only the first occurrence of each element
+     * is kept. The order of result values is determined by the order they occur
+     * in the array.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @returns {Array} Returns the new duplicate free array.
+     * @example
+     *
+     * _.uniq([2, 1, 2]);
+     * // => [2, 1]
+     */
+    function uniq(array) {
+      return (array && array.length) ? baseUniq(array) : [];
+    }
+
+    /**
+     * This method is like `_.uniq` except that it accepts `iteratee` which is
+     * invoked for each element in `array` to generate the criterion by which
+     * uniqueness is computed. The order of result values is determined by the
+     * order they occur in the array. The iteratee is invoked with one argument:
+     * (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {Array} Returns the new duplicate free array.
+     * @example
+     *
+     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
+     * // => [2.1, 1.2]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 1 }, { 'x': 2 }]
+     */
+    function uniqBy(array, iteratee) {
+      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
+    }
+
+    /**
+     * This method is like `_.uniq` except that it accepts `comparator` which
+     * is invoked to compare elements of `array`. The order of result values is
+     * determined by the order they occur in the array.The comparator is invoked
+     * with two arguments: (arrVal, othVal).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns the new duplicate free array.
+     * @example
+     *
+     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
+     *
+     * _.uniqWith(objects, _.isEqual);
+     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
+     */
+    function uniqWith(array, comparator) {
+      comparator = typeof comparator == 'function' ? comparator : undefined;
+      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
+    }
+
+    /**
+     * This method is like `_.zip` except that it accepts an array of grouped
+     * elements and creates an array regrouping the elements to their pre-zip
+     * configuration.
+     *
+     * @static
+     * @memberOf _
+     * @since 1.2.0
+     * @category Array
+     * @param {Array} array The array of grouped elements to process.
+     * @returns {Array} Returns the new array of regrouped elements.
+     * @example
+     *
+     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
+     * // => [['a', 1, true], ['b', 2, false]]
+     *
+     * _.unzip(zipped);
+     * // => [['a', 'b'], [1, 2], [true, false]]
+     */
+    function unzip(array) {
+      if (!(array && array.length)) {
+        return [];
+      }
+      var length = 0;
+      array = arrayFilter(array, function(group) {
+        if (isArrayLikeObject(group)) {
+          length = nativeMax(group.length, length);
+          return true;
+        }
+      });
+      return baseTimes(length, function(index) {
+        return arrayMap(array, baseProperty(index));
+      });
+    }
+
+    /**
+     * This method is like `_.unzip` except that it accepts `iteratee` to specify
+     * how regrouped values should be combined. The iteratee is invoked with the
+     * elements of each group: (...group).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.8.0
+     * @category Array
+     * @param {Array} array The array of grouped elements to process.
+     * @param {Function} [iteratee=_.identity] The function to combine
+     *  regrouped values.
+     * @returns {Array} Returns the new array of regrouped elements.
+     * @example
+     *
+     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
+     * // => [[1, 10, 100], [2, 20, 200]]
+     *
+     * _.unzipWith(zipped, _.add);
+     * // => [3, 30, 300]
+     */
+    function unzipWith(array, iteratee) {
+      if (!(array && array.length)) {
+        return [];
+      }
+      var result = unzip(array);
+      if (iteratee == null) {
+        return result;
+      }
+      return arrayMap(result, function(group) {
+        return apply(iteratee, undefined, group);
+      });
+    }
+
+    /**
+     * Creates an array excluding all given values using
+     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * for equality comparisons.
+     *
+     * **Note:** Unlike `_.pull`, this method returns a new array.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {...*} [values] The values to exclude.
+     * @returns {Array} Returns the new array of filtered values.
+     * @see _.difference, _.xor
+     * @example
+     *
+     * _.without([2, 1, 2, 3], 1, 2);
+     * // => [3]
+     */
+    var without = baseRest(function(array, values) {
+      return isArrayLikeObject(array)
+        ? baseDifference(array, values)
+        : [];
+    });
+
+    /**
+     * Creates an array of unique values that is the
+     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
+     * of the given arrays. The order of result values is determined by the order
+     * they occur in the arrays.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.4.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @returns {Array} Returns the new array of filtered values.
+     * @see _.difference, _.without
+     * @example
+     *
+     * _.xor([2, 1], [2, 3]);
+     * // => [1, 3]
+     */
+    var xor = baseRest(function(arrays) {
+      return baseXor(arrayFilter(arrays, isArrayLikeObject));
+    });
+
+    /**
+     * This method is like `_.xor` except that it accepts `iteratee` which is
+     * invoked for each element of each `arrays` to generate the criterion by
+     * which by which they're compared. The order of result values is determined
+     * by the order they occur in the arrays. The iteratee is invoked with one
+     * argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {Array} Returns the new array of filtered values.
+     * @example
+     *
+     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
+     * // => [1.2, 3.4]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 2 }]
+     */
+    var xorBy = baseRest(function(arrays) {
+      var iteratee = last(arrays);
+      if (isArrayLikeObject(iteratee)) {
+        iteratee = undefined;
+      }
+      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
+    });
+
+    /**
+     * This method is like `_.xor` except that it accepts `comparator` which is
+     * invoked to compare elements of `arrays`. The order of result values is
+     * determined by the order they occur in the arrays. The comparator is invoked
+     * with two arguments: (arrVal, othVal).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Function} [comparator] The comparator invoked per element.
+     * @returns {Array} Returns the new array of filtered values.
+     * @example
+     *
+     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
+     *
+     * _.xorWith(objects, others, _.isEqual);
+     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
+     */
+    var xorWith = baseRest(function(arrays) {
+      var comparator = last(arrays);
+      comparator = typeof comparator == 'function' ? comparator : undefined;
+      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
+    });
+
+    /**
+     * Creates an array of grouped elements, the first of which contains the
+     * first elements of the given arrays, the second of which contains the
+     * second elements of the given arrays, and so on.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to process.
+     * @returns {Array} Returns the new array of grouped elements.
+     * @example
+     *
+     * _.zip(['a', 'b'], [1, 2], [true, false]);
+     * // => [['a', 1, true], ['b', 2, false]]
+     */
+    var zip = baseRest(unzip);
+
+    /**
+     * This method is like `_.fromPairs` except that it accepts two arrays,
+     * one of property identifiers and one of corresponding values.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.4.0
+     * @category Array
+     * @param {Array} [props=[]] The property identifiers.
+     * @param {Array} [values=[]] The property values.
+     * @returns {Object} Returns the new object.
+     * @example
+     *
+     * _.zipObject(['a', 'b'], [1, 2]);
+     * // => { 'a': 1, 'b': 2 }
+     */
+    function zipObject(props, values) {
+      return baseZipObject(props || [], values || [], assignValue);
+    }
+
+    /**
+     * This method is like `_.zipObject` except that it supports property paths.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.1.0
+     * @category Array
+     * @param {Array} [props=[]] The property identifiers.
+     * @param {Array} [values=[]] The property values.
+     * @returns {Object} Returns the new object.
+     * @example
+     *
+     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
+     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
+     */
+    function zipObjectDeep(props, values) {
+      return baseZipObject(props || [], values || [], baseSet);
+    }
+
+    /**
+     * This method is like `_.zip` except that it accepts `iteratee` to specify
+     * how grouped values should be combined. The iteratee is invoked with the
+     * elements of each group: (...group).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.8.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to process.
+     * @param {Function} [iteratee=_.identity] The function to combine
+     *  grouped values.
+     * @returns {Array} Returns the new array of grouped elements.
+     * @example
+     *
+     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
+     *   return a + b + c;
+     * });
+     * // => [111, 222]
+     */
+    var zipWith = baseRest(function(arrays) {
+      var length = arrays.length,
+          iteratee = length > 1 ? arrays[length - 1] : undefined;
+
+      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
+      return unzipWith(arrays, iteratee);
+    });
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
+     * chain sequences enabled. The result of such sequences must be unwrapped
+     * with `_#value`.
+     *
+     * @static
+     * @memberOf _
+     * @since 1.3.0
+     * @category Seq
+     * @param {*} value The value to wrap.
+     * @returns {Object} Returns the new `lodash` wrapper instance.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney',  'age': 36 },
+     *   { 'user': 'fred',    'age': 40 },
+     *   { 'user': 'pebbles', 'age': 1 }
+     * ];
+     *
+     * var youngest = _
+     *   .chain(users)
+     *   .sortBy('age')
+     *   .map(function(o) {
+     *     return o.user + ' is ' + o.age;
+     *   })
+     *   .head()
+     *   .value();
+     * // => 'pebbles is 1'
+     */
+    function chain(value) {
+      var result = lodash(value);
+      result.__chain__ = true;
+      return result;
+    }
+
+    /**
+     * This method invokes `interceptor` and returns `value`. The interceptor
+     * is invoked with one argument; (value). The purpose of this method is to
+     * "tap into" a method chain sequence in order to modify intermediate results.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Seq
+     * @param {*} value The value to provide to `interceptor`.
+     * @param {Function} interceptor The function to invoke.
+     * @returns {*} Returns `value`.
+     * @example
+     *
+     * _([1, 2, 3])
+     *  .tap(function(array) {
+     *    // Mutate input array.
+     *    array.pop();
+     *  })
+     *  .reverse()
+     *  .value();
+     * // => [2, 1]
+     */
+    function tap(value, interceptor) {
+      interceptor(value);
+      return value;
+    }
+
+    /**
+     * This method is like `_.tap` except that it returns the result of `interceptor`.
+     * The purpose of this method is to "pass thru" values replacing intermediate
+     * results in a method chain sequence.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Seq
+     * @param {*} value The value to provide to `interceptor`.
+     * @param {Function} interceptor The function to invoke.
+     * @returns {*} Returns the result of `interceptor`.
+     * @example
+     *
+     * _('  abc  ')
+     *  .chain()
+     *  .trim()
+     *  .thru(function(value) {
+     *    return [value];
+     *  })
+     *  .value();
+     * // => ['abc']
+     */
+    function thru(value, interceptor) {
+      return interceptor(value);
+    }
+
+    /**
+     * This method is the wrapper version of `_.at`.
+     *
+     * @name at
+     * @memberOf _
+     * @since 1.0.0
+     * @category Seq
+     * @param {...(string|string[])} [paths] The property paths to pick.
+     * @returns {Object} Returns the new `lodash` wrapper instance.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+     *
+     * _(object).at(['a[0].b.c', 'a[1]']).value();
+     * // => [3, 4]
+     */
+    var wrapperAt = flatRest(function(paths) {
+      var length = paths.length,
+          start = length ? paths[0] : 0,
+          value = this.__wrapped__,
+          interceptor = function(object) { return baseAt(object, paths); };
+
+      if (length > 1 || this.__actions__.length ||
+          !(value instanceof LazyWrapper) || !isIndex(start)) {
+        return this.thru(interceptor);
+      }
+      value = value.slice(start, +start + (length ? 1 : 0));
+      value.__actions__.push({
+        'func': thru,
+        'args': [interceptor],
+        'thisArg': undefined
+      });
+      return new LodashWrapper(value, this.__chain__).thru(function(array) {
+        if (length && !array.length) {
+          array.push(undefined);
+        }
+        return array;
+      });
+    });
+
+    /**
+     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
+     *
+     * @name chain
+     * @memberOf _
+     * @since 0.1.0
+     * @category Seq
+     * @returns {Object} Returns the new `lodash` wrapper instance.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney', 'age': 36 },
+     *   { 'user': 'fred',   'age': 40 }
+     * ];
+     *
+     * // A sequence without explicit chaining.
+     * _(users).head();
+     * // => { 'user': 'barney', 'age': 36 }
+     *
+     * // A sequence with explicit chaining.
+     * _(users)
+     *   .chain()
+     *   .head()
+     *   .pick('user')
+     *   .value();
+     * // => { 'user': 'barney' }
+     */
+    function wrapperChain() {
+      return chain(this);
+    }
+
+    /**
+     * Executes the chain sequence and returns the wrapped result.
+     *
+     * @name commit
+     * @memberOf _
+     * @since 3.2.0
+     * @category Seq
+     * @returns {Object} Returns the new `lodash` wrapper instance.
+     * @example
+     *
+     * var array = [1, 2];
+     * var wrapped = _(array).push(3);
+     *
+     * console.log(array);
+     * // => [1, 2]
+     *
+     * wrapped = wrapped.commit();
+     * console.log(array);
+     * // => [1, 2, 3]
+     *
+     * wrapped.last();
+     * // => 3
+     *
+     * console.log(array);
+     * // => [1, 2, 3]
+     */
+    function wrapperCommit() {
+      return new LodashWrapper(this.value(), this.__chain__);
+    }
+
+    /**
+     * Gets the next value on a wrapped object following the
+     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
+     *
+     * @name next
+     * @memberOf _
+     * @since 4.0.0
+     * @category Seq
+     * @returns {Object} Returns the next iterator value.
+     * @example
+     *
+     * var wrapped = _([1, 2]);
+     *
+     * wrapped.next();
+     * // => { 'done': false, 'value': 1 }
+     *
+     * wrapped.next();
+     * // => { 'done': false, 'value': 2 }
+     *
+     * wrapped.next();
+     * // => { 'done': true, 'value': undefined }
+     */
+    function wrapperNext() {
+      if (this.__values__ === undefined) {
+        this.__values__ = toArray(this.value());
+      }
+      var done = this.__index__ >= this.__values__.length,
+          value = done ? undefined : this.__values__[this.__index__++];
+
+      return { 'done': done, 'value': value };
+    }
+
+    /**
+     * Enables the wrapper to be iterable.
+     *
+     * @name Symbol.iterator
+     * @memberOf _
+     * @since 4.0.0
+     * @category Seq
+     * @returns {Object} Returns the wrapper object.
+     * @example
+     *
+     * var wrapped = _([1, 2]);
+     *
+     * wrapped[Symbol.iterator]() === wrapped;
+     * // => true
+     *
+     * Array.from(wrapped);
+     * // => [1, 2]
+     */
+    function wrapperToIterator() {
+      return this;
+    }
+
+    /**
+     * Creates a clone of the chain sequence planting `value` as the wrapped value.
+     *
+     * @name plant
+     * @memberOf _
+     * @since 3.2.0
+     * @category Seq
+     * @param {*} value The value to plant.
+     * @returns {Object} Returns the new `lodash` wrapper instance.
+     * @example
+     *
+     * function square(n) {
+     *   return n * n;
+     * }
+     *
+     * var wrapped = _([1, 2]).map(square);
+     * var other = wrapped.plant([3, 4]);
+     *
+     * other.value();
+     * // => [9, 16]
+     *
+     * wrapped.value();
+     * // => [1, 4]
+     */
+    function wrapperPlant(value) {
+      var result,
+          parent = this;
+
+      while (parent instanceof baseLodash) {
+        var clone = wrapperClone(parent);
+        clone.__index__ = 0;
+        clone.__values__ = undefined;
+        if (result) {
+          previous.__wrapped__ = clone;
+        } else {
+          result = clone;
+        }
+        var previous = clone;
+        parent = parent.__wrapped__;
+      }
+      previous.__wrapped__ = value;
+      return result;
+    }
+
+    /**
+     * This method is the wrapper version of `_.reverse`.
+     *
+     * **Note:** This method mutates the wrapped array.
+     *
+     * @name reverse
+     * @memberOf _
+     * @since 0.1.0
+     * @category Seq
+     * @returns {Object} Returns the new `lodash` wrapper instance.
+     * @example
+     *
+     * var array = [1, 2, 3];
+     *
+     * _(array).reverse().value()
+     * // => [3, 2, 1]
+     *
+     * console.log(array);
+     * // => [3, 2, 1]
+     */
+    function wrapperReverse() {
+      var value = this.__wrapped__;
+      if (value instanceof LazyWrapper) {
+        var wrapped = value;
+        if (this.__actions__.length) {
+          wrapped = new LazyWrapper(this);
+        }
+        wrapped = wrapped.reverse();
+        wrapped.__actions__.push({
+          'func': thru,
+          'args': [reverse],
+          'thisArg': undefined
+        });
+        return new LodashWrapper(wrapped, this.__chain__);
+      }
+      return this.thru(reverse);
+    }
+
+    /**
+     * Executes the chain sequence to resolve the unwrapped value.
+     *
+     * @name value
+     * @memberOf _
+     * @since 0.1.0
+     * @alias toJSON, valueOf
+     * @category Seq
+     * @returns {*} Returns the resolved unwrapped value.
+     * @example
+     *
+     * _([1, 2, 3]).value();
+     * // => [1, 2, 3]
+     */
+    function wrapperValue() {
+      return baseWrapperValue(this.__wrapped__, this.__actions__);
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates an object composed of keys generated from the results of running
+     * each element of `collection` thru `iteratee`. The corresponding value of
+     * each key is the number of times the key was returned by `iteratee`. The
+     * iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.5.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+     * @returns {Object} Returns the composed aggregate object.
+     * @example
+     *
+     * _.countBy([6.1, 4.2, 6.3], Math.floor);
+     * // => { '4': 1, '6': 2 }
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.countBy(['one', 'two', 'three'], 'length');
+     * // => { '3': 2, '5': 1 }
+     */
+    var countBy = createAggregator(function(result, value, key) {
+      if (hasOwnProperty.call(result, key)) {
+        ++result[key];
+      } else {
+        baseAssignValue(result, key, 1);
+      }
+    });
+
+    /**
+     * Checks if `predicate` returns truthy for **all** elements of `collection`.
+     * Iteration is stopped once `predicate` returns falsey. The predicate is
+     * invoked with three arguments: (value, index|key, collection).
+     *
+     * **Note:** This method returns `true` for
+     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
+     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
+     * elements of empty collections.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {boolean} Returns `true` if all elements pass the predicate check,
+     *  else `false`.
+     * @example
+     *
+     * _.every([true, 1, null, 'yes'], Boolean);
+     * // => false
+     *
+     * var users = [
+     *   { 'user': 'barney', 'age': 36, 'active': false },
+     *   { 'user': 'fred',   'age': 40, 'active': false }
+     * ];
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.every(users, { 'user': 'barney', 'active': false });
+     * // => false
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.every(users, ['active', false]);
+     * // => true
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.every(users, 'active');
+     * // => false
+     */
+    function every(collection, predicate, guard) {
+      var func = isArray(collection) ? arrayEvery : baseEvery;
+      if (guard && isIterateeCall(collection, predicate, guard)) {
+        predicate = undefined;
+      }
+      return func(collection, getIteratee(predicate, 3));
+    }
+
+    /**
+     * Iterates over elements of `collection`, returning an array of all elements
+     * `predicate` returns truthy for. The predicate is invoked with three
+     * arguments: (value, index|key, collection).
+     *
+     * **Note:** Unlike `_.remove`, this method returns a new array.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the new filtered array.
+     * @see _.reject
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney', 'age': 36, 'active': true },
+     *   { 'user': 'fred',   'age': 40, 'active': false }
+     * ];
+     *
+     * _.filter(users, function(o) { return !o.active; });
+     * // => objects for ['fred']
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.filter(users, { 'age': 36, 'active': true });
+     * // => objects for ['barney']
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.filter(users, ['active', false]);
+     * // => objects for ['fred']
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.filter(users, 'active');
+     * // => objects for ['barney']
+     */
+    function filter(collection, predicate) {
+      var func = isArray(collection) ? arrayFilter : baseFilter;
+      return func(collection, getIteratee(predicate, 3));
+    }
+
+    /**
+     * Iterates over elements of `collection`, returning the first element
+     * `predicate` returns truthy for. The predicate is invoked with three
+     * arguments: (value, index|key, collection).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to inspect.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @param {number} [fromIndex=0] The index to search from.
+     * @returns {*} Returns the matched element, else `undefined`.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney',  'age': 36, 'active': true },
+     *   { 'user': 'fred',    'age': 40, 'active': false },
+     *   { 'user': 'pebbles', 'age': 1,  'active': true }
+     * ];
+     *
+     * _.find(users, function(o) { return o.age < 40; });
+     * // => object for 'barney'
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.find(users, { 'age': 1, 'active': true });
+     * // => object for 'pebbles'
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.find(users, ['active', false]);
+     * // => object for 'fred'
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.find(users, 'active');
+     * // => object for 'barney'
+     */
+    var find = createFind(findIndex);
+
+    /**
+     * This method is like `_.find` except that it iterates over elements of
+     * `collection` from right to left.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to inspect.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @param {number} [fromIndex=collection.length-1] The index to search from.
+     * @returns {*} Returns the matched element, else `undefined`.
+     * @example
+     *
+     * _.findLast([1, 2, 3, 4], function(n) {
+     *   return n % 2 == 1;
+     * });
+     * // => 3
+     */
+    var findLast = createFind(findLastIndex);
+
+    /**
+     * Creates a flattened array of values by running each element in `collection`
+     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
+     * with three arguments: (value, index|key, collection).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the new flattened array.
+     * @example
+     *
+     * function duplicate(n) {
+     *   return [n, n];
+     * }
+     *
+     * _.flatMap([1, 2], duplicate);
+     * // => [1, 1, 2, 2]
+     */
+    function flatMap(collection, iteratee) {
+      return baseFlatten(map(collection, iteratee), 1);
+    }
+
+    /**
+     * This method is like `_.flatMap` except that it recursively flattens the
+     * mapped results.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.7.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the new flattened array.
+     * @example
+     *
+     * function duplicate(n) {
+     *   return [[[n, n]]];
+     * }
+     *
+     * _.flatMapDeep([1, 2], duplicate);
+     * // => [1, 1, 2, 2]
+     */
+    function flatMapDeep(collection, iteratee) {
+      return baseFlatten(map(collection, iteratee), INFINITY);
+    }
+
+    /**
+     * This method is like `_.flatMap` except that it recursively flattens the
+     * mapped results up to `depth` times.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.7.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @param {number} [depth=1] The maximum recursion depth.
+     * @returns {Array} Returns the new flattened array.
+     * @example
+     *
+     * function duplicate(n) {
+     *   return [[[n, n]]];
+     * }
+     *
+     * _.flatMapDepth([1, 2], duplicate, 2);
+     * // => [[1, 1], [2, 2]]
+     */
+    function flatMapDepth(collection, iteratee, depth) {
+      depth = depth === undefined ? 1 : toInteger(depth);
+      return baseFlatten(map(collection, iteratee), depth);
+    }
+
+    /**
+     * Iterates over elements of `collection` and invokes `iteratee` for each element.
+     * The iteratee is invoked with three arguments: (value, index|key, collection).
+     * Iteratee functions may exit iteration early by explicitly returning `false`.
+     *
+     * **Note:** As with other "Collections" methods, objects with a "length"
+     * property are iterated like arrays. To avoid this behavior use `_.forIn`
+     * or `_.forOwn` for object iteration.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @alias each
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Array|Object} Returns `collection`.
+     * @see _.forEachRight
+     * @example
+     *
+     * _.forEach([1, 2], function(value) {
+     *   console.log(value);
+     * });
+     * // => Logs `1` then `2`.
+     *
+     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
+     *   console.log(key);
+     * });
+     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
+     */
+    function forEach(collection, iteratee) {
+      var func = isArray(collection) ? arrayEach : baseEach;
+      return func(collection, getIteratee(iteratee, 3));
+    }
+
+    /**
+     * This method is like `_.forEach` except that it iterates over elements of
+     * `collection` from right to left.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @alias eachRight
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Array|Object} Returns `collection`.
+     * @see _.forEach
+     * @example
+     *
+     * _.forEachRight([1, 2], function(value) {
+     *   console.log(value);
+     * });
+     * // => Logs `2` then `1`.
+     */
+    function forEachRight(collection, iteratee) {
+      var func = isArray(collection) ? arrayEachRight : baseEachRight;
+      return func(collection, getIteratee(iteratee, 3));
+    }
+
+    /**
+     * Creates an object composed of keys generated from the results of running
+     * each element of `collection` thru `iteratee`. The order of grouped values
+     * is determined by the order they occur in `collection`. The corresponding
+     * value of each key is an array of elements responsible for generating the
+     * key. The iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+     * @returns {Object} Returns the composed aggregate object.
+     * @example
+     *
+     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
+     * // => { '4': [4.2], '6': [6.1, 6.3] }
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.groupBy(['one', 'two', 'three'], 'length');
+     * // => { '3': ['one', 'two'], '5': ['three'] }
+     */
+    var groupBy = createAggregator(function(result, value, key) {
+      if (hasOwnProperty.call(result, key)) {
+        result[key].push(value);
+      } else {
+        baseAssignValue(result, key, [value]);
+      }
+    });
+
+    /**
+     * Checks if `value` is in `collection`. If `collection` is a string, it's
+     * checked for a substring of `value`, otherwise
+     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * is used for equality comparisons. If `fromIndex` is negative, it's used as
+     * the offset from the end of `collection`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object|string} collection The collection to inspect.
+     * @param {*} value The value to search for.
+     * @param {number} [fromIndex=0] The index to search from.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
+     * @returns {boolean} Returns `true` if `value` is found, else `false`.
+     * @example
+     *
+     * _.includes([1, 2, 3], 1);
+     * // => true
+     *
+     * _.includes([1, 2, 3], 1, 2);
+     * // => false
+     *
+     * _.includes({ 'a': 1, 'b': 2 }, 1);
+     * // => true
+     *
+     * _.includes('abcd', 'bc');
+     * // => true
+     */
+    function includes(collection, value, fromIndex, guard) {
+      collection = isArrayLike(collection) ? collection : values(collection);
+      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
+
+      var length = collection.length;
+      if (fromIndex < 0) {
+        fromIndex = nativeMax(length + fromIndex, 0);
+      }
+      return isString(collection)
+        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
+        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
+    }
+
+    /**
+     * Invokes the method at `path` of each element in `collection`, returning
+     * an array of the results of each invoked method. Any additional arguments
+     * are provided to each invoked method. If `path` is a function, it's invoked
+     * for, and `this` bound to, each element in `collection`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Array|Function|string} path The path of the method to invoke or
+     *  the function invoked per iteration.
+     * @param {...*} [args] The arguments to invoke each method with.
+     * @returns {Array} Returns the array of results.
+     * @example
+     *
+     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
+     * // => [[1, 5, 7], [1, 2, 3]]
+     *
+     * _.invokeMap([123, 456], String.prototype.split, '');
+     * // => [['1', '2', '3'], ['4', '5', '6']]
+     */
+    var invokeMap = baseRest(function(collection, path, args) {
+      var index = -1,
+          isFunc = typeof path == 'function',
+          result = isArrayLike(collection) ? Array(collection.length) : [];
+
+      baseEach(collection, function(value) {
+        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
+      });
+      return result;
+    });
+
+    /**
+     * Creates an object composed of keys generated from the results of running
+     * each element of `collection` thru `iteratee`. The corresponding value of
+     * each key is the last element responsible for generating the key. The
+     * iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
+     * @returns {Object} Returns the composed aggregate object.
+     * @example
+     *
+     * var array = [
+     *   { 'dir': 'left', 'code': 97 },
+     *   { 'dir': 'right', 'code': 100 }
+     * ];
+     *
+     * _.keyBy(array, function(o) {
+     *   return String.fromCharCode(o.code);
+     * });
+     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+     *
+     * _.keyBy(array, 'dir');
+     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
+     */
+    var keyBy = createAggregator(function(result, value, key) {
+      baseAssignValue(result, key, value);
+    });
+
+    /**
+     * Creates an array of values by running each element in `collection` thru
+     * `iteratee`. The iteratee is invoked with three arguments:
+     * (value, index|key, collection).
+     *
+     * Many lodash methods are guarded to work as iteratees for methods like
+     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+     *
+     * The guarded methods are:
+     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
+     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
+     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
+     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the new mapped array.
+     * @example
+     *
+     * function square(n) {
+     *   return n * n;
+     * }
+     *
+     * _.map([4, 8], square);
+     * // => [16, 64]
+     *
+     * _.map({ 'a': 4, 'b': 8 }, square);
+     * // => [16, 64] (iteration order is not guaranteed)
+     *
+     * var users = [
+     *   { 'user': 'barney' },
+     *   { 'user': 'fred' }
+     * ];
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.map(users, 'user');
+     * // => ['barney', 'fred']
+     */
+    function map(collection, iteratee) {
+      var func = isArray(collection) ? arrayMap : baseMap;
+      return func(collection, getIteratee(iteratee, 3));
+    }
+
+    /**
+     * This method is like `_.sortBy` except that it allows specifying the sort
+     * orders of the iteratees to sort by. If `orders` is unspecified, all values
+     * are sorted in ascending order. Otherwise, specify an order of "desc" for
+     * descending or "asc" for ascending sort order of corresponding values.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
+     *  The iteratees to sort by.
+     * @param {string[]} [orders] The sort orders of `iteratees`.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
+     * @returns {Array} Returns the new sorted array.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'fred',   'age': 48 },
+     *   { 'user': 'barney', 'age': 34 },
+     *   { 'user': 'fred',   'age': 40 },
+     *   { 'user': 'barney', 'age': 36 }
+     * ];
+     *
+     * // Sort by `user` in ascending order and by `age` in descending order.
+     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
+     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+     */
+    function orderBy(collection, iteratees, orders, guard) {
+      if (collection == null) {
+        return [];
+      }
+      if (!isArray(iteratees)) {
+        iteratees = iteratees == null ? [] : [iteratees];
+      }
+      orders = guard ? undefined : orders;
+      if (!isArray(orders)) {
+        orders = orders == null ? [] : [orders];
+      }
+      return baseOrderBy(collection, iteratees, orders);
+    }
+
+    /**
+     * Creates an array of elements split into two groups, the first of which
+     * contains elements `predicate` returns truthy for, the second of which
+     * contains elements `predicate` returns falsey for. The predicate is
+     * invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the array of grouped elements.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney',  'age': 36, 'active': false },
+     *   { 'user': 'fred',    'age': 40, 'active': true },
+     *   { 'user': 'pebbles', 'age': 1,  'active': false }
+     * ];
+     *
+     * _.partition(users, function(o) { return o.active; });
+     * // => objects for [['fred'], ['barney', 'pebbles']]
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.partition(users, { 'age': 1, 'active': false });
+     * // => objects for [['pebbles'], ['barney', 'fred']]
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.partition(users, ['active', false]);
+     * // => objects for [['barney', 'pebbles'], ['fred']]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.partition(users, 'active');
+     * // => objects for [['fred'], ['barney', 'pebbles']]
+     */
+    var partition = createAggregator(function(result, value, key) {
+      result[key ? 0 : 1].push(value);
+    }, function() { return [[], []]; });
+
+    /**
+     * Reduces `collection` to a value which is the accumulated result of running
+     * each element in `collection` thru `iteratee`, where each successive
+     * invocation is supplied the return value of the previous. If `accumulator`
+     * is not given, the first element of `collection` is used as the initial
+     * value. The iteratee is invoked with four arguments:
+     * (accumulator, value, index|key, collection).
+     *
+     * Many lodash methods are guarded to work as iteratees for methods like
+     * `_.reduce`, `_.reduceRight`, and `_.transform`.
+     *
+     * The guarded methods are:
+     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
+     * and `sortBy`
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @param {*} [accumulator] The initial value.
+     * @returns {*} Returns the accumulated value.
+     * @see _.reduceRight
+     * @example
+     *
+     * _.reduce([1, 2], function(sum, n) {
+     *   return sum + n;
+     * }, 0);
+     * // => 3
+     *
+     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+     *   (result[value] || (result[value] = [])).push(key);
+     *   return result;
+     * }, {});
+     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
+     */
+    function reduce(collection, iteratee, accumulator) {
+      var func = isArray(collection) ? arrayReduce : baseReduce,
+          initAccum = arguments.length < 3;
+
+      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
+    }
+
+    /**
+     * This method is like `_.reduce` except that it iterates over elements of
+     * `collection` from right to left.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @param {*} [accumulator] The initial value.
+     * @returns {*} Returns the accumulated value.
+     * @see _.reduce
+     * @example
+     *
+     * var array = [[0, 1], [2, 3], [4, 5]];
+     *
+     * _.reduceRight(array, function(flattened, other) {
+     *   return flattened.concat(other);
+     * }, []);
+     * // => [4, 5, 2, 3, 0, 1]
+     */
+    function reduceRight(collection, iteratee, accumulator) {
+      var func = isArray(collection) ? arrayReduceRight : baseReduce,
+          initAccum = arguments.length < 3;
+
+      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
+    }
+
+    /**
+     * The opposite of `_.filter`; this method returns the elements of `collection`
+     * that `predicate` does **not** return truthy for.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the new filtered array.
+     * @see _.filter
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney', 'age': 36, 'active': false },
+     *   { 'user': 'fred',   'age': 40, 'active': true }
+     * ];
+     *
+     * _.reject(users, function(o) { return !o.active; });
+     * // => objects for ['fred']
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.reject(users, { 'age': 40, 'active': true });
+     * // => objects for ['barney']
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.reject(users, ['active', false]);
+     * // => objects for ['fred']
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.reject(users, 'active');
+     * // => objects for ['barney']
+     */
+    function reject(collection, predicate) {
+      var func = isArray(collection) ? arrayFilter : baseFilter;
+      return func(collection, negate(getIteratee(predicate, 3)));
+    }
+
+    /**
+     * Gets a random element from `collection`.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to sample.
+     * @returns {*} Returns the random element.
+     * @example
+     *
+     * _.sample([1, 2, 3, 4]);
+     * // => 2
+     */
+    function sample(collection) {
+      var func = isArray(collection) ? arraySample : baseSample;
+      return func(collection);
+    }
+
+    /**
+     * Gets `n` random elements at unique keys from `collection` up to the
+     * size of `collection`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to sample.
+     * @param {number} [n=1] The number of elements to sample.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Array} Returns the random elements.
+     * @example
+     *
+     * _.sampleSize([1, 2, 3], 2);
+     * // => [3, 1]
+     *
+     * _.sampleSize([1, 2, 3], 4);
+     * // => [2, 3, 1]
+     */
+    function sampleSize(collection, n, guard) {
+      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
+        n = 1;
+      } else {
+        n = toInteger(n);
+      }
+      var func = isArray(collection) ? arraySampleSize : baseSampleSize;
+      return func(collection, n);
+    }
+
+    /**
+     * Creates an array of shuffled values, using a version of the
+     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to shuffle.
+     * @returns {Array} Returns the new shuffled array.
+     * @example
+     *
+     * _.shuffle([1, 2, 3, 4]);
+     * // => [4, 1, 3, 2]
+     */
+    function shuffle(collection) {
+      var func = isArray(collection) ? arrayShuffle : baseShuffle;
+      return func(collection);
+    }
+
+    /**
+     * Gets the size of `collection` by returning its length for array-like
+     * values or the number of own enumerable string keyed properties for objects.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object|string} collection The collection to inspect.
+     * @returns {number} Returns the collection size.
+     * @example
+     *
+     * _.size([1, 2, 3]);
+     * // => 3
+     *
+     * _.size({ 'a': 1, 'b': 2 });
+     * // => 2
+     *
+     * _.size('pebbles');
+     * // => 7
+     */
+    function size(collection) {
+      if (collection == null) {
+        return 0;
+      }
+      if (isArrayLike(collection)) {
+        return isString(collection) ? stringSize(collection) : collection.length;
+      }
+      var tag = getTag(collection);
+      if (tag == mapTag || tag == setTag) {
+        return collection.size;
+      }
+      return baseKeys(collection).length;
+    }
+
+    /**
+     * Checks if `predicate` returns truthy for **any** element of `collection`.
+     * Iteration is stopped once `predicate` returns truthy. The predicate is
+     * invoked with three arguments: (value, index|key, collection).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {boolean} Returns `true` if any element passes the predicate check,
+     *  else `false`.
+     * @example
+     *
+     * _.some([null, 0, 'yes', false], Boolean);
+     * // => true
+     *
+     * var users = [
+     *   { 'user': 'barney', 'active': true },
+     *   { 'user': 'fred',   'active': false }
+     * ];
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.some(users, { 'user': 'barney', 'active': false });
+     * // => false
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.some(users, ['active', false]);
+     * // => true
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.some(users, 'active');
+     * // => true
+     */
+    function some(collection, predicate, guard) {
+      var func = isArray(collection) ? arraySome : baseSome;
+      if (guard && isIterateeCall(collection, predicate, guard)) {
+        predicate = undefined;
+      }
+      return func(collection, getIteratee(predicate, 3));
+    }
+
+    /**
+     * Creates an array of elements, sorted in ascending order by the results of
+     * running each element in a collection thru each iteratee. This method
+     * performs a stable sort, that is, it preserves the original sort order of
+     * equal elements. The iteratees are invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {...(Function|Function[])} [iteratees=[_.identity]]
+     *  The iteratees to sort by.
+     * @returns {Array} Returns the new sorted array.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'fred',   'age': 48 },
+     *   { 'user': 'barney', 'age': 36 },
+     *   { 'user': 'fred',   'age': 40 },
+     *   { 'user': 'barney', 'age': 34 }
+     * ];
+     *
+     * _.sortBy(users, [function(o) { return o.user; }]);
+     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+     *
+     * _.sortBy(users, ['user', 'age']);
+     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
+     */
+    var sortBy = baseRest(function(collection, iteratees) {
+      if (collection == null) {
+        return [];
+      }
+      var length = iteratees.length;
+      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
+        iteratees = [];
+      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
+        iteratees = [iteratees[0]];
+      }
+      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
+    });
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Gets the timestamp of the number of milliseconds that have elapsed since
+     * the Unix epoch (1 January 1970 00:00:00 UTC).
+     *
+     * @static
+     * @memberOf _
+     * @since 2.4.0
+     * @category Date
+     * @returns {number} Returns the timestamp.
+     * @example
+     *
+     * _.defer(function(stamp) {
+     *   console.log(_.now() - stamp);
+     * }, _.now());
+     * // => Logs the number of milliseconds it took for the deferred invocation.
+     */
+    var now = ctxNow || function() {
+      return root.Date.now();
+    };
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * The opposite of `_.before`; this method creates a function that invokes
+     * `func` once it's called `n` or more times.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Function
+     * @param {number} n The number of calls before `func` is invoked.
+     * @param {Function} func The function to restrict.
+     * @returns {Function} Returns the new restricted function.
+     * @example
+     *
+     * var saves = ['profile', 'settings'];
+     *
+     * var done = _.after(saves.length, function() {
+     *   console.log('done saving!');
+     * });
+     *
+     * _.forEach(saves, function(type) {
+     *   asyncSave({ 'type': type, 'complete': done });
+     * });
+     * // => Logs 'done saving!' after the two async saves have completed.
+     */
+    function after(n, func) {
+      if (typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      n = toInteger(n);
+      return function() {
+        if (--n < 1) {
+          return func.apply(this, arguments);
+        }
+      };
+    }
+
+    /**
+     * Creates a function that invokes `func`, with up to `n` arguments,
+     * ignoring any additional arguments.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Function
+     * @param {Function} func The function to cap arguments for.
+     * @param {number} [n=func.length] The arity cap.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Function} Returns the new capped function.
+     * @example
+     *
+     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
+     * // => [6, 8, 10]
+     */
+    function ary(func, n, guard) {
+      n = guard ? undefined : n;
+      n = (func && n == null) ? func.length : n;
+      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
+    }
+
+    /**
+     * Creates a function that invokes `func`, with the `this` binding and arguments
+     * of the created function, while it's called less than `n` times. Subsequent
+     * calls to the created function return the result of the last `func` invocation.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Function
+     * @param {number} n The number of calls at which `func` is no longer invoked.
+     * @param {Function} func The function to restrict.
+     * @returns {Function} Returns the new restricted function.
+     * @example
+     *
+     * jQuery(element).on('click', _.before(5, addContactToList));
+     * // => Allows adding up to 4 contacts to the list.
+     */
+    function before(n, func) {
+      var result;
+      if (typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      n = toInteger(n);
+      return function() {
+        if (--n > 0) {
+          result = func.apply(this, arguments);
+        }
+        if (n <= 1) {
+          func = undefined;
+        }
+        return result;
+      };
+    }
+
+    /**
+     * Creates a function that invokes `func` with the `this` binding of `thisArg`
+     * and `partials` prepended to the arguments it receives.
+     *
+     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
+     * may be used as a placeholder for partially applied arguments.
+     *
+     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
+     * property of bound functions.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Function
+     * @param {Function} func The function to bind.
+     * @param {*} thisArg The `this` binding of `func`.
+     * @param {...*} [partials] The arguments to be partially applied.
+     * @returns {Function} Returns the new bound function.
+     * @example
+     *
+     * function greet(greeting, punctuation) {
+     *   return greeting + ' ' + this.user + punctuation;
+     * }
+     *
+     * var object = { 'user': 'fred' };
+     *
+     * var bound = _.bind(greet, object, 'hi');
+     * bound('!');
+     * // => 'hi fred!'
+     *
+     * // Bound with placeholders.
+     * var bound = _.bind(greet, object, _, '!');
+     * bound('hi');
+     * // => 'hi fred!'
+     */
+    var bind = baseRest(function(func, thisArg, partials) {
+      var bitmask = WRAP_BIND_FLAG;
+      if (partials.length) {
+        var holders = replaceHolders(partials, getHolder(bind));
+        bitmask |= WRAP_PARTIAL_FLAG;
+      }
+      return createWrap(func, bitmask, thisArg, partials, holders);
+    });
+
+    /**
+     * Creates a function that invokes the method at `object[key]` with `partials`
+     * prepended to the arguments it receives.
+     *
+     * This method differs from `_.bind` by allowing bound functions to reference
+     * methods that may be redefined or don't yet exist. See
+     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
+     * for more details.
+     *
+     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
+     * builds, may be used as a placeholder for partially applied arguments.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.10.0
+     * @category Function
+     * @param {Object} object The object to invoke the method on.
+     * @param {string} key The key of the method.
+     * @param {...*} [partials] The arguments to be partially applied.
+     * @returns {Function} Returns the new bound function.
+     * @example
+     *
+     * var object = {
+     *   'user': 'fred',
+     *   'greet': function(greeting, punctuation) {
+     *     return greeting + ' ' + this.user + punctuation;
+     *   }
+     * };
+     *
+     * var bound = _.bindKey(object, 'greet', 'hi');
+     * bound('!');
+     * // => 'hi fred!'
+     *
+     * object.greet = function(greeting, punctuation) {
+     *   return greeting + 'ya ' + this.user + punctuation;
+     * };
+     *
+     * bound('!');
+     * // => 'hiya fred!'
+     *
+     * // Bound with placeholders.
+     * var bound = _.bindKey(object, 'greet', _, '!');
+     * bound('hi');
+     * // => 'hiya fred!'
+     */
+    var bindKey = baseRest(function(object, key, partials) {
+      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
+      if (partials.length) {
+        var holders = replaceHolders(partials, getHolder(bindKey));
+        bitmask |= WRAP_PARTIAL_FLAG;
+      }
+      return createWrap(key, bitmask, object, partials, holders);
+    });
+
+    /**
+     * Creates a function that accepts arguments of `func` and either invokes
+     * `func` returning its result, if at least `arity` number of arguments have
+     * been provided, or returns a function that accepts the remaining `func`
+     * arguments, and so on. The arity of `func` may be specified if `func.length`
+     * is not sufficient.
+     *
+     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
+     * may be used as a placeholder for provided arguments.
+     *
+     * **Note:** This method doesn't set the "length" property of curried functions.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @category Function
+     * @param {Function} func The function to curry.
+     * @param {number} [arity=func.length] The arity of `func`.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Function} Returns the new curried function.
+     * @example
+     *
+     * var abc = function(a, b, c) {
+     *   return [a, b, c];
+     * };
+     *
+     * var curried = _.curry(abc);
+     *
+     * curried(1)(2)(3);
+     * // => [1, 2, 3]
+     *
+     * curried(1, 2)(3);
+     * // => [1, 2, 3]
+     *
+     * curried(1, 2, 3);
+     * // => [1, 2, 3]
+     *
+     * // Curried with placeholders.
+     * curried(1)(_, 3)(2);
+     * // => [1, 2, 3]
+     */
+    function curry(func, arity, guard) {
+      arity = guard ? undefined : arity;
+      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
+      result.placeholder = curry.placeholder;
+      return result;
+    }
+
+    /**
+     * This method is like `_.curry` except that arguments are applied to `func`
+     * in the manner of `_.partialRight` instead of `_.partial`.
+     *
+     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
+     * builds, may be used as a placeholder for provided arguments.
+     *
+     * **Note:** This method doesn't set the "length" property of curried functions.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Function
+     * @param {Function} func The function to curry.
+     * @param {number} [arity=func.length] The arity of `func`.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Function} Returns the new curried function.
+     * @example
+     *
+     * var abc = function(a, b, c) {
+     *   return [a, b, c];
+     * };
+     *
+     * var curried = _.curryRight(abc);
+     *
+     * curried(3)(2)(1);
+     * // => [1, 2, 3]
+     *
+     * curried(2, 3)(1);
+     * // => [1, 2, 3]
+     *
+     * curried(1, 2, 3);
+     * // => [1, 2, 3]
+     *
+     * // Curried with placeholders.
+     * curried(3)(1, _)(2);
+     * // => [1, 2, 3]
+     */
+    function curryRight(func, arity, guard) {
+      arity = guard ? undefined : arity;
+      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
+      result.placeholder = curryRight.placeholder;
+      return result;
+    }
+
+    /**
+     * Creates a debounced function that delays invoking `func` until after `wait`
+     * milliseconds have elapsed since the last time the debounced function was
+     * invoked. The debounced function comes with a `cancel` method to cancel
+     * delayed `func` invocations and a `flush` method to immediately invoke them.
+     * Provide `options` to indicate whether `func` should be invoked on the
+     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
+     * with the last arguments provided to the debounced function. Subsequent
+     * calls to the debounced function return the result of the last `func`
+     * invocation.
+     *
+     * **Note:** If `leading` and `trailing` options are `true`, `func` is
+     * invoked on the trailing edge of the timeout only if the debounced function
+     * is invoked more than once during the `wait` timeout.
+     *
+     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+     *
+     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+     * for details over the differences between `_.debounce` and `_.throttle`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Function
+     * @param {Function} func The function to debounce.
+     * @param {number} [wait=0] The number of milliseconds to delay.
+     * @param {Object} [options={}] The options object.
+     * @param {boolean} [options.leading=false]
+     *  Specify invoking on the leading edge of the timeout.
+     * @param {number} [options.maxWait]
+     *  The maximum time `func` is allowed to be delayed before it's invoked.
+     * @param {boolean} [options.trailing=true]
+     *  Specify invoking on the trailing edge of the timeout.
+     * @returns {Function} Returns the new debounced function.
+     * @example
+     *
+     * // Avoid costly calculations while the window size is in flux.
+     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
+     *
+     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
+     * jQuery(element).on('click', _.debounce(sendMail, 300, {
+     *   'leading': true,
+     *   'trailing': false
+     * }));
+     *
+     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
+     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
+     * var source = new EventSource('/stream');
+     * jQuery(source).on('message', debounced);
+     *
+     * // Cancel the trailing debounced invocation.
+     * jQuery(window).on('popstate', debounced.cancel);
+     */
+    function debounce(func, wait, options) {
+      var lastArgs,
+          lastThis,
+          maxWait,
+          result,
+          timerId,
+          lastCallTime,
+          lastInvokeTime = 0,
+          leading = false,
+          maxing = false,
+          trailing = true;
+
+      if (typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      wait = toNumber(wait) || 0;
+      if (isObject(options)) {
+        leading = !!options.leading;
+        maxing = 'maxWait' in options;
+        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
+        trailing = 'trailing' in options ? !!options.trailing : trailing;
+      }
+
+      function invokeFunc(time) {
+        var args = lastArgs,
+            thisArg = lastThis;
+
+        lastArgs = lastThis = undefined;
+        lastInvokeTime = time;
+        result = func.apply(thisArg, args);
+        return result;
+      }
+
+      function leadingEdge(time) {
+        // Reset any `maxWait` timer.
+        lastInvokeTime = time;
+        // Start the timer for the trailing edge.
+        timerId = setTimeout(timerExpired, wait);
+        // Invoke the leading edge.
+        return leading ? invokeFunc(time) : result;
+      }
+
+      function remainingWait(time) {
+        var timeSinceLastCall = time - lastCallTime,
+            timeSinceLastInvoke = time - lastInvokeTime,
+            result = wait - timeSinceLastCall;
+
+        return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
+      }
+
+      function shouldInvoke(time) {
+        var timeSinceLastCall = time - lastCallTime,
+            timeSinceLastInvoke = time - lastInvokeTime;
+
+        // Either this is the first call, activity has stopped and we're at the
+        // trailing edge, the system time has gone backwards and we're treating
+        // it as the trailing edge, or we've hit the `maxWait` limit.
+        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
+          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
+      }
+
+      function timerExpired() {
+        var time = now();
+        if (shouldInvoke(time)) {
+          return trailingEdge(time);
+        }
+        // Restart the timer.
+        timerId = setTimeout(timerExpired, remainingWait(time));
+      }
+
+      function trailingEdge(time) {
+        timerId = undefined;
+
+        // Only invoke if we have `lastArgs` which means `func` has been
+        // debounced at least once.
+        if (trailing && lastArgs) {
+          return invokeFunc(time);
+        }
+        lastArgs = lastThis = undefined;
+        return result;
+      }
+
+      function cancel() {
+        if (timerId !== undefined) {
+          clearTimeout(timerId);
+        }
+        lastInvokeTime = 0;
+        lastArgs = lastCallTime = lastThis = timerId = undefined;
+      }
+
+      function flush() {
+        return timerId === undefined ? result : trailingEdge(now());
+      }
+
+      function debounced() {
+        var time = now(),
+            isInvoking = shouldInvoke(time);
+
+        lastArgs = arguments;
+        lastThis = this;
+        lastCallTime = time;
+
+        if (isInvoking) {
+          if (timerId === undefined) {
+            return leadingEdge(lastCallTime);
+          }
+          if (maxing) {
+            // Handle invocations in a tight loop.
+            timerId = setTimeout(timerExpired, wait);
+            return invokeFunc(lastCallTime);
+          }
+        }
+        if (timerId === undefined) {
+          timerId = setTimeout(timerExpired, wait);
+        }
+        return result;
+      }
+      debounced.cancel = cancel;
+      debounced.flush = flush;
+      return debounced;
+    }
+
+    /**
+     * Defers invoking the `func` until the current call stack has cleared. Any
+     * additional arguments are provided to `func` when it's invoked.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Function
+     * @param {Function} func The function to defer.
+     * @param {...*} [args] The arguments to invoke `func` with.
+     * @returns {number} Returns the timer id.
+     * @example
+     *
+     * _.defer(function(text) {
+     *   console.log(text);
+     * }, 'deferred');
+     * // => Logs 'deferred' after one millisecond.
+     */
+    var defer = baseRest(function(func, args) {
+      return baseDelay(func, 1, args);
+    });
+
+    /**
+     * Invokes `func` after `wait` milliseconds. Any additional arguments are
+     * provided to `func` when it's invoked.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Function
+     * @param {Function} func The function to delay.
+     * @param {number} wait The number of milliseconds to delay invocation.
+     * @param {...*} [args] The arguments to invoke `func` with.
+     * @returns {number} Returns the timer id.
+     * @example
+     *
+     * _.delay(function(text) {
+     *   console.log(text);
+     * }, 1000, 'later');
+     * // => Logs 'later' after one second.
+     */
+    var delay = baseRest(function(func, wait, args) {
+      return baseDelay(func, toNumber(wait) || 0, args);
+    });
+
+    /**
+     * Creates a function that invokes `func` with arguments reversed.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Function
+     * @param {Function} func The function to flip arguments for.
+     * @returns {Function} Returns the new flipped function.
+     * @example
+     *
+     * var flipped = _.flip(function() {
+     *   return _.toArray(arguments);
+     * });
+     *
+     * flipped('a', 'b', 'c', 'd');
+     * // => ['d', 'c', 'b', 'a']
+     */
+    function flip(func) {
+      return createWrap(func, WRAP_FLIP_FLAG);
+    }
+
+    /**
+     * Creates a function that memoizes the result of `func`. If `resolver` is
+     * provided, it determines the cache key for storing the result based on the
+     * arguments provided to the memoized function. By default, the first argument
+     * provided to the memoized function is used as the map cache key. The `func`
+     * is invoked with the `this` binding of the memoized function.
+     *
+     * **Note:** The cache is exposed as the `cache` property on the memoized
+     * function. Its creation may be customized by replacing the `_.memoize.Cache`
+     * constructor with one whose instances implement the
+     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
+     * method interface of `clear`, `delete`, `get`, `has`, and `set`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Function
+     * @param {Function} func The function to have its output memoized.
+     * @param {Function} [resolver] The function to resolve the cache key.
+     * @returns {Function} Returns the new memoized function.
+     * @example
+     *
+     * var object = { 'a': 1, 'b': 2 };
+     * var other = { 'c': 3, 'd': 4 };
+     *
+     * var values = _.memoize(_.values);
+     * values(object);
+     * // => [1, 2]
+     *
+     * values(other);
+     * // => [3, 4]
+     *
+     * object.a = 2;
+     * values(object);
+     * // => [1, 2]
+     *
+     * // Modify the result cache.
+     * values.cache.set(object, ['a', 'b']);
+     * values(object);
+     * // => ['a', 'b']
+     *
+     * // Replace `_.memoize.Cache`.
+     * _.memoize.Cache = WeakMap;
+     */
+    function memoize(func, resolver) {
+      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      var memoized = function() {
+        var args = arguments,
+            key = resolver ? resolver.apply(this, args) : args[0],
+            cache = memoized.cache;
+
+        if (cache.has(key)) {
+          return cache.get(key);
+        }
+        var result = func.apply(this, args);
+        memoized.cache = cache.set(key, result) || cache;
+        return result;
+      };
+      memoized.cache = new (memoize.Cache || MapCache);
+      return memoized;
+    }
+
+    // Expose `MapCache`.
+    memoize.Cache = MapCache;
+
+    /**
+     * Creates a function that negates the result of the predicate `func`. The
+     * `func` predicate is invoked with the `this` binding and arguments of the
+     * created function.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Function
+     * @param {Function} predicate The predicate to negate.
+     * @returns {Function} Returns the new negated function.
+     * @example
+     *
+     * function isEven(n) {
+     *   return n % 2 == 0;
+     * }
+     *
+     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
+     * // => [1, 3, 5]
+     */
+    function negate(predicate) {
+      if (typeof predicate != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      return function() {
+        var args = arguments;
+        switch (args.length) {
+          case 0: return !predicate.call(this);
+          case 1: return !predicate.call(this, args[0]);
+          case 2: return !predicate.call(this, args[0], args[1]);
+          case 3: return !predicate.call(this, args[0], args[1], args[2]);
+        }
+        return !predicate.apply(this, args);
+      };
+    }
+
+    /**
+     * Creates a function that is restricted to invoking `func` once. Repeat calls
+     * to the function return the value of the first invocation. The `func` is
+     * invoked with the `this` binding and arguments of the created function.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Function
+     * @param {Function} func The function to restrict.
+     * @returns {Function} Returns the new restricted function.
+     * @example
+     *
+     * var initialize = _.once(createApplication);
+     * initialize();
+     * initialize();
+     * // => `createApplication` is invoked once
+     */
+    function once(func) {
+      return before(2, func);
+    }
+
+    /**
+     * Creates a function that invokes `func` with its arguments transformed.
+     *
+     * @static
+     * @since 4.0.0
+     * @memberOf _
+     * @category Function
+     * @param {Function} func The function to wrap.
+     * @param {...(Function|Function[])} [transforms=[_.identity]]
+     *  The argument transforms.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * function doubled(n) {
+     *   return n * 2;
+     * }
+     *
+     * function square(n) {
+     *   return n * n;
+     * }
+     *
+     * var func = _.overArgs(function(x, y) {
+     *   return [x, y];
+     * }, [square, doubled]);
+     *
+     * func(9, 3);
+     * // => [81, 6]
+     *
+     * func(10, 5);
+     * // => [100, 10]
+     */
+    var overArgs = castRest(function(func, transforms) {
+      transforms = (transforms.length == 1 && isArray(transforms[0]))
+        ? arrayMap(transforms[0], baseUnary(getIteratee()))
+        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
+
+      var funcsLength = transforms.length;
+      return baseRest(function(args) {
+        var index = -1,
+            length = nativeMin(args.length, funcsLength);
+
+        while (++index < length) {
+          args[index] = transforms[index].call(this, args[index]);
+        }
+        return apply(func, this, args);
+      });
+    });
+
+    /**
+     * Creates a function that invokes `func` with `partials` prepended to the
+     * arguments it receives. This method is like `_.bind` except it does **not**
+     * alter the `this` binding.
+     *
+     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
+     * builds, may be used as a placeholder for partially applied arguments.
+     *
+     * **Note:** This method doesn't set the "length" property of partially
+     * applied functions.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.2.0
+     * @category Function
+     * @param {Function} func The function to partially apply arguments to.
+     * @param {...*} [partials] The arguments to be partially applied.
+     * @returns {Function} Returns the new partially applied function.
+     * @example
+     *
+     * function greet(greeting, name) {
+     *   return greeting + ' ' + name;
+     * }
+     *
+     * var sayHelloTo = _.partial(greet, 'hello');
+     * sayHelloTo('fred');
+     * // => 'hello fred'
+     *
+     * // Partially applied with placeholders.
+     * var greetFred = _.partial(greet, _, 'fred');
+     * greetFred('hi');
+     * // => 'hi fred'
+     */
+    var partial = baseRest(function(func, partials) {
+      var holders = replaceHolders(partials, getHolder(partial));
+      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
+    });
+
+    /**
+     * This method is like `_.partial` except that partially applied arguments
+     * are appended to the arguments it receives.
+     *
+     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
+     * builds, may be used as a placeholder for partially applied arguments.
+     *
+     * **Note:** This method doesn't set the "length" property of partially
+     * applied functions.
+     *
+     * @static
+     * @memberOf _
+     * @since 1.0.0
+     * @category Function
+     * @param {Function} func The function to partially apply arguments to.
+     * @param {...*} [partials] The arguments to be partially applied.
+     * @returns {Function} Returns the new partially applied function.
+     * @example
+     *
+     * function greet(greeting, name) {
+     *   return greeting + ' ' + name;
+     * }
+     *
+     * var greetFred = _.partialRight(greet, 'fred');
+     * greetFred('hi');
+     * // => 'hi fred'
+     *
+     * // Partially applied with placeholders.
+     * var sayHelloTo = _.partialRight(greet, 'hello', _);
+     * sayHelloTo('fred');
+     * // => 'hello fred'
+     */
+    var partialRight = baseRest(function(func, partials) {
+      var holders = replaceHolders(partials, getHolder(partialRight));
+      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
+    });
+
+    /**
+     * Creates a function that invokes `func` with arguments arranged according
+     * to the specified `indexes` where the argument value at the first index is
+     * provided as the first argument, the argument value at the second index is
+     * provided as the second argument, and so on.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Function
+     * @param {Function} func The function to rearrange arguments for.
+     * @param {...(number|number[])} indexes The arranged argument indexes.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var rearged = _.rearg(function(a, b, c) {
+     *   return [a, b, c];
+     * }, [2, 0, 1]);
+     *
+     * rearged('b', 'c', 'a')
+     * // => ['a', 'b', 'c']
+     */
+    var rearg = flatRest(function(func, indexes) {
+      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
+    });
+
+    /**
+     * Creates a function that invokes `func` with the `this` binding of the
+     * created function and arguments from `start` and beyond provided as
+     * an array.
+     *
+     * **Note:** This method is based on the
+     * [rest parameter](https://mdn.io/rest_parameters).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Function
+     * @param {Function} func The function to apply a rest parameter to.
+     * @param {number} [start=func.length-1] The start position of the rest parameter.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var say = _.rest(function(what, names) {
+     *   return what + ' ' + _.initial(names).join(', ') +
+     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+     * });
+     *
+     * say('hello', 'fred', 'barney', 'pebbles');
+     * // => 'hello fred, barney, & pebbles'
+     */
+    function rest(func, start) {
+      if (typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      start = start === undefined ? start : toInteger(start);
+      return baseRest(func, start);
+    }
+
+    /**
+     * Creates a function that invokes `func` with the `this` binding of the
+     * create function and an array of arguments much like
+     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
+     *
+     * **Note:** This method is based on the
+     * [spread operator](https://mdn.io/spread_operator).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.2.0
+     * @category Function
+     * @param {Function} func The function to spread arguments over.
+     * @param {number} [start=0] The start position of the spread.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var say = _.spread(function(who, what) {
+     *   return who + ' says ' + what;
+     * });
+     *
+     * say(['fred', 'hello']);
+     * // => 'fred says hello'
+     *
+     * var numbers = Promise.all([
+     *   Promise.resolve(40),
+     *   Promise.resolve(36)
+     * ]);
+     *
+     * numbers.then(_.spread(function(x, y) {
+     *   return x + y;
+     * }));
+     * // => a Promise of 76
+     */
+    function spread(func, start) {
+      if (typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      start = start == null ? 0 : nativeMax(toInteger(start), 0);
+      return baseRest(function(args) {
+        var array = args[start],
+            otherArgs = castSlice(args, 0, start);
+
+        if (array) {
+          arrayPush(otherArgs, array);
+        }
+        return apply(func, this, otherArgs);
+      });
+    }
+
+    /**
+     * Creates a throttled function that only invokes `func` at most once per
+     * every `wait` milliseconds. The throttled function comes with a `cancel`
+     * method to cancel delayed `func` invocations and a `flush` method to
+     * immediately invoke them. Provide `options` to indicate whether `func`
+     * should be invoked on the leading and/or trailing edge of the `wait`
+     * timeout. The `func` is invoked with the last arguments provided to the
+     * throttled function. Subsequent calls to the throttled function return the
+     * result of the last `func` invocation.
+     *
+     * **Note:** If `leading` and `trailing` options are `true`, `func` is
+     * invoked on the trailing edge of the timeout only if the throttled function
+     * is invoked more than once during the `wait` timeout.
+     *
+     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+     *
+     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+     * for details over the differences between `_.throttle` and `_.debounce`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Function
+     * @param {Function} func The function to throttle.
+     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
+     * @param {Object} [options={}] The options object.
+     * @param {boolean} [options.leading=true]
+     *  Specify invoking on the leading edge of the timeout.
+     * @param {boolean} [options.trailing=true]
+     *  Specify invoking on the trailing edge of the timeout.
+     * @returns {Function} Returns the new throttled function.
+     * @example
+     *
+     * // Avoid excessively updating the position while scrolling.
+     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
+     *
+     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
+     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
+     * jQuery(element).on('click', throttled);
+     *
+     * // Cancel the trailing throttled invocation.
+     * jQuery(window).on('popstate', throttled.cancel);
+     */
+    function throttle(func, wait, options) {
+      var leading = true,
+          trailing = true;
+
+      if (typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      if (isObject(options)) {
+        leading = 'leading' in options ? !!options.leading : leading;
+        trailing = 'trailing' in options ? !!options.trailing : trailing;
+      }
+      return debounce(func, wait, {
+        'leading': leading,
+        'maxWait': wait,
+        'trailing': trailing
+      });
+    }
+
+    /**
+     * Creates a function that accepts up to one argument, ignoring any
+     * additional arguments.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Function
+     * @param {Function} func The function to cap arguments for.
+     * @returns {Function} Returns the new capped function.
+     * @example
+     *
+     * _.map(['6', '8', '10'], _.unary(parseInt));
+     * // => [6, 8, 10]
+     */
+    function unary(func) {
+      return ary(func, 1);
+    }
+
+    /**
+     * Creates a function that provides `value` to `wrapper` as its first
+     * argument. Any additional arguments provided to the function are appended
+     * to those provided to the `wrapper`. The wrapper is invoked with the `this`
+     * binding of the created function.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Function
+     * @param {*} value The value to wrap.
+     * @param {Function} [wrapper=identity] The wrapper function.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var p = _.wrap(_.escape, function(func, text) {
+     *   return '<p>' + func(text) + '</p>';
+     * });
+     *
+     * p('fred, barney, & pebbles');
+     * // => '<p>fred, barney, &amp; pebbles</p>'
+     */
+    function wrap(value, wrapper) {
+      return partial(castFunction(wrapper), value);
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Casts `value` as an array if it's not one.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.4.0
+     * @category Lang
+     * @param {*} value The value to inspect.
+     * @returns {Array} Returns the cast array.
+     * @example
+     *
+     * _.castArray(1);
+     * // => [1]
+     *
+     * _.castArray({ 'a': 1 });
+     * // => [{ 'a': 1 }]
+     *
+     * _.castArray('abc');
+     * // => ['abc']
+     *
+     * _.castArray(null);
+     * // => [null]
+     *
+     * _.castArray(undefined);
+     * // => [undefined]
+     *
+     * _.castArray();
+     * // => []
+     *
+     * var array = [1, 2, 3];
+     * console.log(_.castArray(array) === array);
+     * // => true
+     */
+    function castArray() {
+      if (!arguments.length) {
+        return [];
+      }
+      var value = arguments[0];
+      return isArray(value) ? value : [value];
+    }
+
+    /**
+     * Creates a shallow clone of `value`.
+     *
+     * **Note:** This method is loosely based on the
+     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
+     * and supports cloning arrays, array buffers, booleans, date objects, maps,
+     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
+     * arrays. The own enumerable properties of `arguments` objects are cloned
+     * as plain objects. An empty object is returned for uncloneable values such
+     * as error objects, functions, DOM nodes, and WeakMaps.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to clone.
+     * @returns {*} Returns the cloned value.
+     * @see _.cloneDeep
+     * @example
+     *
+     * var objects = [{ 'a': 1 }, { 'b': 2 }];
+     *
+     * var shallow = _.clone(objects);
+     * console.log(shallow[0] === objects[0]);
+     * // => true
+     */
+    function clone(value) {
+      return baseClone(value, CLONE_SYMBOLS_FLAG);
+    }
+
+    /**
+     * This method is like `_.clone` except that it accepts `customizer` which
+     * is invoked to produce the cloned value. If `customizer` returns `undefined`,
+     * cloning is handled by the method instead. The `customizer` is invoked with
+     * up to four arguments; (value [, index|key, object, stack]).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to clone.
+     * @param {Function} [customizer] The function to customize cloning.
+     * @returns {*} Returns the cloned value.
+     * @see _.cloneDeepWith
+     * @example
+     *
+     * function customizer(value) {
+     *   if (_.isElement(value)) {
+     *     return value.cloneNode(false);
+     *   }
+     * }
+     *
+     * var el = _.cloneWith(document.body, customizer);
+     *
+     * console.log(el === document.body);
+     * // => false
+     * console.log(el.nodeName);
+     * // => 'BODY'
+     * console.log(el.childNodes.length);
+     * // => 0
+     */
+    function cloneWith(value, customizer) {
+      customizer = typeof customizer == 'function' ? customizer : undefined;
+      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
+    }
+
+    /**
+     * This method is like `_.clone` except that it recursively clones `value`.
+     *
+     * @static
+     * @memberOf _
+     * @since 1.0.0
+     * @category Lang
+     * @param {*} value The value to recursively clone.
+     * @returns {*} Returns the deep cloned value.
+     * @see _.clone
+     * @example
+     *
+     * var objects = [{ 'a': 1 }, { 'b': 2 }];
+     *
+     * var deep = _.cloneDeep(objects);
+     * console.log(deep[0] === objects[0]);
+     * // => false
+     */
+    function cloneDeep(value) {
+      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
+    }
+
+    /**
+     * This method is like `_.cloneWith` except that it recursively clones `value`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to recursively clone.
+     * @param {Function} [customizer] The function to customize cloning.
+     * @returns {*} Returns the deep cloned value.
+     * @see _.cloneWith
+     * @example
+     *
+     * function customizer(value) {
+     *   if (_.isElement(value)) {
+     *     return value.cloneNode(true);
+     *   }
+     * }
+     *
+     * var el = _.cloneDeepWith(document.body, customizer);
+     *
+     * console.log(el === document.body);
+     * // => false
+     * console.log(el.nodeName);
+     * // => 'BODY'
+     * console.log(el.childNodes.length);
+     * // => 20
+     */
+    function cloneDeepWith(value, customizer) {
+      customizer = typeof customizer == 'function' ? customizer : undefined;
+      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
+    }
+
+    /**
+     * Checks if `object` conforms to `source` by invoking the predicate
+     * properties of `source` with the corresponding property values of `object`.
+     *
+     * **Note:** This method is equivalent to `_.conforms` when `source` is
+     * partially applied.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.14.0
+     * @category Lang
+     * @param {Object} object The object to inspect.
+     * @param {Object} source The object of property predicates to conform to.
+     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
+     * @example
+     *
+     * var object = { 'a': 1, 'b': 2 };
+     *
+     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
+     * // => true
+     *
+     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
+     * // => false
+     */
+    function conformsTo(object, source) {
+      return source == null || baseConformsTo(object, source, keys(source));
+    }
+
+    /**
+     * Performs a
+     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+     * comparison between two values to determine if they are equivalent.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+     * @example
+     *
+     * var object = { 'a': 1 };
+     * var other = { 'a': 1 };
+     *
+     * _.eq(object, object);
+     * // => true
+     *
+     * _.eq(object, other);
+     * // => false
+     *
+     * _.eq('a', 'a');
+     * // => true
+     *
+     * _.eq('a', Object('a'));
+     * // => false
+     *
+     * _.eq(NaN, NaN);
+     * // => true
+     */
+    function eq(value, other) {
+      return value === other || (value !== value && other !== other);
+    }
+
+    /**
+     * Checks if `value` is greater than `other`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.9.0
+     * @category Lang
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @returns {boolean} Returns `true` if `value` is greater than `other`,
+     *  else `false`.
+     * @see _.lt
+     * @example
+     *
+     * _.gt(3, 1);
+     * // => true
+     *
+     * _.gt(3, 3);
+     * // => false
+     *
+     * _.gt(1, 3);
+     * // => false
+     */
+    var gt = createRelationalOperation(baseGt);
+
+    /**
+     * Checks if `value` is greater than or equal to `other`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.9.0
+     * @category Lang
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @returns {boolean} Returns `true` if `value` is greater than or equal to
+     *  `other`, else `false`.
+     * @see _.lte
+     * @example
+     *
+     * _.gte(3, 1);
+     * // => true
+     *
+     * _.gte(3, 3);
+     * // => true
+     *
+     * _.gte(1, 3);
+     * // => false
+     */
+    var gte = createRelationalOperation(function(value, other) {
+      return value >= other;
+    });
+
+    /**
+     * Checks if `value` is likely an `arguments` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+     *  else `false`.
+     * @example
+     *
+     * _.isArguments(function() { return arguments; }());
+     * // => true
+     *
+     * _.isArguments([1, 2, 3]);
+     * // => false
+     */
+    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
+      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
+        !propertyIsEnumerable.call(value, 'callee');
+    };
+
+    /**
+     * Checks if `value` is classified as an `Array` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is an array, else `false`.
+     * @example
+     *
+     * _.isArray([1, 2, 3]);
+     * // => true
+     *
+     * _.isArray(document.body.children);
+     * // => false
+     *
+     * _.isArray('abc');
+     * // => false
+     *
+     * _.isArray(_.noop);
+     * // => false
+     */
+    var isArray = Array.isArray;
+
+    /**
+     * Checks if `value` is classified as an `ArrayBuffer` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.3.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
+     * @example
+     *
+     * _.isArrayBuffer(new ArrayBuffer(2));
+     * // => true
+     *
+     * _.isArrayBuffer(new Array(2));
+     * // => false
+     */
+    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
+
+    /**
+     * Checks if `value` is array-like. A value is considered array-like if it's
+     * not a function and has a `value.length` that's an integer greater than or
+     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+     * @example
+     *
+     * _.isArrayLike([1, 2, 3]);
+     * // => true
+     *
+     * _.isArrayLike(document.body.children);
+     * // => true
+     *
+     * _.isArrayLike('abc');
+     * // => true
+     *
+     * _.isArrayLike(_.noop);
+     * // => false
+     */
+    function isArrayLike(value) {
+      return value != null && isLength(value.length) && !isFunction(value);
+    }
+
+    /**
+     * This method is like `_.isArrayLike` except that it also checks if `value`
+     * is an object.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is an array-like object,
+     *  else `false`.
+     * @example
+     *
+     * _.isArrayLikeObject([1, 2, 3]);
+     * // => true
+     *
+     * _.isArrayLikeObject(document.body.children);
+     * // => true
+     *
+     * _.isArrayLikeObject('abc');
+     * // => false
+     *
+     * _.isArrayLikeObject(_.noop);
+     * // => false
+     */
+    function isArrayLikeObject(value) {
+      return isObjectLike(value) && isArrayLike(value);
+    }
+
+    /**
+     * Checks if `value` is classified as a boolean primitive or object.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
+     * @example
+     *
+     * _.isBoolean(false);
+     * // => true
+     *
+     * _.isBoolean(null);
+     * // => false
+     */
+    function isBoolean(value) {
+      return value === true || value === false ||
+        (isObjectLike(value) && baseGetTag(value) == boolTag);
+    }
+
+    /**
+     * Checks if `value` is a buffer.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.3.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
+     * @example
+     *
+     * _.isBuffer(new Buffer(2));
+     * // => true
+     *
+     * _.isBuffer(new Uint8Array(2));
+     * // => false
+     */
+    var isBuffer = nativeIsBuffer || stubFalse;
+
+    /**
+     * Checks if `value` is classified as a `Date` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
+     * @example
+     *
+     * _.isDate(new Date);
+     * // => true
+     *
+     * _.isDate('Mon April 23 2012');
+     * // => false
+     */
+    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
+
+    /**
+     * Checks if `value` is likely a DOM element.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
+     * @example
+     *
+     * _.isElement(document.body);
+     * // => true
+     *
+     * _.isElement('<body>');
+     * // => false
+     */
+    function isElement(value) {
+      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
+    }
+
+    /**
+     * Checks if `value` is an empty object, collection, map, or set.
+     *
+     * Objects are considered empty if they have no own enumerable string keyed
+     * properties.
+     *
+     * Array-like values such as `arguments` objects, arrays, buffers, strings, or
+     * jQuery-like collections are considered empty if they have a `length` of `0`.
+     * Similarly, maps and sets are considered empty if they have a `size` of `0`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
+     * @example
+     *
+     * _.isEmpty(null);
+     * // => true
+     *
+     * _.isEmpty(true);
+     * // => true
+     *
+     * _.isEmpty(1);
+     * // => true
+     *
+     * _.isEmpty([1, 2, 3]);
+     * // => false
+     *
+     * _.isEmpty({ 'a': 1 });
+     * // => false
+     */
+    function isEmpty(value) {
+      if (value == null) {
+        return true;
+      }
+      if (isArrayLike(value) &&
+          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
+            isBuffer(value) || isTypedArray(value) || isArguments(value))) {
+        return !value.length;
+      }
+      var tag = getTag(value);
+      if (tag == mapTag || tag == setTag) {
+        return !value.size;
+      }
+      if (isPrototype(value)) {
+        return !baseKeys(value).length;
+      }
+      for (var key in value) {
+        if (hasOwnProperty.call(value, key)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    /**
+     * Performs a deep comparison between two values to determine if they are
+     * equivalent.
+     *
+     * **Note:** This method supports comparing arrays, array buffers, booleans,
+     * date objects, error objects, maps, numbers, `Object` objects, regexes,
+     * sets, strings, symbols, and typed arrays. `Object` objects are compared
+     * by their own, not inherited, enumerable properties. Functions and DOM
+     * nodes are compared by strict equality, i.e. `===`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+     * @example
+     *
+     * var object = { 'a': 1 };
+     * var other = { 'a': 1 };
+     *
+     * _.isEqual(object, other);
+     * // => true
+     *
+     * object === other;
+     * // => false
+     */
+    function isEqual(value, other) {
+      return baseIsEqual(value, other);
+    }
+
+    /**
+     * This method is like `_.isEqual` except that it accepts `customizer` which
+     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
+     * are handled by the method instead. The `customizer` is invoked with up to
+     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @param {Function} [customizer] The function to customize comparisons.
+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+     * @example
+     *
+     * function isGreeting(value) {
+     *   return /^h(?:i|ello)$/.test(value);
+     * }
+     *
+     * function customizer(objValue, othValue) {
+     *   if (isGreeting(objValue) && isGreeting(othValue)) {
+     *     return true;
+     *   }
+     * }
+     *
+     * var array = ['hello', 'goodbye'];
+     * var other = ['hi', 'goodbye'];
+     *
+     * _.isEqualWith(array, other, customizer);
+     * // => true
+     */
+    function isEqualWith(value, other, customizer) {
+      customizer = typeof customizer == 'function' ? customizer : undefined;
+      var result = customizer ? customizer(value, other) : undefined;
+      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
+    }
+
+    /**
+     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
+     * `SyntaxError`, `TypeError`, or `URIError` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
+     * @example
+     *
+     * _.isError(new Error);
+     * // => true
+     *
+     * _.isError(Error);
+     * // => false
+     */
+    function isError(value) {
+      if (!isObjectLike(value)) {
+        return false;
+      }
+      var tag = baseGetTag(value);
+      return tag == errorTag || tag == domExcTag ||
+        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
+    }
+
+    /**
+     * Checks if `value` is a finite primitive number.
+     *
+     * **Note:** This method is based on
+     * [`Number.isFinite`](https://mdn.io/Number/isFinite).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
+     * @example
+     *
+     * _.isFinite(3);
+     * // => true
+     *
+     * _.isFinite(Number.MIN_VALUE);
+     * // => true
+     *
+     * _.isFinite(Infinity);
+     * // => false
+     *
+     * _.isFinite('3');
+     * // => false
+     */
+    function isFinite(value) {
+      return typeof value == 'number' && nativeIsFinite(value);
+    }
+
+    /**
+     * Checks if `value` is classified as a `Function` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a function, else `false`.
+     * @example
+     *
+     * _.isFunction(_);
+     * // => true
+     *
+     * _.isFunction(/abc/);
+     * // => false
+     */
+    function isFunction(value) {
+      if (!isObject(value)) {
+        return false;
+      }
+      // The use of `Object#toString` avoids issues with the `typeof` operator
+      // in Safari 9 which returns 'object' for typed arrays and other constructors.
+      var tag = baseGetTag(value);
+      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
+    }
+
+    /**
+     * Checks if `value` is an integer.
+     *
+     * **Note:** This method is based on
+     * [`Number.isInteger`](https://mdn.io/Number/isInteger).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
+     * @example
+     *
+     * _.isInteger(3);
+     * // => true
+     *
+     * _.isInteger(Number.MIN_VALUE);
+     * // => false
+     *
+     * _.isInteger(Infinity);
+     * // => false
+     *
+     * _.isInteger('3');
+     * // => false
+     */
+    function isInteger(value) {
+      return typeof value == 'number' && value == toInteger(value);
+    }
+
+    /**
+     * Checks if `value` is a valid array-like length.
+     *
+     * **Note:** This method is loosely based on
+     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+     * @example
+     *
+     * _.isLength(3);
+     * // => true
+     *
+     * _.isLength(Number.MIN_VALUE);
+     * // => false
+     *
+     * _.isLength(Infinity);
+     * // => false
+     *
+     * _.isLength('3');
+     * // => false
+     */
+    function isLength(value) {
+      return typeof value == 'number' &&
+        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+    }
+
+    /**
+     * Checks if `value` is the
+     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+     * @example
+     *
+     * _.isObject({});
+     * // => true
+     *
+     * _.isObject([1, 2, 3]);
+     * // => true
+     *
+     * _.isObject(_.noop);
+     * // => true
+     *
+     * _.isObject(null);
+     * // => false
+     */
+    function isObject(value) {
+      var type = typeof value;
+      return value != null && (type == 'object' || type == 'function');
+    }
+
+    /**
+     * Checks if `value` is object-like. A value is object-like if it's not `null`
+     * and has a `typeof` result of "object".
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+     * @example
+     *
+     * _.isObjectLike({});
+     * // => true
+     *
+     * _.isObjectLike([1, 2, 3]);
+     * // => true
+     *
+     * _.isObjectLike(_.noop);
+     * // => false
+     *
+     * _.isObjectLike(null);
+     * // => false
+     */
+    function isObjectLike(value) {
+      return value != null && typeof value == 'object';
+    }
+
+    /**
+     * Checks if `value` is classified as a `Map` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.3.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
+     * @example
+     *
+     * _.isMap(new Map);
+     * // => true
+     *
+     * _.isMap(new WeakMap);
+     * // => false
+     */
+    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
+
+    /**
+     * Performs a partial deep comparison between `object` and `source` to
+     * determine if `object` contains equivalent property values.
+     *
+     * **Note:** This method is equivalent to `_.matches` when `source` is
+     * partially applied.
+     *
+     * Partial comparisons will match empty array and empty object `source`
+     * values against any array or object value, respectively. See `_.isEqual`
+     * for a list of supported value comparisons.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Lang
+     * @param {Object} object The object to inspect.
+     * @param {Object} source The object of property values to match.
+     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+     * @example
+     *
+     * var object = { 'a': 1, 'b': 2 };
+     *
+     * _.isMatch(object, { 'b': 2 });
+     * // => true
+     *
+     * _.isMatch(object, { 'b': 1 });
+     * // => false
+     */
+    function isMatch(object, source) {
+      return object === source || baseIsMatch(object, source, getMatchData(source));
+    }
+
+    /**
+     * This method is like `_.isMatch` except that it accepts `customizer` which
+     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
+     * are handled by the method instead. The `customizer` is invoked with five
+     * arguments: (objValue, srcValue, index|key, object, source).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {Object} object The object to inspect.
+     * @param {Object} source The object of property values to match.
+     * @param {Function} [customizer] The function to customize comparisons.
+     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+     * @example
+     *
+     * function isGreeting(value) {
+     *   return /^h(?:i|ello)$/.test(value);
+     * }
+     *
+     * function customizer(objValue, srcValue) {
+     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
+     *     return true;
+     *   }
+     * }
+     *
+     * var object = { 'greeting': 'hello' };
+     * var source = { 'greeting': 'hi' };
+     *
+     * _.isMatchWith(object, source, customizer);
+     * // => true
+     */
+    function isMatchWith(object, source, customizer) {
+      customizer = typeof customizer == 'function' ? customizer : undefined;
+      return baseIsMatch(object, source, getMatchData(source), customizer);
+    }
+
+    /**
+     * Checks if `value` is `NaN`.
+     *
+     * **Note:** This method is based on
+     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
+     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
+     * `undefined` and other non-number values.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
+     * @example
+     *
+     * _.isNaN(NaN);
+     * // => true
+     *
+     * _.isNaN(new Number(NaN));
+     * // => true
+     *
+     * isNaN(undefined);
+     * // => true
+     *
+     * _.isNaN(undefined);
+     * // => false
+     */
+    function isNaN(value) {
+      // An `NaN` primitive is the only value that is not equal to itself.
+      // Perform the `toStringTag` check first to avoid errors with some
+      // ActiveX objects in IE.
+      return isNumber(value) && value != +value;
+    }
+
+    /**
+     * Checks if `value` is a pristine native function.
+     *
+     * **Note:** This method can't reliably detect native functions in the presence
+     * of the core-js package because core-js circumvents this kind of detection.
+     * Despite multiple requests, the core-js maintainer has made it clear: any
+     * attempt to fix the detection will be obstructed. As a result, we're left
+     * with little choice but to throw an error. Unfortunately, this also affects
+     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
+     * which rely on core-js.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a native function,
+     *  else `false`.
+     * @example
+     *
+     * _.isNative(Array.prototype.push);
+     * // => true
+     *
+     * _.isNative(_);
+     * // => false
+     */
+    function isNative(value) {
+      if (isMaskable(value)) {
+        throw new Error(CORE_ERROR_TEXT);
+      }
+      return baseIsNative(value);
+    }
+
+    /**
+     * Checks if `value` is `null`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
+     * @example
+     *
+     * _.isNull(null);
+     * // => true
+     *
+     * _.isNull(void 0);
+     * // => false
+     */
+    function isNull(value) {
+      return value === null;
+    }
+
+    /**
+     * Checks if `value` is `null` or `undefined`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
+     * @example
+     *
+     * _.isNil(null);
+     * // => true
+     *
+     * _.isNil(void 0);
+     * // => true
+     *
+     * _.isNil(NaN);
+     * // => false
+     */
+    function isNil(value) {
+      return value == null;
+    }
+
+    /**
+     * Checks if `value` is classified as a `Number` primitive or object.
+     *
+     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
+     * classified as numbers, use the `_.isFinite` method.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a number, else `false`.
+     * @example
+     *
+     * _.isNumber(3);
+     * // => true
+     *
+     * _.isNumber(Number.MIN_VALUE);
+     * // => true
+     *
+     * _.isNumber(Infinity);
+     * // => true
+     *
+     * _.isNumber('3');
+     * // => false
+     */
+    function isNumber(value) {
+      return typeof value == 'number' ||
+        (isObjectLike(value) && baseGetTag(value) == numberTag);
+    }
+
+    /**
+     * Checks if `value` is a plain object, that is, an object created by the
+     * `Object` constructor or one with a `[[Prototype]]` of `null`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.8.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     * }
+     *
+     * _.isPlainObject(new Foo);
+     * // => false
+     *
+     * _.isPlainObject([1, 2, 3]);
+     * // => false
+     *
+     * _.isPlainObject({ 'x': 0, 'y': 0 });
+     * // => true
+     *
+     * _.isPlainObject(Object.create(null));
+     * // => true
+     */
+    function isPlainObject(value) {
+      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
+        return false;
+      }
+      var proto = getPrototype(value);
+      if (proto === null) {
+        return true;
+      }
+      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
+      return typeof Ctor == 'function' && Ctor instanceof Ctor &&
+        funcToString.call(Ctor) == objectCtorString;
+    }
+
+    /**
+     * Checks if `value` is classified as a `RegExp` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
+     * @example
+     *
+     * _.isRegExp(/abc/);
+     * // => true
+     *
+     * _.isRegExp('/abc/');
+     * // => false
+     */
+    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
+
+    /**
+     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
+     * double precision number which isn't the result of a rounded unsafe integer.
+     *
+     * **Note:** This method is based on
+     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
+     * @example
+     *
+     * _.isSafeInteger(3);
+     * // => true
+     *
+     * _.isSafeInteger(Number.MIN_VALUE);
+     * // => false
+     *
+     * _.isSafeInteger(Infinity);
+     * // => false
+     *
+     * _.isSafeInteger('3');
+     * // => false
+     */
+    function isSafeInteger(value) {
+      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
+    }
+
+    /**
+     * Checks if `value` is classified as a `Set` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.3.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
+     * @example
+     *
+     * _.isSet(new Set);
+     * // => true
+     *
+     * _.isSet(new WeakSet);
+     * // => false
+     */
+    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
+
+    /**
+     * Checks if `value` is classified as a `String` primitive or object.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a string, else `false`.
+     * @example
+     *
+     * _.isString('abc');
+     * // => true
+     *
+     * _.isString(1);
+     * // => false
+     */
+    function isString(value) {
+      return typeof value == 'string' ||
+        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
+    }
+
+    /**
+     * Checks if `value` is classified as a `Symbol` primitive or object.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
+     * @example
+     *
+     * _.isSymbol(Symbol.iterator);
+     * // => true
+     *
+     * _.isSymbol('abc');
+     * // => false
+     */
+    function isSymbol(value) {
+      return typeof value == 'symbol' ||
+        (isObjectLike(value) && baseGetTag(value) == symbolTag);
+    }
+
+    /**
+     * Checks if `value` is classified as a typed array.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
+     * @example
+     *
+     * _.isTypedArray(new Uint8Array);
+     * // => true
+     *
+     * _.isTypedArray([]);
+     * // => false
+     */
+    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
+
+    /**
+     * Checks if `value` is `undefined`.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
+     * @example
+     *
+     * _.isUndefined(void 0);
+     * // => true
+     *
+     * _.isUndefined(null);
+     * // => false
+     */
+    function isUndefined(value) {
+      return value === undefined;
+    }
+
+    /**
+     * Checks if `value` is classified as a `WeakMap` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.3.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
+     * @example
+     *
+     * _.isWeakMap(new WeakMap);
+     * // => true
+     *
+     * _.isWeakMap(new Map);
+     * // => false
+     */
+    function isWeakMap(value) {
+      return isObjectLike(value) && getTag(value) == weakMapTag;
+    }
+
+    /**
+     * Checks if `value` is classified as a `WeakSet` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.3.0
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
+     * @example
+     *
+     * _.isWeakSet(new WeakSet);
+     * // => true
+     *
+     * _.isWeakSet(new Set);
+     * // => false
+     */
+    function isWeakSet(value) {
+      return isObjectLike(value) && baseGetTag(value) == weakSetTag;
+    }
+
+    /**
+     * Checks if `value` is less than `other`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.9.0
+     * @category Lang
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @returns {boolean} Returns `true` if `value` is less than `other`,
+     *  else `false`.
+     * @see _.gt
+     * @example
+     *
+     * _.lt(1, 3);
+     * // => true
+     *
+     * _.lt(3, 3);
+     * // => false
+     *
+     * _.lt(3, 1);
+     * // => false
+     */
+    var lt = createRelationalOperation(baseLt);
+
+    /**
+     * Checks if `value` is less than or equal to `other`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.9.0
+     * @category Lang
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @returns {boolean} Returns `true` if `value` is less than or equal to
+     *  `other`, else `false`.
+     * @see _.gte
+     * @example
+     *
+     * _.lte(1, 3);
+     * // => true
+     *
+     * _.lte(3, 3);
+     * // => true
+     *
+     * _.lte(3, 1);
+     * // => false
+     */
+    var lte = createRelationalOperation(function(value, other) {
+      return value <= other;
+    });
+
+    /**
+     * Converts `value` to an array.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Lang
+     * @param {*} value The value to convert.
+     * @returns {Array} Returns the converted array.
+     * @example
+     *
+     * _.toArray({ 'a': 1, 'b': 2 });
+     * // => [1, 2]
+     *
+     * _.toArray('abc');
+     * // => ['a', 'b', 'c']
+     *
+     * _.toArray(1);
+     * // => []
+     *
+     * _.toArray(null);
+     * // => []
+     */
+    function toArray(value) {
+      if (!value) {
+        return [];
+      }
+      if (isArrayLike(value)) {
+        return isString(value) ? stringToArray(value) : copyArray(value);
+      }
+      if (symIterator && value[symIterator]) {
+        return iteratorToArray(value[symIterator]());
+      }
+      var tag = getTag(value),
+          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
+
+      return func(value);
+    }
+
+    /**
+     * Converts `value` to a finite number.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.12.0
+     * @category Lang
+     * @param {*} value The value to convert.
+     * @returns {number} Returns the converted number.
+     * @example
+     *
+     * _.toFinite(3.2);
+     * // => 3.2
+     *
+     * _.toFinite(Number.MIN_VALUE);
+     * // => 5e-324
+     *
+     * _.toFinite(Infinity);
+     * // => 1.7976931348623157e+308
+     *
+     * _.toFinite('3.2');
+     * // => 3.2
+     */
+    function toFinite(value) {
+      if (!value) {
+        return value === 0 ? value : 0;
+      }
+      value = toNumber(value);
+      if (value === INFINITY || value === -INFINITY) {
+        var sign = (value < 0 ? -1 : 1);
+        return sign * MAX_INTEGER;
+      }
+      return value === value ? value : 0;
+    }
+
+    /**
+     * Converts `value` to an integer.
+     *
+     * **Note:** This method is loosely based on
+     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to convert.
+     * @returns {number} Returns the converted integer.
+     * @example
+     *
+     * _.toInteger(3.2);
+     * // => 3
+     *
+     * _.toInteger(Number.MIN_VALUE);
+     * // => 0
+     *
+     * _.toInteger(Infinity);
+     * // => 1.7976931348623157e+308
+     *
+     * _.toInteger('3.2');
+     * // => 3
+     */
+    function toInteger(value) {
+      var result = toFinite(value),
+          remainder = result % 1;
+
+      return result === result ? (remainder ? result - remainder : result) : 0;
+    }
+
+    /**
+     * Converts `value` to an integer suitable for use as the length of an
+     * array-like object.
+     *
+     * **Note:** This method is based on
+     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to convert.
+     * @returns {number} Returns the converted integer.
+     * @example
+     *
+     * _.toLength(3.2);
+     * // => 3
+     *
+     * _.toLength(Number.MIN_VALUE);
+     * // => 0
+     *
+     * _.toLength(Infinity);
+     * // => 4294967295
+     *
+     * _.toLength('3.2');
+     * // => 3
+     */
+    function toLength(value) {
+      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
+    }
+
+    /**
+     * Converts `value` to a number.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to process.
+     * @returns {number} Returns the number.
+     * @example
+     *
+     * _.toNumber(3.2);
+     * // => 3.2
+     *
+     * _.toNumber(Number.MIN_VALUE);
+     * // => 5e-324
+     *
+     * _.toNumber(Infinity);
+     * // => Infinity
+     *
+     * _.toNumber('3.2');
+     * // => 3.2
+     */
+    function toNumber(value) {
+      if (typeof value == 'number') {
+        return value;
+      }
+      if (isSymbol(value)) {
+        return NAN;
+      }
+      if (isObject(value)) {
+        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
+        value = isObject(other) ? (other + '') : other;
+      }
+      if (typeof value != 'string') {
+        return value === 0 ? value : +value;
+      }
+      value = value.replace(reTrim, '');
+      var isBinary = reIsBinary.test(value);
+      return (isBinary || reIsOctal.test(value))
+        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
+        : (reIsBadHex.test(value) ? NAN : +value);
+    }
+
+    /**
+     * Converts `value` to a plain object flattening inherited enumerable string
+     * keyed properties of `value` to own properties of the plain object.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Lang
+     * @param {*} value The value to convert.
+     * @returns {Object} Returns the converted plain object.
+     * @example
+     *
+     * function Foo() {
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.assign({ 'a': 1 }, new Foo);
+     * // => { 'a': 1, 'b': 2 }
+     *
+     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
+     * // => { 'a': 1, 'b': 2, 'c': 3 }
+     */
+    function toPlainObject(value) {
+      return copyObject(value, keysIn(value));
+    }
+
+    /**
+     * Converts `value` to a safe integer. A safe integer can be compared and
+     * represented correctly.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to convert.
+     * @returns {number} Returns the converted integer.
+     * @example
+     *
+     * _.toSafeInteger(3.2);
+     * // => 3
+     *
+     * _.toSafeInteger(Number.MIN_VALUE);
+     * // => 0
+     *
+     * _.toSafeInteger(Infinity);
+     * // => 9007199254740991
+     *
+     * _.toSafeInteger('3.2');
+     * // => 3
+     */
+    function toSafeInteger(value) {
+      return value
+        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
+        : (value === 0 ? value : 0);
+    }
+
+    /**
+     * Converts `value` to a string. An empty string is returned for `null`
+     * and `undefined` values. The sign of `-0` is preserved.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Lang
+     * @param {*} value The value to convert.
+     * @returns {string} Returns the converted string.
+     * @example
+     *
+     * _.toString(null);
+     * // => ''
+     *
+     * _.toString(-0);
+     * // => '-0'
+     *
+     * _.toString([1, 2, 3]);
+     * // => '1,2,3'
+     */
+    function toString(value) {
+      return value == null ? '' : baseToString(value);
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Assigns own enumerable string keyed properties of source objects to the
+     * destination object. Source objects are applied from left to right.
+     * Subsequent sources overwrite property assignments of previous sources.
+     *
+     * **Note:** This method mutates `object` and is loosely based on
+     * [`Object.assign`](https://mdn.io/Object/assign).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.10.0
+     * @category Object
+     * @param {Object} object The destination object.
+     * @param {...Object} [sources] The source objects.
+     * @returns {Object} Returns `object`.
+     * @see _.assignIn
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     * }
+     *
+     * function Bar() {
+     *   this.c = 3;
+     * }
+     *
+     * Foo.prototype.b = 2;
+     * Bar.prototype.d = 4;
+     *
+     * _.assign({ 'a': 0 }, new Foo, new Bar);
+     * // => { 'a': 1, 'c': 3 }
+     */
+    var assign = createAssigner(function(object, source) {
+      if (isPrototype(source) || isArrayLike(source)) {
+        copyObject(source, keys(source), object);
+        return;
+      }
+      for (var key in source) {
+        if (hasOwnProperty.call(source, key)) {
+          assignValue(object, key, source[key]);
+        }
+      }
+    });
+
+    /**
+     * This method is like `_.assign` except that it iterates over own and
+     * inherited source properties.
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @alias extend
+     * @category Object
+     * @param {Object} object The destination object.
+     * @param {...Object} [sources] The source objects.
+     * @returns {Object} Returns `object`.
+     * @see _.assign
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     * }
+     *
+     * function Bar() {
+     *   this.c = 3;
+     * }
+     *
+     * Foo.prototype.b = 2;
+     * Bar.prototype.d = 4;
+     *
+     * _.assignIn({ 'a': 0 }, new Foo, new Bar);
+     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
+     */
+    var assignIn = createAssigner(function(object, source) {
+      copyObject(source, keysIn(source), object);
+    });
+
+    /**
+     * This method is like `_.assignIn` except that it accepts `customizer`
+     * which is invoked to produce the assigned values. If `customizer` returns
+     * `undefined`, assignment is handled by the method instead. The `customizer`
+     * is invoked with five arguments: (objValue, srcValue, key, object, source).
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @alias extendWith
+     * @category Object
+     * @param {Object} object The destination object.
+     * @param {...Object} sources The source objects.
+     * @param {Function} [customizer] The function to customize assigned values.
+     * @returns {Object} Returns `object`.
+     * @see _.assignWith
+     * @example
+     *
+     * function customizer(objValue, srcValue) {
+     *   return _.isUndefined(objValue) ? srcValue : objValue;
+     * }
+     *
+     * var defaults = _.partialRight(_.assignInWith, customizer);
+     *
+     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+     * // => { 'a': 1, 'b': 2 }
+     */
+    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
+      copyObject(source, keysIn(source), object, customizer);
+    });
+
+    /**
+     * This method is like `_.assign` except that it accepts `customizer`
+     * which is invoked to produce the assigned values. If `customizer` returns
+     * `undefined`, assignment is handled by the method instead. The `customizer`
+     * is invoked with five arguments: (objValue, srcValue, key, object, source).
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Object
+     * @param {Object} object The destination object.
+     * @param {...Object} sources The source objects.
+     * @param {Function} [customizer] The function to customize assigned values.
+     * @returns {Object} Returns `object`.
+     * @see _.assignInWith
+     * @example
+     *
+     * function customizer(objValue, srcValue) {
+     *   return _.isUndefined(objValue) ? srcValue : objValue;
+     * }
+     *
+     * var defaults = _.partialRight(_.assignWith, customizer);
+     *
+     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+     * // => { 'a': 1, 'b': 2 }
+     */
+    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
+      copyObject(source, keys(source), object, customizer);
+    });
+
+    /**
+     * Creates an array of values corresponding to `paths` of `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 1.0.0
+     * @category Object
+     * @param {Object} object The object to iterate over.
+     * @param {...(string|string[])} [paths] The property paths to pick.
+     * @returns {Array} Returns the picked values.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+     *
+     * _.at(object, ['a[0].b.c', 'a[1]']);
+     * // => [3, 4]
+     */
+    var at = flatRest(baseAt);
+
+    /**
+     * Creates an object that inherits from the `prototype` object. If a
+     * `properties` object is given, its own enumerable string keyed properties
+     * are assigned to the created object.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.3.0
+     * @category Object
+     * @param {Object} prototype The object to inherit from.
+     * @param {Object} [properties] The properties to assign to the object.
+     * @returns {Object} Returns the new object.
+     * @example
+     *
+     * function Shape() {
+     *   this.x = 0;
+     *   this.y = 0;
+     * }
+     *
+     * function Circle() {
+     *   Shape.call(this);
+     * }
+     *
+     * Circle.prototype = _.create(Shape.prototype, {
+     *   'constructor': Circle
+     * });
+     *
+     * var circle = new Circle;
+     * circle instanceof Circle;
+     * // => true
+     *
+     * circle instanceof Shape;
+     * // => true
+     */
+    function create(prototype, properties) {
+      var result = baseCreate(prototype);
+      return properties == null ? result : baseAssign(result, properties);
+    }
+
+    /**
+     * Assigns own and inherited enumerable string keyed properties of source
+     * objects to the destination object for all destination properties that
+     * resolve to `undefined`. Source objects are applied from left to right.
+     * Once a property is set, additional values of the same property are ignored.
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The destination object.
+     * @param {...Object} [sources] The source objects.
+     * @returns {Object} Returns `object`.
+     * @see _.defaultsDeep
+     * @example
+     *
+     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+     * // => { 'a': 1, 'b': 2 }
+     */
+    var defaults = baseRest(function(args) {
+      args.push(undefined, customDefaultsAssignIn);
+      return apply(assignInWith, undefined, args);
+    });
+
+    /**
+     * This method is like `_.defaults` except that it recursively assigns
+     * default properties.
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.10.0
+     * @category Object
+     * @param {Object} object The destination object.
+     * @param {...Object} [sources] The source objects.
+     * @returns {Object} Returns `object`.
+     * @see _.defaults
+     * @example
+     *
+     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
+     * // => { 'a': { 'b': 2, 'c': 3 } }
+     */
+    var defaultsDeep = baseRest(function(args) {
+      args.push(undefined, customDefaultsMerge);
+      return apply(mergeWith, undefined, args);
+    });
+
+    /**
+     * This method is like `_.find` except that it returns the key of the first
+     * element `predicate` returns truthy for instead of the element itself.
+     *
+     * @static
+     * @memberOf _
+     * @since 1.1.0
+     * @category Object
+     * @param {Object} object The object to inspect.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {string|undefined} Returns the key of the matched element,
+     *  else `undefined`.
+     * @example
+     *
+     * var users = {
+     *   'barney':  { 'age': 36, 'active': true },
+     *   'fred':    { 'age': 40, 'active': false },
+     *   'pebbles': { 'age': 1,  'active': true }
+     * };
+     *
+     * _.findKey(users, function(o) { return o.age < 40; });
+     * // => 'barney' (iteration order is not guaranteed)
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.findKey(users, { 'age': 1, 'active': true });
+     * // => 'pebbles'
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.findKey(users, ['active', false]);
+     * // => 'fred'
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.findKey(users, 'active');
+     * // => 'barney'
+     */
+    function findKey(object, predicate) {
+      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
+    }
+
+    /**
+     * This method is like `_.findKey` except that it iterates over elements of
+     * a collection in the opposite order.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @category Object
+     * @param {Object} object The object to inspect.
+     * @param {Function} [predicate=_.identity] The function invoked per iteration.
+     * @returns {string|undefined} Returns the key of the matched element,
+     *  else `undefined`.
+     * @example
+     *
+     * var users = {
+     *   'barney':  { 'age': 36, 'active': true },
+     *   'fred':    { 'age': 40, 'active': false },
+     *   'pebbles': { 'age': 1,  'active': true }
+     * };
+     *
+     * _.findLastKey(users, function(o) { return o.age < 40; });
+     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.findLastKey(users, { 'age': 36, 'active': true });
+     * // => 'barney'
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.findLastKey(users, ['active', false]);
+     * // => 'fred'
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.findLastKey(users, 'active');
+     * // => 'pebbles'
+     */
+    function findLastKey(object, predicate) {
+      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
+    }
+
+    /**
+     * Iterates over own and inherited enumerable string keyed properties of an
+     * object and invokes `iteratee` for each property. The iteratee is invoked
+     * with three arguments: (value, key, object). Iteratee functions may exit
+     * iteration early by explicitly returning `false`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.3.0
+     * @category Object
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Object} Returns `object`.
+     * @see _.forInRight
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.forIn(new Foo, function(value, key) {
+     *   console.log(key);
+     * });
+     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
+     */
+    function forIn(object, iteratee) {
+      return object == null
+        ? object
+        : baseFor(object, getIteratee(iteratee, 3), keysIn);
+    }
+
+    /**
+     * This method is like `_.forIn` except that it iterates over properties of
+     * `object` in the opposite order.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @category Object
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Object} Returns `object`.
+     * @see _.forIn
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.forInRight(new Foo, function(value, key) {
+     *   console.log(key);
+     * });
+     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
+     */
+    function forInRight(object, iteratee) {
+      return object == null
+        ? object
+        : baseForRight(object, getIteratee(iteratee, 3), keysIn);
+    }
+
+    /**
+     * Iterates over own enumerable string keyed properties of an object and
+     * invokes `iteratee` for each property. The iteratee is invoked with three
+     * arguments: (value, key, object). Iteratee functions may exit iteration
+     * early by explicitly returning `false`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.3.0
+     * @category Object
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Object} Returns `object`.
+     * @see _.forOwnRight
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.forOwn(new Foo, function(value, key) {
+     *   console.log(key);
+     * });
+     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
+     */
+    function forOwn(object, iteratee) {
+      return object && baseForOwn(object, getIteratee(iteratee, 3));
+    }
+
+    /**
+     * This method is like `_.forOwn` except that it iterates over properties of
+     * `object` in the opposite order.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.0.0
+     * @category Object
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Object} Returns `object`.
+     * @see _.forOwn
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.forOwnRight(new Foo, function(value, key) {
+     *   console.log(key);
+     * });
+     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
+     */
+    function forOwnRight(object, iteratee) {
+      return object && baseForOwnRight(object, getIteratee(iteratee, 3));
+    }
+
+    /**
+     * Creates an array of function property names from own enumerable properties
+     * of `object`.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The object to inspect.
+     * @returns {Array} Returns the function names.
+     * @see _.functionsIn
+     * @example
+     *
+     * function Foo() {
+     *   this.a = _.constant('a');
+     *   this.b = _.constant('b');
+     * }
+     *
+     * Foo.prototype.c = _.constant('c');
+     *
+     * _.functions(new Foo);
+     * // => ['a', 'b']
+     */
+    function functions(object) {
+      return object == null ? [] : baseFunctions(object, keys(object));
+    }
+
+    /**
+     * Creates an array of function property names from own and inherited
+     * enumerable properties of `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Object
+     * @param {Object} object The object to inspect.
+     * @returns {Array} Returns the function names.
+     * @see _.functions
+     * @example
+     *
+     * function Foo() {
+     *   this.a = _.constant('a');
+     *   this.b = _.constant('b');
+     * }
+     *
+     * Foo.prototype.c = _.constant('c');
+     *
+     * _.functionsIn(new Foo);
+     * // => ['a', 'b', 'c']
+     */
+    function functionsIn(object) {
+      return object == null ? [] : baseFunctions(object, keysIn(object));
+    }
+
+    /**
+     * Gets the value at `path` of `object`. If the resolved value is
+     * `undefined`, the `defaultValue` is returned in its place.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.7.0
+     * @category Object
+     * @param {Object} object The object to query.
+     * @param {Array|string} path The path of the property to get.
+     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+     * @returns {*} Returns the resolved value.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+     *
+     * _.get(object, 'a[0].b.c');
+     * // => 3
+     *
+     * _.get(object, ['a', '0', 'b', 'c']);
+     * // => 3
+     *
+     * _.get(object, 'a.b.c', 'default');
+     * // => 'default'
+     */
+    function get(object, path, defaultValue) {
+      var result = object == null ? undefined : baseGet(object, path);
+      return result === undefined ? defaultValue : result;
+    }
+
+    /**
+     * Checks if `path` is a direct property of `object`.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The object to query.
+     * @param {Array|string} path The path to check.
+     * @returns {boolean} Returns `true` if `path` exists, else `false`.
+     * @example
+     *
+     * var object = { 'a': { 'b': 2 } };
+     * var other = _.create({ 'a': _.create({ 'b': 2 }) });
+     *
+     * _.has(object, 'a');
+     * // => true
+     *
+     * _.has(object, 'a.b');
+     * // => true
+     *
+     * _.has(object, ['a', 'b']);
+     * // => true
+     *
+     * _.has(other, 'a');
+     * // => false
+     */
+    function has(object, path) {
+      return object != null && hasPath(object, path, baseHas);
+    }
+
+    /**
+     * Checks if `path` is a direct or inherited property of `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Object
+     * @param {Object} object The object to query.
+     * @param {Array|string} path The path to check.
+     * @returns {boolean} Returns `true` if `path` exists, else `false`.
+     * @example
+     *
+     * var object = _.create({ 'a': _.create({ 'b': 2 }) });
+     *
+     * _.hasIn(object, 'a');
+     * // => true
+     *
+     * _.hasIn(object, 'a.b');
+     * // => true
+     *
+     * _.hasIn(object, ['a', 'b']);
+     * // => true
+     *
+     * _.hasIn(object, 'b');
+     * // => false
+     */
+    function hasIn(object, path) {
+      return object != null && hasPath(object, path, baseHasIn);
+    }
+
+    /**
+     * Creates an object composed of the inverted keys and values of `object`.
+     * If `object` contains duplicate values, subsequent values overwrite
+     * property assignments of previous values.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.7.0
+     * @category Object
+     * @param {Object} object The object to invert.
+     * @returns {Object} Returns the new inverted object.
+     * @example
+     *
+     * var object = { 'a': 1, 'b': 2, 'c': 1 };
+     *
+     * _.invert(object);
+     * // => { '1': 'c', '2': 'b' }
+     */
+    var invert = createInverter(function(result, value, key) {
+      result[value] = key;
+    }, constant(identity));
+
+    /**
+     * This method is like `_.invert` except that the inverted object is generated
+     * from the results of running each element of `object` thru `iteratee`. The
+     * corresponding inverted value of each inverted key is an array of keys
+     * responsible for generating the inverted value. The iteratee is invoked
+     * with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.1.0
+     * @category Object
+     * @param {Object} object The object to invert.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {Object} Returns the new inverted object.
+     * @example
+     *
+     * var object = { 'a': 1, 'b': 2, 'c': 1 };
+     *
+     * _.invertBy(object);
+     * // => { '1': ['a', 'c'], '2': ['b'] }
+     *
+     * _.invertBy(object, function(value) {
+     *   return 'group' + value;
+     * });
+     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
+     */
+    var invertBy = createInverter(function(result, value, key) {
+      if (hasOwnProperty.call(result, value)) {
+        result[value].push(key);
+      } else {
+        result[value] = [key];
+      }
+    }, getIteratee);
+
+    /**
+     * Invokes the method at `path` of `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Object
+     * @param {Object} object The object to query.
+     * @param {Array|string} path The path of the method to invoke.
+     * @param {...*} [args] The arguments to invoke the method with.
+     * @returns {*} Returns the result of the invoked method.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
+     *
+     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
+     * // => [2, 3]
+     */
+    var invoke = baseRest(baseInvoke);
+
+    /**
+     * Creates an array of the own enumerable property names of `object`.
+     *
+     * **Note:** Non-object values are coerced to objects. See the
+     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
+     * for more details.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names.
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.keys(new Foo);
+     * // => ['a', 'b'] (iteration order is not guaranteed)
+     *
+     * _.keys('hi');
+     * // => ['0', '1']
+     */
+    function keys(object) {
+      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
+    }
+
+    /**
+     * Creates an array of the own and inherited enumerable property names of `object`.
+     *
+     * **Note:** Non-object values are coerced to objects.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names.
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.keysIn(new Foo);
+     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+     */
+    function keysIn(object) {
+      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
+    }
+
+    /**
+     * The opposite of `_.mapValues`; this method creates an object with the
+     * same values as `object` and keys generated by running each own enumerable
+     * string keyed property of `object` thru `iteratee`. The iteratee is invoked
+     * with three arguments: (value, key, object).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.8.0
+     * @category Object
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Object} Returns the new mapped object.
+     * @see _.mapValues
+     * @example
+     *
+     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
+     *   return key + value;
+     * });
+     * // => { 'a1': 1, 'b2': 2 }
+     */
+    function mapKeys(object, iteratee) {
+      var result = {};
+      iteratee = getIteratee(iteratee, 3);
+
+      baseForOwn(object, function(value, key, object) {
+        baseAssignValue(result, iteratee(value, key, object), value);
+      });
+      return result;
+    }
+
+    /**
+     * Creates an object with the same keys as `object` and values generated
+     * by running each own enumerable string keyed property of `object` thru
+     * `iteratee`. The iteratee is invoked with three arguments:
+     * (value, key, object).
+     *
+     * @static
+     * @memberOf _
+     * @since 2.4.0
+     * @category Object
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Object} Returns the new mapped object.
+     * @see _.mapKeys
+     * @example
+     *
+     * var users = {
+     *   'fred':    { 'user': 'fred',    'age': 40 },
+     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
+     * };
+     *
+     * _.mapValues(users, function(o) { return o.age; });
+     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.mapValues(users, 'age');
+     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+     */
+    function mapValues(object, iteratee) {
+      var result = {};
+      iteratee = getIteratee(iteratee, 3);
+
+      baseForOwn(object, function(value, key, object) {
+        baseAssignValue(result, key, iteratee(value, key, object));
+      });
+      return result;
+    }
+
+    /**
+     * This method is like `_.assign` except that it recursively merges own and
+     * inherited enumerable string keyed properties of source objects into the
+     * destination object. Source properties that resolve to `undefined` are
+     * skipped if a destination value exists. Array and plain object properties
+     * are merged recursively. Other objects and value types are overridden by
+     * assignment. Source objects are applied from left to right. Subsequent
+     * sources overwrite property assignments of previous sources.
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.5.0
+     * @category Object
+     * @param {Object} object The destination object.
+     * @param {...Object} [sources] The source objects.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * var object = {
+     *   'a': [{ 'b': 2 }, { 'd': 4 }]
+     * };
+     *
+     * var other = {
+     *   'a': [{ 'c': 3 }, { 'e': 5 }]
+     * };
+     *
+     * _.merge(object, other);
+     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
+     */
+    var merge = createAssigner(function(object, source, srcIndex) {
+      baseMerge(object, source, srcIndex);
+    });
+
+    /**
+     * This method is like `_.merge` except that it accepts `customizer` which
+     * is invoked to produce the merged values of the destination and source
+     * properties. If `customizer` returns `undefined`, merging is handled by the
+     * method instead. The `customizer` is invoked with six arguments:
+     * (objValue, srcValue, key, object, source, stack).
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Object
+     * @param {Object} object The destination object.
+     * @param {...Object} sources The source objects.
+     * @param {Function} customizer The function to customize assigned values.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * function customizer(objValue, srcValue) {
+     *   if (_.isArray(objValue)) {
+     *     return objValue.concat(srcValue);
+     *   }
+     * }
+     *
+     * var object = { 'a': [1], 'b': [2] };
+     * var other = { 'a': [3], 'b': [4] };
+     *
+     * _.mergeWith(object, other, customizer);
+     * // => { 'a': [1, 3], 'b': [2, 4] }
+     */
+    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
+      baseMerge(object, source, srcIndex, customizer);
+    });
+
+    /**
+     * The opposite of `_.pick`; this method creates an object composed of the
+     * own and inherited enumerable property paths of `object` that are not omitted.
+     *
+     * **Note:** This method is considerably slower than `_.pick`.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The source object.
+     * @param {...(string|string[])} [paths] The property paths to omit.
+     * @returns {Object} Returns the new object.
+     * @example
+     *
+     * var object = { 'a': 1, 'b': '2', 'c': 3 };
+     *
+     * _.omit(object, ['a', 'c']);
+     * // => { 'b': '2' }
+     */
+    var omit = flatRest(function(object, paths) {
+      var result = {};
+      if (object == null) {
+        return result;
+      }
+      var isDeep = false;
+      paths = arrayMap(paths, function(path) {
+        path = castPath(path, object);
+        isDeep || (isDeep = path.length > 1);
+        return path;
+      });
+      copyObject(object, getAllKeysIn(object), result);
+      if (isDeep) {
+        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
+      }
+      var length = paths.length;
+      while (length--) {
+        baseUnset(result, paths[length]);
+      }
+      return result;
+    });
+
+    /**
+     * The opposite of `_.pickBy`; this method creates an object composed of
+     * the own and inherited enumerable string keyed properties of `object` that
+     * `predicate` doesn't return truthy for. The predicate is invoked with two
+     * arguments: (value, key).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Object
+     * @param {Object} object The source object.
+     * @param {Function} [predicate=_.identity] The function invoked per property.
+     * @returns {Object} Returns the new object.
+     * @example
+     *
+     * var object = { 'a': 1, 'b': '2', 'c': 3 };
+     *
+     * _.omitBy(object, _.isNumber);
+     * // => { 'b': '2' }
+     */
+    function omitBy(object, predicate) {
+      return pickBy(object, negate(getIteratee(predicate)));
+    }
+
+    /**
+     * Creates an object composed of the picked `object` properties.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The source object.
+     * @param {...(string|string[])} [paths] The property paths to pick.
+     * @returns {Object} Returns the new object.
+     * @example
+     *
+     * var object = { 'a': 1, 'b': '2', 'c': 3 };
+     *
+     * _.pick(object, ['a', 'c']);
+     * // => { 'a': 1, 'c': 3 }
+     */
+    var pick = flatRest(function(object, paths) {
+      return object == null ? {} : basePick(object, paths);
+    });
+
+    /**
+     * Creates an object composed of the `object` properties `predicate` returns
+     * truthy for. The predicate is invoked with two arguments: (value, key).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Object
+     * @param {Object} object The source object.
+     * @param {Function} [predicate=_.identity] The function invoked per property.
+     * @returns {Object} Returns the new object.
+     * @example
+     *
+     * var object = { 'a': 1, 'b': '2', 'c': 3 };
+     *
+     * _.pickBy(object, _.isNumber);
+     * // => { 'a': 1, 'c': 3 }
+     */
+    function pickBy(object, predicate) {
+      if (object == null) {
+        return {};
+      }
+      var props = arrayMap(getAllKeysIn(object), function(prop) {
+        return [prop];
+      });
+      predicate = getIteratee(predicate);
+      return basePickBy(object, props, function(value, path) {
+        return predicate(value, path[0]);
+      });
+    }
+
+    /**
+     * This method is like `_.get` except that if the resolved value is a
+     * function it's invoked with the `this` binding of its parent object and
+     * its result is returned.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The object to query.
+     * @param {Array|string} path The path of the property to resolve.
+     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
+     * @returns {*} Returns the resolved value.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
+     *
+     * _.result(object, 'a[0].b.c1');
+     * // => 3
+     *
+     * _.result(object, 'a[0].b.c2');
+     * // => 4
+     *
+     * _.result(object, 'a[0].b.c3', 'default');
+     * // => 'default'
+     *
+     * _.result(object, 'a[0].b.c3', _.constant('default'));
+     * // => 'default'
+     */
+    function result(object, path, defaultValue) {
+      path = castPath(path, object);
+
+      var index = -1,
+          length = path.length;
+
+      // Ensure the loop is entered when path is empty.
+      if (!length) {
+        length = 1;
+        object = undefined;
+      }
+      while (++index < length) {
+        var value = object == null ? undefined : object[toKey(path[index])];
+        if (value === undefined) {
+          index = length;
+          value = defaultValue;
+        }
+        object = isFunction(value) ? value.call(object) : value;
+      }
+      return object;
+    }
+
+    /**
+     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
+     * it's created. Arrays are created for missing index properties while objects
+     * are created for all other missing properties. Use `_.setWith` to customize
+     * `path` creation.
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.7.0
+     * @category Object
+     * @param {Object} object The object to modify.
+     * @param {Array|string} path The path of the property to set.
+     * @param {*} value The value to set.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+     *
+     * _.set(object, 'a[0].b.c', 4);
+     * console.log(object.a[0].b.c);
+     * // => 4
+     *
+     * _.set(object, ['x', '0', 'y', 'z'], 5);
+     * console.log(object.x[0].y.z);
+     * // => 5
+     */
+    function set(object, path, value) {
+      return object == null ? object : baseSet(object, path, value);
+    }
+
+    /**
+     * This method is like `_.set` except that it accepts `customizer` which is
+     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
+     * path creation is handled by the method instead. The `customizer` is invoked
+     * with three arguments: (nsValue, key, nsObject).
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Object
+     * @param {Object} object The object to modify.
+     * @param {Array|string} path The path of the property to set.
+     * @param {*} value The value to set.
+     * @param {Function} [customizer] The function to customize assigned values.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * var object = {};
+     *
+     * _.setWith(object, '[0][1]', 'a', Object);
+     * // => { '0': { '1': 'a' } }
+     */
+    function setWith(object, path, value, customizer) {
+      customizer = typeof customizer == 'function' ? customizer : undefined;
+      return object == null ? object : baseSet(object, path, value, customizer);
+    }
+
+    /**
+     * Creates an array of own enumerable string keyed-value pairs for `object`
+     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
+     * entries are returned.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @alias entries
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the key-value pairs.
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.toPairs(new Foo);
+     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
+     */
+    var toPairs = createToPairs(keys);
+
+    /**
+     * Creates an array of own and inherited enumerable string keyed-value pairs
+     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
+     * or set, its entries are returned.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @alias entriesIn
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the key-value pairs.
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.toPairsIn(new Foo);
+     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
+     */
+    var toPairsIn = createToPairs(keysIn);
+
+    /**
+     * An alternative to `_.reduce`; this method transforms `object` to a new
+     * `accumulator` object which is the result of running each of its own
+     * enumerable string keyed properties thru `iteratee`, with each invocation
+     * potentially mutating the `accumulator` object. If `accumulator` is not
+     * provided, a new object with the same `[[Prototype]]` will be used. The
+     * iteratee is invoked with four arguments: (accumulator, value, key, object).
+     * Iteratee functions may exit iteration early by explicitly returning `false`.
+     *
+     * @static
+     * @memberOf _
+     * @since 1.3.0
+     * @category Object
+     * @param {Object} object The object to iterate over.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @param {*} [accumulator] The custom accumulator value.
+     * @returns {*} Returns the accumulated value.
+     * @example
+     *
+     * _.transform([2, 3, 4], function(result, n) {
+     *   result.push(n *= n);
+     *   return n % 2 == 0;
+     * }, []);
+     * // => [4, 9]
+     *
+     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+     *   (result[value] || (result[value] = [])).push(key);
+     * }, {});
+     * // => { '1': ['a', 'c'], '2': ['b'] }
+     */
+    function transform(object, iteratee, accumulator) {
+      var isArr = isArray(object),
+          isArrLike = isArr || isBuffer(object) || isTypedArray(object);
+
+      iteratee = getIteratee(iteratee, 4);
+      if (accumulator == null) {
+        var Ctor = object && object.constructor;
+        if (isArrLike) {
+          accumulator = isArr ? new Ctor : [];
+        }
+        else if (isObject(object)) {
+          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
+        }
+        else {
+          accumulator = {};
+        }
+      }
+      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
+        return iteratee(accumulator, value, index, object);
+      });
+      return accumulator;
+    }
+
+    /**
+     * Removes the property at `path` of `object`.
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Object
+     * @param {Object} object The object to modify.
+     * @param {Array|string} path The path of the property to unset.
+     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
+     * _.unset(object, 'a[0].b.c');
+     * // => true
+     *
+     * console.log(object);
+     * // => { 'a': [{ 'b': {} }] };
+     *
+     * _.unset(object, ['a', '0', 'b', 'c']);
+     * // => true
+     *
+     * console.log(object);
+     * // => { 'a': [{ 'b': {} }] };
+     */
+    function unset(object, path) {
+      return object == null ? true : baseUnset(object, path);
+    }
+
+    /**
+     * This method is like `_.set` except that accepts `updater` to produce the
+     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
+     * is invoked with one argument: (value).
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.6.0
+     * @category Object
+     * @param {Object} object The object to modify.
+     * @param {Array|string} path The path of the property to set.
+     * @param {Function} updater The function to produce the updated value.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+     *
+     * _.update(object, 'a[0].b.c', function(n) { return n * n; });
+     * console.log(object.a[0].b.c);
+     * // => 9
+     *
+     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
+     * console.log(object.x[0].y.z);
+     * // => 0
+     */
+    function update(object, path, updater) {
+      return object == null ? object : baseUpdate(object, path, castFunction(updater));
+    }
+
+    /**
+     * This method is like `_.update` except that it accepts `customizer` which is
+     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
+     * path creation is handled by the method instead. The `customizer` is invoked
+     * with three arguments: (nsValue, key, nsObject).
+     *
+     * **Note:** This method mutates `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.6.0
+     * @category Object
+     * @param {Object} object The object to modify.
+     * @param {Array|string} path The path of the property to set.
+     * @param {Function} updater The function to produce the updated value.
+     * @param {Function} [customizer] The function to customize assigned values.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * var object = {};
+     *
+     * _.updateWith(object, '[0][1]', _.constant('a'), Object);
+     * // => { '0': { '1': 'a' } }
+     */
+    function updateWith(object, path, updater, customizer) {
+      customizer = typeof customizer == 'function' ? customizer : undefined;
+      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
+    }
+
+    /**
+     * Creates an array of the own enumerable string keyed property values of `object`.
+     *
+     * **Note:** Non-object values are coerced to objects.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property values.
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.values(new Foo);
+     * // => [1, 2] (iteration order is not guaranteed)
+     *
+     * _.values('hi');
+     * // => ['h', 'i']
+     */
+    function values(object) {
+      return object == null ? [] : baseValues(object, keys(object));
+    }
+
+    /**
+     * Creates an array of the own and inherited enumerable string keyed property
+     * values of `object`.
+     *
+     * **Note:** Non-object values are coerced to objects.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property values.
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.valuesIn(new Foo);
+     * // => [1, 2, 3] (iteration order is not guaranteed)
+     */
+    function valuesIn(object) {
+      return object == null ? [] : baseValues(object, keysIn(object));
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Clamps `number` within the inclusive `lower` and `upper` bounds.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Number
+     * @param {number} number The number to clamp.
+     * @param {number} [lower] The lower bound.
+     * @param {number} upper The upper bound.
+     * @returns {number} Returns the clamped number.
+     * @example
+     *
+     * _.clamp(-10, -5, 5);
+     * // => -5
+     *
+     * _.clamp(10, -5, 5);
+     * // => 5
+     */
+    function clamp(number, lower, upper) {
+      if (upper === undefined) {
+        upper = lower;
+        lower = undefined;
+      }
+      if (upper !== undefined) {
+        upper = toNumber(upper);
+        upper = upper === upper ? upper : 0;
+      }
+      if (lower !== undefined) {
+        lower = toNumber(lower);
+        lower = lower === lower ? lower : 0;
+      }
+      return baseClamp(toNumber(number), lower, upper);
+    }
+
+    /**
+     * Checks if `n` is between `start` and up to, but not including, `end`. If
+     * `end` is not specified, it's set to `start` with `start` then set to `0`.
+     * If `start` is greater than `end` the params are swapped to support
+     * negative ranges.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.3.0
+     * @category Number
+     * @param {number} number The number to check.
+     * @param {number} [start=0] The start of the range.
+     * @param {number} end The end of the range.
+     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
+     * @see _.range, _.rangeRight
+     * @example
+     *
+     * _.inRange(3, 2, 4);
+     * // => true
+     *
+     * _.inRange(4, 8);
+     * // => true
+     *
+     * _.inRange(4, 2);
+     * // => false
+     *
+     * _.inRange(2, 2);
+     * // => false
+     *
+     * _.inRange(1.2, 2);
+     * // => true
+     *
+     * _.inRange(5.2, 4);
+     * // => false
+     *
+     * _.inRange(-3, -2, -6);
+     * // => true
+     */
+    function inRange(number, start, end) {
+      start = toFinite(start);
+      if (end === undefined) {
+        end = start;
+        start = 0;
+      } else {
+        end = toFinite(end);
+      }
+      number = toNumber(number);
+      return baseInRange(number, start, end);
+    }
+
+    /**
+     * Produces a random number between the inclusive `lower` and `upper` bounds.
+     * If only one argument is provided a number between `0` and the given number
+     * is returned. If `floating` is `true`, or either `lower` or `upper` are
+     * floats, a floating-point number is returned instead of an integer.
+     *
+     * **Note:** JavaScript follows the IEEE-754 standard for resolving
+     * floating-point values which can produce unexpected results.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.7.0
+     * @category Number
+     * @param {number} [lower=0] The lower bound.
+     * @param {number} [upper=1] The upper bound.
+     * @param {boolean} [floating] Specify returning a floating-point number.
+     * @returns {number} Returns the random number.
+     * @example
+     *
+     * _.random(0, 5);
+     * // => an integer between 0 and 5
+     *
+     * _.random(5);
+     * // => also an integer between 0 and 5
+     *
+     * _.random(5, true);
+     * // => a floating-point number between 0 and 5
+     *
+     * _.random(1.2, 5.2);
+     * // => a floating-point number between 1.2 and 5.2
+     */
+    function random(lower, upper, floating) {
+      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
+        upper = floating = undefined;
+      }
+      if (floating === undefined) {
+        if (typeof upper == 'boolean') {
+          floating = upper;
+          upper = undefined;
+        }
+        else if (typeof lower == 'boolean') {
+          floating = lower;
+          lower = undefined;
+        }
+      }
+      if (lower === undefined && upper === undefined) {
+        lower = 0;
+        upper = 1;
+      }
+      else {
+        lower = toFinite(lower);
+        if (upper === undefined) {
+          upper = lower;
+          lower = 0;
+        } else {
+          upper = toFinite(upper);
+        }
+      }
+      if (lower > upper) {
+        var temp = lower;
+        lower = upper;
+        upper = temp;
+      }
+      if (floating || lower % 1 || upper % 1) {
+        var rand = nativeRandom();
+        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
+      }
+      return baseRandom(lower, upper);
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the camel cased string.
+     * @example
+     *
+     * _.camelCase('Foo Bar');
+     * // => 'fooBar'
+     *
+     * _.camelCase('--foo-bar--');
+     * // => 'fooBar'
+     *
+     * _.camelCase('__FOO_BAR__');
+     * // => 'fooBar'
+     */
+    var camelCase = createCompounder(function(result, word, index) {
+      word = word.toLowerCase();
+      return result + (index ? capitalize(word) : word);
+    });
+
+    /**
+     * Converts the first character of `string` to upper case and the remaining
+     * to lower case.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to capitalize.
+     * @returns {string} Returns the capitalized string.
+     * @example
+     *
+     * _.capitalize('FRED');
+     * // => 'Fred'
+     */
+    function capitalize(string) {
+      return upperFirst(toString(string).toLowerCase());
+    }
+
+    /**
+     * Deburrs `string` by converting
+     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
+     * letters to basic Latin letters and removing
+     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to deburr.
+     * @returns {string} Returns the deburred string.
+     * @example
+     *
+     * _.deburr('déjà vu');
+     * // => 'deja vu'
+     */
+    function deburr(string) {
+      string = toString(string);
+      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
+    }
+
+    /**
+     * Checks if `string` ends with the given target string.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to inspect.
+     * @param {string} [target] The string to search for.
+     * @param {number} [position=string.length] The position to search up to.
+     * @returns {boolean} Returns `true` if `string` ends with `target`,
+     *  else `false`.
+     * @example
+     *
+     * _.endsWith('abc', 'c');
+     * // => true
+     *
+     * _.endsWith('abc', 'b');
+     * // => false
+     *
+     * _.endsWith('abc', 'b', 2);
+     * // => true
+     */
+    function endsWith(string, target, position) {
+      string = toString(string);
+      target = baseToString(target);
+
+      var length = string.length;
+      position = position === undefined
+        ? length
+        : baseClamp(toInteger(position), 0, length);
+
+      var end = position;
+      position -= target.length;
+      return position >= 0 && string.slice(position, end) == target;
+    }
+
+    /**
+     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
+     * corresponding HTML entities.
+     *
+     * **Note:** No other characters are escaped. To escape additional
+     * characters use a third-party library like [_he_](https://mths.be/he).
+     *
+     * Though the ">" character is escaped for symmetry, characters like
+     * ">" and "/" don't need escaping in HTML and have no special meaning
+     * unless they're part of a tag or unquoted attribute value. See
+     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
+     * (under "semi-related fun fact") for more details.
+     *
+     * When working with HTML you should always
+     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
+     * XSS vectors.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category String
+     * @param {string} [string=''] The string to escape.
+     * @returns {string} Returns the escaped string.
+     * @example
+     *
+     * _.escape('fred, barney, & pebbles');
+     * // => 'fred, barney, &amp; pebbles'
+     */
+    function escape(string) {
+      string = toString(string);
+      return (string && reHasUnescapedHtml.test(string))
+        ? string.replace(reUnescapedHtml, escapeHtmlChar)
+        : string;
+    }
+
+    /**
+     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
+     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to escape.
+     * @returns {string} Returns the escaped string.
+     * @example
+     *
+     * _.escapeRegExp('[lodash](https://lodash.com/)');
+     * // => '\[lodash\]\(https://lodash\.com/\)'
+     */
+    function escapeRegExp(string) {
+      string = toString(string);
+      return (string && reHasRegExpChar.test(string))
+        ? string.replace(reRegExpChar, '\\$&')
+        : string;
+    }
+
+    /**
+     * Converts `string` to
+     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the kebab cased string.
+     * @example
+     *
+     * _.kebabCase('Foo Bar');
+     * // => 'foo-bar'
+     *
+     * _.kebabCase('fooBar');
+     * // => 'foo-bar'
+     *
+     * _.kebabCase('__FOO_BAR__');
+     * // => 'foo-bar'
+     */
+    var kebabCase = createCompounder(function(result, word, index) {
+      return result + (index ? '-' : '') + word.toLowerCase();
+    });
+
+    /**
+     * Converts `string`, as space separated words, to lower case.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the lower cased string.
+     * @example
+     *
+     * _.lowerCase('--Foo-Bar--');
+     * // => 'foo bar'
+     *
+     * _.lowerCase('fooBar');
+     * // => 'foo bar'
+     *
+     * _.lowerCase('__FOO_BAR__');
+     * // => 'foo bar'
+     */
+    var lowerCase = createCompounder(function(result, word, index) {
+      return result + (index ? ' ' : '') + word.toLowerCase();
+    });
+
+    /**
+     * Converts the first character of `string` to lower case.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the converted string.
+     * @example
+     *
+     * _.lowerFirst('Fred');
+     * // => 'fred'
+     *
+     * _.lowerFirst('FRED');
+     * // => 'fRED'
+     */
+    var lowerFirst = createCaseFirst('toLowerCase');
+
+    /**
+     * Pads `string` on the left and right sides if it's shorter than `length`.
+     * Padding characters are truncated if they can't be evenly divided by `length`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to pad.
+     * @param {number} [length=0] The padding length.
+     * @param {string} [chars=' '] The string used as padding.
+     * @returns {string} Returns the padded string.
+     * @example
+     *
+     * _.pad('abc', 8);
+     * // => '  abc   '
+     *
+     * _.pad('abc', 8, '_-');
+     * // => '_-abc_-_'
+     *
+     * _.pad('abc', 3);
+     * // => 'abc'
+     */
+    function pad(string, length, chars) {
+      string = toString(string);
+      length = toInteger(length);
+
+      var strLength = length ? stringSize(string) : 0;
+      if (!length || strLength >= length) {
+        return string;
+      }
+      var mid = (length - strLength) / 2;
+      return (
+        createPadding(nativeFloor(mid), chars) +
+        string +
+        createPadding(nativeCeil(mid), chars)
+      );
+    }
+
+    /**
+     * Pads `string` on the right side if it's shorter than `length`. Padding
+     * characters are truncated if they exceed `length`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to pad.
+     * @param {number} [length=0] The padding length.
+     * @param {string} [chars=' '] The string used as padding.
+     * @returns {string} Returns the padded string.
+     * @example
+     *
+     * _.padEnd('abc', 6);
+     * // => 'abc   '
+     *
+     * _.padEnd('abc', 6, '_-');
+     * // => 'abc_-_'
+     *
+     * _.padEnd('abc', 3);
+     * // => 'abc'
+     */
+    function padEnd(string, length, chars) {
+      string = toString(string);
+      length = toInteger(length);
+
+      var strLength = length ? stringSize(string) : 0;
+      return (length && strLength < length)
+        ? (string + createPadding(length - strLength, chars))
+        : string;
+    }
+
+    /**
+     * Pads `string` on the left side if it's shorter than `length`. Padding
+     * characters are truncated if they exceed `length`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to pad.
+     * @param {number} [length=0] The padding length.
+     * @param {string} [chars=' '] The string used as padding.
+     * @returns {string} Returns the padded string.
+     * @example
+     *
+     * _.padStart('abc', 6);
+     * // => '   abc'
+     *
+     * _.padStart('abc', 6, '_-');
+     * // => '_-_abc'
+     *
+     * _.padStart('abc', 3);
+     * // => 'abc'
+     */
+    function padStart(string, length, chars) {
+      string = toString(string);
+      length = toInteger(length);
+
+      var strLength = length ? stringSize(string) : 0;
+      return (length && strLength < length)
+        ? (createPadding(length - strLength, chars) + string)
+        : string;
+    }
+
+    /**
+     * Converts `string` to an integer of the specified radix. If `radix` is
+     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
+     * hexadecimal, in which case a `radix` of `16` is used.
+     *
+     * **Note:** This method aligns with the
+     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
+     *
+     * @static
+     * @memberOf _
+     * @since 1.1.0
+     * @category String
+     * @param {string} string The string to convert.
+     * @param {number} [radix=10] The radix to interpret `value` by.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {number} Returns the converted integer.
+     * @example
+     *
+     * _.parseInt('08');
+     * // => 8
+     *
+     * _.map(['6', '08', '10'], _.parseInt);
+     * // => [6, 8, 10]
+     */
+    function parseInt(string, radix, guard) {
+      if (guard || radix == null) {
+        radix = 0;
+      } else if (radix) {
+        radix = +radix;
+      }
+      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
+    }
+
+    /**
+     * Repeats the given string `n` times.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to repeat.
+     * @param {number} [n=1] The number of times to repeat the string.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {string} Returns the repeated string.
+     * @example
+     *
+     * _.repeat('*', 3);
+     * // => '***'
+     *
+     * _.repeat('abc', 2);
+     * // => 'abcabc'
+     *
+     * _.repeat('abc', 0);
+     * // => ''
+     */
+    function repeat(string, n, guard) {
+      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
+        n = 1;
+      } else {
+        n = toInteger(n);
+      }
+      return baseRepeat(toString(string), n);
+    }
+
+    /**
+     * Replaces matches for `pattern` in `string` with `replacement`.
+     *
+     * **Note:** This method is based on
+     * [`String#replace`](https://mdn.io/String/replace).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to modify.
+     * @param {RegExp|string} pattern The pattern to replace.
+     * @param {Function|string} replacement The match replacement.
+     * @returns {string} Returns the modified string.
+     * @example
+     *
+     * _.replace('Hi Fred', 'Fred', 'Barney');
+     * // => 'Hi Barney'
+     */
+    function replace() {
+      var args = arguments,
+          string = toString(args[0]);
+
+      return args.length < 3 ? string : string.replace(args[1], args[2]);
+    }
+
+    /**
+     * Converts `string` to
+     * [snake case](https://en.wikipedia.org/wiki/Snake_case).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the snake cased string.
+     * @example
+     *
+     * _.snakeCase('Foo Bar');
+     * // => 'foo_bar'
+     *
+     * _.snakeCase('fooBar');
+     * // => 'foo_bar'
+     *
+     * _.snakeCase('--FOO-BAR--');
+     * // => 'foo_bar'
+     */
+    var snakeCase = createCompounder(function(result, word, index) {
+      return result + (index ? '_' : '') + word.toLowerCase();
+    });
+
+    /**
+     * Splits `string` by `separator`.
+     *
+     * **Note:** This method is based on
+     * [`String#split`](https://mdn.io/String/split).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to split.
+     * @param {RegExp|string} separator The separator pattern to split by.
+     * @param {number} [limit] The length to truncate results to.
+     * @returns {Array} Returns the string segments.
+     * @example
+     *
+     * _.split('a-b-c', '-', 2);
+     * // => ['a', 'b']
+     */
+    function split(string, separator, limit) {
+      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
+        separator = limit = undefined;
+      }
+      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
+      if (!limit) {
+        return [];
+      }
+      string = toString(string);
+      if (string && (
+            typeof separator == 'string' ||
+            (separator != null && !isRegExp(separator))
+          )) {
+        separator = baseToString(separator);
+        if (!separator && hasUnicode(string)) {
+          return castSlice(stringToArray(string), 0, limit);
+        }
+      }
+      return string.split(separator, limit);
+    }
+
+    /**
+     * Converts `string` to
+     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
+     *
+     * @static
+     * @memberOf _
+     * @since 3.1.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the start cased string.
+     * @example
+     *
+     * _.startCase('--foo-bar--');
+     * // => 'Foo Bar'
+     *
+     * _.startCase('fooBar');
+     * // => 'Foo Bar'
+     *
+     * _.startCase('__FOO_BAR__');
+     * // => 'FOO BAR'
+     */
+    var startCase = createCompounder(function(result, word, index) {
+      return result + (index ? ' ' : '') + upperFirst(word);
+    });
+
+    /**
+     * Checks if `string` starts with the given target string.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to inspect.
+     * @param {string} [target] The string to search for.
+     * @param {number} [position=0] The position to search from.
+     * @returns {boolean} Returns `true` if `string` starts with `target`,
+     *  else `false`.
+     * @example
+     *
+     * _.startsWith('abc', 'a');
+     * // => true
+     *
+     * _.startsWith('abc', 'b');
+     * // => false
+     *
+     * _.startsWith('abc', 'b', 1);
+     * // => true
+     */
+    function startsWith(string, target, position) {
+      string = toString(string);
+      position = position == null
+        ? 0
+        : baseClamp(toInteger(position), 0, string.length);
+
+      target = baseToString(target);
+      return string.slice(position, position + target.length) == target;
+    }
+
+    /**
+     * Creates a compiled template function that can interpolate data properties
+     * in "interpolate" delimiters, HTML-escape interpolated data properties in
+     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
+     * properties may be accessed as free variables in the template. If a setting
+     * object is given, it takes precedence over `_.templateSettings` values.
+     *
+     * **Note:** In the development build `_.template` utilizes
+     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
+     * for easier debugging.
+     *
+     * For more information on precompiling templates see
+     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
+     *
+     * For more information on Chrome extension sandboxes see
+     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category String
+     * @param {string} [string=''] The template string.
+     * @param {Object} [options={}] The options object.
+     * @param {RegExp} [options.escape=_.templateSettings.escape]
+     *  The HTML "escape" delimiter.
+     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
+     *  The "evaluate" delimiter.
+     * @param {Object} [options.imports=_.templateSettings.imports]
+     *  An object to import into the template as free variables.
+     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
+     *  The "interpolate" delimiter.
+     * @param {string} [options.sourceURL='lodash.templateSources[n]']
+     *  The sourceURL of the compiled template.
+     * @param {string} [options.variable='obj']
+     *  The data object variable name.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Function} Returns the compiled template function.
+     * @example
+     *
+     * // Use the "interpolate" delimiter to create a compiled template.
+     * var compiled = _.template('hello <%= user %>!');
+     * compiled({ 'user': 'fred' });
+     * // => 'hello fred!'
+     *
+     * // Use the HTML "escape" delimiter to escape data property values.
+     * var compiled = _.template('<b><%- value %></b>');
+     * compiled({ 'value': '<script>' });
+     * // => '<b>&lt;script&gt;</b>'
+     *
+     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
+     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
+     * compiled({ 'users': ['fred', 'barney'] });
+     * // => '<li>fred</li><li>barney</li>'
+     *
+     * // Use the internal `print` function in "evaluate" delimiters.
+     * var compiled = _.template('<% print("hello " + user); %>!');
+     * compiled({ 'user': 'barney' });
+     * // => 'hello barney!'
+     *
+     * // Use the ES template literal delimiter as an "interpolate" delimiter.
+     * // Disable support by replacing the "interpolate" delimiter.
+     * var compiled = _.template('hello ${ user }!');
+     * compiled({ 'user': 'pebbles' });
+     * // => 'hello pebbles!'
+     *
+     * // Use backslashes to treat delimiters as plain text.
+     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
+     * compiled({ 'value': 'ignored' });
+     * // => '<%- value %>'
+     *
+     * // Use the `imports` option to import `jQuery` as `jq`.
+     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
+     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
+     * compiled({ 'users': ['fred', 'barney'] });
+     * // => '<li>fred</li><li>barney</li>'
+     *
+     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
+     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
+     * compiled(data);
+     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
+     *
+     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
+     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
+     * compiled.source;
+     * // => function(data) {
+     * //   var __t, __p = '';
+     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
+     * //   return __p;
+     * // }
+     *
+     * // Use custom template delimiters.
+     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
+     * var compiled = _.template('hello {{ user }}!');
+     * compiled({ 'user': 'mustache' });
+     * // => 'hello mustache!'
+     *
+     * // Use the `source` property to inline compiled templates for meaningful
+     * // line numbers in error messages and stack traces.
+     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
+     *   var JST = {\
+     *     "main": ' + _.template(mainText).source + '\
+     *   };\
+     * ');
+     */
+    function template(string, options, guard) {
+      // Based on John Resig's `tmpl` implementation
+      // (http://ejohn.org/blog/javascript-micro-templating/)
+      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
+      var settings = lodash.templateSettings;
+
+      if (guard && isIterateeCall(string, options, guard)) {
+        options = undefined;
+      }
+      string = toString(string);
+      options = assignInWith({}, options, settings, customDefaultsAssignIn);
+
+      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
+          importsKeys = keys(imports),
+          importsValues = baseValues(imports, importsKeys);
+
+      var isEscaping,
+          isEvaluating,
+          index = 0,
+          interpolate = options.interpolate || reNoMatch,
+          source = "__p += '";
+
+      // Compile the regexp to match each delimiter.
+      var reDelimiters = RegExp(
+        (options.escape || reNoMatch).source + '|' +
+        interpolate.source + '|' +
+        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
+        (options.evaluate || reNoMatch).source + '|$'
+      , 'g');
+
+      // Use a sourceURL for easier debugging.
+      var sourceURL = '//# sourceURL=' +
+        ('sourceURL' in options
+          ? options.sourceURL
+          : ('lodash.templateSources[' + (++templateCounter) + ']')
+        ) + '\n';
+
+      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
+        interpolateValue || (interpolateValue = esTemplateValue);
+
+        // Escape characters that can't be included in string literals.
+        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
+
+        // Replace delimiters with snippets.
+        if (escapeValue) {
+          isEscaping = true;
+          source += "' +\n__e(" + escapeValue + ") +\n'";
+        }
+        if (evaluateValue) {
+          isEvaluating = true;
+          source += "';\n" + evaluateValue + ";\n__p += '";
+        }
+        if (interpolateValue) {
+          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
+        }
+        index = offset + match.length;
+
+        // The JS engine embedded in Adobe products needs `match` returned in
+        // order to produce the correct `offset` value.
+        return match;
+      });
+
+      source += "';\n";
+
+      // If `variable` is not specified wrap a with-statement around the generated
+      // code to add the data object to the top of the scope chain.
+      var variable = options.variable;
+      if (!variable) {
+        source = 'with (obj) {\n' + source + '\n}\n';
+      }
+      // Cleanup code by stripping empty strings.
+      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
+        .replace(reEmptyStringMiddle, '$1')
+        .replace(reEmptyStringTrailing, '$1;');
+
+      // Frame code as the function body.
+      source = 'function(' + (variable || 'obj') + ') {\n' +
+        (variable
+          ? ''
+          : 'obj || (obj = {});\n'
+        ) +
+        "var __t, __p = ''" +
+        (isEscaping
+           ? ', __e = _.escape'
+           : ''
+        ) +
+        (isEvaluating
+          ? ', __j = Array.prototype.join;\n' +
+            "function print() { __p += __j.call(arguments, '') }\n"
+          : ';\n'
+        ) +
+        source +
+        'return __p\n}';
+
+      var result = attempt(function() {
+        return Function(importsKeys, sourceURL + 'return ' + source)
+          .apply(undefined, importsValues);
+      });
+
+      // Provide the compiled function's source by its `toString` method or
+      // the `source` property as a convenience for inlining compiled templates.
+      result.source = source;
+      if (isError(result)) {
+        throw result;
+      }
+      return result;
+    }
+
+    /**
+     * Converts `string`, as a whole, to lower case just like
+     * [String#toLowerCase](https://mdn.io/toLowerCase).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the lower cased string.
+     * @example
+     *
+     * _.toLower('--Foo-Bar--');
+     * // => '--foo-bar--'
+     *
+     * _.toLower('fooBar');
+     * // => 'foobar'
+     *
+     * _.toLower('__FOO_BAR__');
+     * // => '__foo_bar__'
+     */
+    function toLower(value) {
+      return toString(value).toLowerCase();
+    }
+
+    /**
+     * Converts `string`, as a whole, to upper case just like
+     * [String#toUpperCase](https://mdn.io/toUpperCase).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the upper cased string.
+     * @example
+     *
+     * _.toUpper('--foo-bar--');
+     * // => '--FOO-BAR--'
+     *
+     * _.toUpper('fooBar');
+     * // => 'FOOBAR'
+     *
+     * _.toUpper('__foo_bar__');
+     * // => '__FOO_BAR__'
+     */
+    function toUpper(value) {
+      return toString(value).toUpperCase();
+    }
+
+    /**
+     * Removes leading and trailing whitespace or specified characters from `string`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to trim.
+     * @param {string} [chars=whitespace] The characters to trim.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {string} Returns the trimmed string.
+     * @example
+     *
+     * _.trim('  abc  ');
+     * // => 'abc'
+     *
+     * _.trim('-_-abc-_-', '_-');
+     * // => 'abc'
+     *
+     * _.map(['  foo  ', '  bar  '], _.trim);
+     * // => ['foo', 'bar']
+     */
+    function trim(string, chars, guard) {
+      string = toString(string);
+      if (string && (guard || chars === undefined)) {
+        return string.replace(reTrim, '');
+      }
+      if (!string || !(chars = baseToString(chars))) {
+        return string;
+      }
+      var strSymbols = stringToArray(string),
+          chrSymbols = stringToArray(chars),
+          start = charsStartIndex(strSymbols, chrSymbols),
+          end = charsEndIndex(strSymbols, chrSymbols) + 1;
+
+      return castSlice(strSymbols, start, end).join('');
+    }
+
+    /**
+     * Removes trailing whitespace or specified characters from `string`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to trim.
+     * @param {string} [chars=whitespace] The characters to trim.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {string} Returns the trimmed string.
+     * @example
+     *
+     * _.trimEnd('  abc  ');
+     * // => '  abc'
+     *
+     * _.trimEnd('-_-abc-_-', '_-');
+     * // => '-_-abc'
+     */
+    function trimEnd(string, chars, guard) {
+      string = toString(string);
+      if (string && (guard || chars === undefined)) {
+        return string.replace(reTrimEnd, '');
+      }
+      if (!string || !(chars = baseToString(chars))) {
+        return string;
+      }
+      var strSymbols = stringToArray(string),
+          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
+
+      return castSlice(strSymbols, 0, end).join('');
+    }
+
+    /**
+     * Removes leading whitespace or specified characters from `string`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to trim.
+     * @param {string} [chars=whitespace] The characters to trim.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {string} Returns the trimmed string.
+     * @example
+     *
+     * _.trimStart('  abc  ');
+     * // => 'abc  '
+     *
+     * _.trimStart('-_-abc-_-', '_-');
+     * // => 'abc-_-'
+     */
+    function trimStart(string, chars, guard) {
+      string = toString(string);
+      if (string && (guard || chars === undefined)) {
+        return string.replace(reTrimStart, '');
+      }
+      if (!string || !(chars = baseToString(chars))) {
+        return string;
+      }
+      var strSymbols = stringToArray(string),
+          start = charsStartIndex(strSymbols, stringToArray(chars));
+
+      return castSlice(strSymbols, start).join('');
+    }
+
+    /**
+     * Truncates `string` if it's longer than the given maximum string length.
+     * The last characters of the truncated string are replaced with the omission
+     * string which defaults to "...".
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to truncate.
+     * @param {Object} [options={}] The options object.
+     * @param {number} [options.length=30] The maximum string length.
+     * @param {string} [options.omission='...'] The string to indicate text is omitted.
+     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
+     * @returns {string} Returns the truncated string.
+     * @example
+     *
+     * _.truncate('hi-diddly-ho there, neighborino');
+     * // => 'hi-diddly-ho there, neighbo...'
+     *
+     * _.truncate('hi-diddly-ho there, neighborino', {
+     *   'length': 24,
+     *   'separator': ' '
+     * });
+     * // => 'hi-diddly-ho there,...'
+     *
+     * _.truncate('hi-diddly-ho there, neighborino', {
+     *   'length': 24,
+     *   'separator': /,? +/
+     * });
+     * // => 'hi-diddly-ho there...'
+     *
+     * _.truncate('hi-diddly-ho there, neighborino', {
+     *   'omission': ' [...]'
+     * });
+     * // => 'hi-diddly-ho there, neig [...]'
+     */
+    function truncate(string, options) {
+      var length = DEFAULT_TRUNC_LENGTH,
+          omission = DEFAULT_TRUNC_OMISSION;
+
+      if (isObject(options)) {
+        var separator = 'separator' in options ? options.separator : separator;
+        length = 'length' in options ? toInteger(options.length) : length;
+        omission = 'omission' in options ? baseToString(options.omission) : omission;
+      }
+      string = toString(string);
+
+      var strLength = string.length;
+      if (hasUnicode(string)) {
+        var strSymbols = stringToArray(string);
+        strLength = strSymbols.length;
+      }
+      if (length >= strLength) {
+        return string;
+      }
+      var end = length - stringSize(omission);
+      if (end < 1) {
+        return omission;
+      }
+      var result = strSymbols
+        ? castSlice(strSymbols, 0, end).join('')
+        : string.slice(0, end);
+
+      if (separator === undefined) {
+        return result + omission;
+      }
+      if (strSymbols) {
+        end += (result.length - end);
+      }
+      if (isRegExp(separator)) {
+        if (string.slice(end).search(separator)) {
+          var match,
+              substring = result;
+
+          if (!separator.global) {
+            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
+          }
+          separator.lastIndex = 0;
+          while ((match = separator.exec(substring))) {
+            var newEnd = match.index;
+          }
+          result = result.slice(0, newEnd === undefined ? end : newEnd);
+        }
+      } else if (string.indexOf(baseToString(separator), end) != end) {
+        var index = result.lastIndexOf(separator);
+        if (index > -1) {
+          result = result.slice(0, index);
+        }
+      }
+      return result + omission;
+    }
+
+    /**
+     * The inverse of `_.escape`; this method converts the HTML entities
+     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
+     * their corresponding characters.
+     *
+     * **Note:** No other HTML entities are unescaped. To unescape additional
+     * HTML entities use a third-party library like [_he_](https://mths.be/he).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.6.0
+     * @category String
+     * @param {string} [string=''] The string to unescape.
+     * @returns {string} Returns the unescaped string.
+     * @example
+     *
+     * _.unescape('fred, barney, &amp; pebbles');
+     * // => 'fred, barney, & pebbles'
+     */
+    function unescape(string) {
+      string = toString(string);
+      return (string && reHasEscapedHtml.test(string))
+        ? string.replace(reEscapedHtml, unescapeHtmlChar)
+        : string;
+    }
+
+    /**
+     * Converts `string`, as space separated words, to upper case.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the upper cased string.
+     * @example
+     *
+     * _.upperCase('--foo-bar');
+     * // => 'FOO BAR'
+     *
+     * _.upperCase('fooBar');
+     * // => 'FOO BAR'
+     *
+     * _.upperCase('__foo_bar__');
+     * // => 'FOO BAR'
+     */
+    var upperCase = createCompounder(function(result, word, index) {
+      return result + (index ? ' ' : '') + word.toUpperCase();
+    });
+
+    /**
+     * Converts the first character of `string` to upper case.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category String
+     * @param {string} [string=''] The string to convert.
+     * @returns {string} Returns the converted string.
+     * @example
+     *
+     * _.upperFirst('fred');
+     * // => 'Fred'
+     *
+     * _.upperFirst('FRED');
+     * // => 'FRED'
+     */
+    var upperFirst = createCaseFirst('toUpperCase');
+
+    /**
+     * Splits `string` into an array of its words.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category String
+     * @param {string} [string=''] The string to inspect.
+     * @param {RegExp|string} [pattern] The pattern to match words.
+     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
+     * @returns {Array} Returns the words of `string`.
+     * @example
+     *
+     * _.words('fred, barney, & pebbles');
+     * // => ['fred', 'barney', 'pebbles']
+     *
+     * _.words('fred, barney, & pebbles', /[^, ]+/g);
+     * // => ['fred', 'barney', '&', 'pebbles']
+     */
+    function words(string, pattern, guard) {
+      string = toString(string);
+      pattern = guard ? undefined : pattern;
+
+      if (pattern === undefined) {
+        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
+      }
+      return string.match(pattern) || [];
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Attempts to invoke `func`, returning either the result or the caught error
+     * object. Any additional arguments are provided to `func` when it's invoked.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Util
+     * @param {Function} func The function to attempt.
+     * @param {...*} [args] The arguments to invoke `func` with.
+     * @returns {*} Returns the `func` result or error object.
+     * @example
+     *
+     * // Avoid throwing errors for invalid selectors.
+     * var elements = _.attempt(function(selector) {
+     *   return document.querySelectorAll(selector);
+     * }, '>_>');
+     *
+     * if (_.isError(elements)) {
+     *   elements = [];
+     * }
+     */
+    var attempt = baseRest(function(func, args) {
+      try {
+        return apply(func, undefined, args);
+      } catch (e) {
+        return isError(e) ? e : new Error(e);
+      }
+    });
+
+    /**
+     * Binds methods of an object to the object itself, overwriting the existing
+     * method.
+     *
+     * **Note:** This method doesn't set the "length" property of bound functions.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Util
+     * @param {Object} object The object to bind and assign the bound methods to.
+     * @param {...(string|string[])} methodNames The object method names to bind.
+     * @returns {Object} Returns `object`.
+     * @example
+     *
+     * var view = {
+     *   'label': 'docs',
+     *   'click': function() {
+     *     console.log('clicked ' + this.label);
+     *   }
+     * };
+     *
+     * _.bindAll(view, ['click']);
+     * jQuery(element).on('click', view.click);
+     * // => Logs 'clicked docs' when clicked.
+     */
+    var bindAll = flatRest(function(object, methodNames) {
+      arrayEach(methodNames, function(key) {
+        key = toKey(key);
+        baseAssignValue(object, key, bind(object[key], object));
+      });
+      return object;
+    });
+
+    /**
+     * Creates a function that iterates over `pairs` and invokes the corresponding
+     * function of the first predicate to return truthy. The predicate-function
+     * pairs are invoked with the `this` binding and arguments of the created
+     * function.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {Array} pairs The predicate-function pairs.
+     * @returns {Function} Returns the new composite function.
+     * @example
+     *
+     * var func = _.cond([
+     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
+     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
+     *   [_.stubTrue,                      _.constant('no match')]
+     * ]);
+     *
+     * func({ 'a': 1, 'b': 2 });
+     * // => 'matches A'
+     *
+     * func({ 'a': 0, 'b': 1 });
+     * // => 'matches B'
+     *
+     * func({ 'a': '1', 'b': '2' });
+     * // => 'no match'
+     */
+    function cond(pairs) {
+      var length = pairs == null ? 0 : pairs.length,
+          toIteratee = getIteratee();
+
+      pairs = !length ? [] : arrayMap(pairs, function(pair) {
+        if (typeof pair[1] != 'function') {
+          throw new TypeError(FUNC_ERROR_TEXT);
+        }
+        return [toIteratee(pair[0]), pair[1]];
+      });
+
+      return baseRest(function(args) {
+        var index = -1;
+        while (++index < length) {
+          var pair = pairs[index];
+          if (apply(pair[0], this, args)) {
+            return apply(pair[1], this, args);
+          }
+        }
+      });
+    }
+
+    /**
+     * Creates a function that invokes the predicate properties of `source` with
+     * the corresponding property values of a given object, returning `true` if
+     * all predicates return truthy, else `false`.
+     *
+     * **Note:** The created function is equivalent to `_.conformsTo` with
+     * `source` partially applied.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {Object} source The object of property predicates to conform to.
+     * @returns {Function} Returns the new spec function.
+     * @example
+     *
+     * var objects = [
+     *   { 'a': 2, 'b': 1 },
+     *   { 'a': 1, 'b': 2 }
+     * ];
+     *
+     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
+     * // => [{ 'a': 1, 'b': 2 }]
+     */
+    function conforms(source) {
+      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
+    }
+
+    /**
+     * Creates a function that returns `value`.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.4.0
+     * @category Util
+     * @param {*} value The value to return from the new function.
+     * @returns {Function} Returns the new constant function.
+     * @example
+     *
+     * var objects = _.times(2, _.constant({ 'a': 1 }));
+     *
+     * console.log(objects);
+     * // => [{ 'a': 1 }, { 'a': 1 }]
+     *
+     * console.log(objects[0] === objects[1]);
+     * // => true
+     */
+    function constant(value) {
+      return function() {
+        return value;
+      };
+    }
+
+    /**
+     * Checks `value` to determine whether a default value should be returned in
+     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
+     * or `undefined`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.14.0
+     * @category Util
+     * @param {*} value The value to check.
+     * @param {*} defaultValue The default value.
+     * @returns {*} Returns the resolved value.
+     * @example
+     *
+     * _.defaultTo(1, 10);
+     * // => 1
+     *
+     * _.defaultTo(undefined, 10);
+     * // => 10
+     */
+    function defaultTo(value, defaultValue) {
+      return (value == null || value !== value) ? defaultValue : value;
+    }
+
+    /**
+     * Creates a function that returns the result of invoking the given functions
+     * with the `this` binding of the created function, where each successive
+     * invocation is supplied the return value of the previous.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Util
+     * @param {...(Function|Function[])} [funcs] The functions to invoke.
+     * @returns {Function} Returns the new composite function.
+     * @see _.flowRight
+     * @example
+     *
+     * function square(n) {
+     *   return n * n;
+     * }
+     *
+     * var addSquare = _.flow([_.add, square]);
+     * addSquare(1, 2);
+     * // => 9
+     */
+    var flow = createFlow();
+
+    /**
+     * This method is like `_.flow` except that it creates a function that
+     * invokes the given functions from right to left.
+     *
+     * @static
+     * @since 3.0.0
+     * @memberOf _
+     * @category Util
+     * @param {...(Function|Function[])} [funcs] The functions to invoke.
+     * @returns {Function} Returns the new composite function.
+     * @see _.flow
+     * @example
+     *
+     * function square(n) {
+     *   return n * n;
+     * }
+     *
+     * var addSquare = _.flowRight([square, _.add]);
+     * addSquare(1, 2);
+     * // => 9
+     */
+    var flowRight = createFlow(true);
+
+    /**
+     * This method returns the first argument it receives.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Util
+     * @param {*} value Any value.
+     * @returns {*} Returns `value`.
+     * @example
+     *
+     * var object = { 'a': 1 };
+     *
+     * console.log(_.identity(object) === object);
+     * // => true
+     */
+    function identity(value) {
+      return value;
+    }
+
+    /**
+     * Creates a function that invokes `func` with the arguments of the created
+     * function. If `func` is a property name, the created function returns the
+     * property value for a given element. If `func` is an array or object, the
+     * created function returns `true` for elements that contain the equivalent
+     * source properties, otherwise it returns `false`.
+     *
+     * @static
+     * @since 4.0.0
+     * @memberOf _
+     * @category Util
+     * @param {*} [func=_.identity] The value to convert to a callback.
+     * @returns {Function} Returns the callback.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney', 'age': 36, 'active': true },
+     *   { 'user': 'fred',   'age': 40, 'active': false }
+     * ];
+     *
+     * // The `_.matches` iteratee shorthand.
+     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
+     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
+     *
+     * // The `_.matchesProperty` iteratee shorthand.
+     * _.filter(users, _.iteratee(['user', 'fred']));
+     * // => [{ 'user': 'fred', 'age': 40 }]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.map(users, _.iteratee('user'));
+     * // => ['barney', 'fred']
+     *
+     * // Create custom iteratee shorthands.
+     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
+     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
+     *     return func.test(string);
+     *   };
+     * });
+     *
+     * _.filter(['abc', 'def'], /ef/);
+     * // => ['def']
+     */
+    function iteratee(func) {
+      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
+    }
+
+    /**
+     * Creates a function that performs a partial deep comparison between a given
+     * object and `source`, returning `true` if the given object has equivalent
+     * property values, else `false`.
+     *
+     * **Note:** The created function is equivalent to `_.isMatch` with `source`
+     * partially applied.
+     *
+     * Partial comparisons will match empty array and empty object `source`
+     * values against any array or object value, respectively. See `_.isEqual`
+     * for a list of supported value comparisons.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Util
+     * @param {Object} source The object of property values to match.
+     * @returns {Function} Returns the new spec function.
+     * @example
+     *
+     * var objects = [
+     *   { 'a': 1, 'b': 2, 'c': 3 },
+     *   { 'a': 4, 'b': 5, 'c': 6 }
+     * ];
+     *
+     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
+     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
+     */
+    function matches(source) {
+      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
+    }
+
+    /**
+     * Creates a function that performs a partial deep comparison between the
+     * value at `path` of a given object to `srcValue`, returning `true` if the
+     * object value is equivalent, else `false`.
+     *
+     * **Note:** Partial comparisons will match empty array and empty object
+     * `srcValue` values against any array or object value, respectively. See
+     * `_.isEqual` for a list of supported value comparisons.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.2.0
+     * @category Util
+     * @param {Array|string} path The path of the property to get.
+     * @param {*} srcValue The value to match.
+     * @returns {Function} Returns the new spec function.
+     * @example
+     *
+     * var objects = [
+     *   { 'a': 1, 'b': 2, 'c': 3 },
+     *   { 'a': 4, 'b': 5, 'c': 6 }
+     * ];
+     *
+     * _.find(objects, _.matchesProperty('a', 4));
+     * // => { 'a': 4, 'b': 5, 'c': 6 }
+     */
+    function matchesProperty(path, srcValue) {
+      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
+    }
+
+    /**
+     * Creates a function that invokes the method at `path` of a given object.
+     * Any additional arguments are provided to the invoked method.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.7.0
+     * @category Util
+     * @param {Array|string} path The path of the method to invoke.
+     * @param {...*} [args] The arguments to invoke the method with.
+     * @returns {Function} Returns the new invoker function.
+     * @example
+     *
+     * var objects = [
+     *   { 'a': { 'b': _.constant(2) } },
+     *   { 'a': { 'b': _.constant(1) } }
+     * ];
+     *
+     * _.map(objects, _.method('a.b'));
+     * // => [2, 1]
+     *
+     * _.map(objects, _.method(['a', 'b']));
+     * // => [2, 1]
+     */
+    var method = baseRest(function(path, args) {
+      return function(object) {
+        return baseInvoke(object, path, args);
+      };
+    });
+
+    /**
+     * The opposite of `_.method`; this method creates a function that invokes
+     * the method at a given path of `object`. Any additional arguments are
+     * provided to the invoked method.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.7.0
+     * @category Util
+     * @param {Object} object The object to query.
+     * @param {...*} [args] The arguments to invoke the method with.
+     * @returns {Function} Returns the new invoker function.
+     * @example
+     *
+     * var array = _.times(3, _.constant),
+     *     object = { 'a': array, 'b': array, 'c': array };
+     *
+     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
+     * // => [2, 0]
+     *
+     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
+     * // => [2, 0]
+     */
+    var methodOf = baseRest(function(object, args) {
+      return function(path) {
+        return baseInvoke(object, path, args);
+      };
+    });
+
+    /**
+     * Adds all own enumerable string keyed function properties of a source
+     * object to the destination object. If `object` is a function, then methods
+     * are added to its prototype as well.
+     *
+     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
+     * avoid conflicts caused by modifying the original.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Util
+     * @param {Function|Object} [object=lodash] The destination object.
+     * @param {Object} source The object of functions to add.
+     * @param {Object} [options={}] The options object.
+     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
+     * @returns {Function|Object} Returns `object`.
+     * @example
+     *
+     * function vowels(string) {
+     *   return _.filter(string, function(v) {
+     *     return /[aeiou]/i.test(v);
+     *   });
+     * }
+     *
+     * _.mixin({ 'vowels': vowels });
+     * _.vowels('fred');
+     * // => ['e']
+     *
+     * _('fred').vowels().value();
+     * // => ['e']
+     *
+     * _.mixin({ 'vowels': vowels }, { 'chain': false });
+     * _('fred').vowels();
+     * // => ['e']
+     */
+    function mixin(object, source, options) {
+      var props = keys(source),
+          methodNames = baseFunctions(source, props);
+
+      if (options == null &&
+          !(isObject(source) && (methodNames.length || !props.length))) {
+        options = source;
+        source = object;
+        object = this;
+        methodNames = baseFunctions(source, keys(source));
+      }
+      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
+          isFunc = isFunction(object);
+
+      arrayEach(methodNames, function(methodName) {
+        var func = source[methodName];
+        object[methodName] = func;
+        if (isFunc) {
+          object.prototype[methodName] = function() {
+            var chainAll = this.__chain__;
+            if (chain || chainAll) {
+              var result = object(this.__wrapped__),
+                  actions = result.__actions__ = copyArray(this.__actions__);
+
+              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
+              result.__chain__ = chainAll;
+              return result;
+            }
+            return func.apply(object, arrayPush([this.value()], arguments));
+          };
+        }
+      });
+
+      return object;
+    }
+
+    /**
+     * Reverts the `_` variable to its previous value and returns a reference to
+     * the `lodash` function.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Util
+     * @returns {Function} Returns the `lodash` function.
+     * @example
+     *
+     * var lodash = _.noConflict();
+     */
+    function noConflict() {
+      if (root._ === this) {
+        root._ = oldDash;
+      }
+      return this;
+    }
+
+    /**
+     * This method returns `undefined`.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.3.0
+     * @category Util
+     * @example
+     *
+     * _.times(2, _.noop);
+     * // => [undefined, undefined]
+     */
+    function noop() {
+      // No operation performed.
+    }
+
+    /**
+     * Creates a function that gets the argument at index `n`. If `n` is negative,
+     * the nth argument from the end is returned.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {number} [n=0] The index of the argument to return.
+     * @returns {Function} Returns the new pass-thru function.
+     * @example
+     *
+     * var func = _.nthArg(1);
+     * func('a', 'b', 'c', 'd');
+     * // => 'b'
+     *
+     * var func = _.nthArg(-2);
+     * func('a', 'b', 'c', 'd');
+     * // => 'c'
+     */
+    function nthArg(n) {
+      n = toInteger(n);
+      return baseRest(function(args) {
+        return baseNth(args, n);
+      });
+    }
+
+    /**
+     * Creates a function that invokes `iteratees` with the arguments it receives
+     * and returns their results.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {...(Function|Function[])} [iteratees=[_.identity]]
+     *  The iteratees to invoke.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var func = _.over([Math.max, Math.min]);
+     *
+     * func(1, 2, 3, 4);
+     * // => [4, 1]
+     */
+    var over = createOver(arrayMap);
+
+    /**
+     * Creates a function that checks if **all** of the `predicates` return
+     * truthy when invoked with the arguments it receives.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {...(Function|Function[])} [predicates=[_.identity]]
+     *  The predicates to check.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var func = _.overEvery([Boolean, isFinite]);
+     *
+     * func('1');
+     * // => true
+     *
+     * func(null);
+     * // => false
+     *
+     * func(NaN);
+     * // => false
+     */
+    var overEvery = createOver(arrayEvery);
+
+    /**
+     * Creates a function that checks if **any** of the `predicates` return
+     * truthy when invoked with the arguments it receives.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {...(Function|Function[])} [predicates=[_.identity]]
+     *  The predicates to check.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var func = _.overSome([Boolean, isFinite]);
+     *
+     * func('1');
+     * // => true
+     *
+     * func(null);
+     * // => true
+     *
+     * func(NaN);
+     * // => false
+     */
+    var overSome = createOver(arraySome);
+
+    /**
+     * Creates a function that returns the value at `path` of a given object.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.4.0
+     * @category Util
+     * @param {Array|string} path The path of the property to get.
+     * @returns {Function} Returns the new accessor function.
+     * @example
+     *
+     * var objects = [
+     *   { 'a': { 'b': 2 } },
+     *   { 'a': { 'b': 1 } }
+     * ];
+     *
+     * _.map(objects, _.property('a.b'));
+     * // => [2, 1]
+     *
+     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
+     * // => [1, 2]
+     */
+    function property(path) {
+      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
+    }
+
+    /**
+     * The opposite of `_.property`; this method creates a function that returns
+     * the value at a given path of `object`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Util
+     * @param {Object} object The object to query.
+     * @returns {Function} Returns the new accessor function.
+     * @example
+     *
+     * var array = [0, 1, 2],
+     *     object = { 'a': array, 'b': array, 'c': array };
+     *
+     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
+     * // => [2, 0]
+     *
+     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
+     * // => [2, 0]
+     */
+    function propertyOf(object) {
+      return function(path) {
+        return object == null ? undefined : baseGet(object, path);
+      };
+    }
+
+    /**
+     * Creates an array of numbers (positive and/or negative) progressing from
+     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
+     * `start` is specified without an `end` or `step`. If `end` is not specified,
+     * it's set to `start` with `start` then set to `0`.
+     *
+     * **Note:** JavaScript follows the IEEE-754 standard for resolving
+     * floating-point values which can produce unexpected results.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Util
+     * @param {number} [start=0] The start of the range.
+     * @param {number} end The end of the range.
+     * @param {number} [step=1] The value to increment or decrement by.
+     * @returns {Array} Returns the range of numbers.
+     * @see _.inRange, _.rangeRight
+     * @example
+     *
+     * _.range(4);
+     * // => [0, 1, 2, 3]
+     *
+     * _.range(-4);
+     * // => [0, -1, -2, -3]
+     *
+     * _.range(1, 5);
+     * // => [1, 2, 3, 4]
+     *
+     * _.range(0, 20, 5);
+     * // => [0, 5, 10, 15]
+     *
+     * _.range(0, -4, -1);
+     * // => [0, -1, -2, -3]
+     *
+     * _.range(1, 4, 0);
+     * // => [1, 1, 1]
+     *
+     * _.range(0);
+     * // => []
+     */
+    var range = createRange();
+
+    /**
+     * This method is like `_.range` except that it populates values in
+     * descending order.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {number} [start=0] The start of the range.
+     * @param {number} end The end of the range.
+     * @param {number} [step=1] The value to increment or decrement by.
+     * @returns {Array} Returns the range of numbers.
+     * @see _.inRange, _.range
+     * @example
+     *
+     * _.rangeRight(4);
+     * // => [3, 2, 1, 0]
+     *
+     * _.rangeRight(-4);
+     * // => [-3, -2, -1, 0]
+     *
+     * _.rangeRight(1, 5);
+     * // => [4, 3, 2, 1]
+     *
+     * _.rangeRight(0, 20, 5);
+     * // => [15, 10, 5, 0]
+     *
+     * _.rangeRight(0, -4, -1);
+     * // => [-3, -2, -1, 0]
+     *
+     * _.rangeRight(1, 4, 0);
+     * // => [1, 1, 1]
+     *
+     * _.rangeRight(0);
+     * // => []
+     */
+    var rangeRight = createRange(true);
+
+    /**
+     * This method returns a new empty array.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.13.0
+     * @category Util
+     * @returns {Array} Returns the new empty array.
+     * @example
+     *
+     * var arrays = _.times(2, _.stubArray);
+     *
+     * console.log(arrays);
+     * // => [[], []]
+     *
+     * console.log(arrays[0] === arrays[1]);
+     * // => false
+     */
+    function stubArray() {
+      return [];
+    }
+
+    /**
+     * This method returns `false`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.13.0
+     * @category Util
+     * @returns {boolean} Returns `false`.
+     * @example
+     *
+     * _.times(2, _.stubFalse);
+     * // => [false, false]
+     */
+    function stubFalse() {
+      return false;
+    }
+
+    /**
+     * This method returns a new empty object.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.13.0
+     * @category Util
+     * @returns {Object} Returns the new empty object.
+     * @example
+     *
+     * var objects = _.times(2, _.stubObject);
+     *
+     * console.log(objects);
+     * // => [{}, {}]
+     *
+     * console.log(objects[0] === objects[1]);
+     * // => false
+     */
+    function stubObject() {
+      return {};
+    }
+
+    /**
+     * This method returns an empty string.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.13.0
+     * @category Util
+     * @returns {string} Returns the empty string.
+     * @example
+     *
+     * _.times(2, _.stubString);
+     * // => ['', '']
+     */
+    function stubString() {
+      return '';
+    }
+
+    /**
+     * This method returns `true`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.13.0
+     * @category Util
+     * @returns {boolean} Returns `true`.
+     * @example
+     *
+     * _.times(2, _.stubTrue);
+     * // => [true, true]
+     */
+    function stubTrue() {
+      return true;
+    }
+
+    /**
+     * Invokes the iteratee `n` times, returning an array of the results of
+     * each invocation. The iteratee is invoked with one argument; (index).
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Util
+     * @param {number} n The number of times to invoke `iteratee`.
+     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+     * @returns {Array} Returns the array of results.
+     * @example
+     *
+     * _.times(3, String);
+     * // => ['0', '1', '2']
+     *
+     *  _.times(4, _.constant(0));
+     * // => [0, 0, 0, 0]
+     */
+    function times(n, iteratee) {
+      n = toInteger(n);
+      if (n < 1 || n > MAX_SAFE_INTEGER) {
+        return [];
+      }
+      var index = MAX_ARRAY_LENGTH,
+          length = nativeMin(n, MAX_ARRAY_LENGTH);
+
+      iteratee = getIteratee(iteratee);
+      n -= MAX_ARRAY_LENGTH;
+
+      var result = baseTimes(length, iteratee);
+      while (++index < n) {
+        iteratee(index);
+      }
+      return result;
+    }
+
+    /**
+     * Converts `value` to a property path array.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {*} value The value to convert.
+     * @returns {Array} Returns the new property path array.
+     * @example
+     *
+     * _.toPath('a.b.c');
+     * // => ['a', 'b', 'c']
+     *
+     * _.toPath('a[0].b.c');
+     * // => ['a', '0', 'b', 'c']
+     */
+    function toPath(value) {
+      if (isArray(value)) {
+        return arrayMap(value, toKey);
+      }
+      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
+    }
+
+    /**
+     * Generates a unique ID. If `prefix` is given, the ID is appended to it.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Util
+     * @param {string} [prefix=''] The value to prefix the ID with.
+     * @returns {string} Returns the unique ID.
+     * @example
+     *
+     * _.uniqueId('contact_');
+     * // => 'contact_104'
+     *
+     * _.uniqueId();
+     * // => '105'
+     */
+    function uniqueId(prefix) {
+      var id = ++idCounter;
+      return toString(prefix) + id;
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Adds two numbers.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.4.0
+     * @category Math
+     * @param {number} augend The first number in an addition.
+     * @param {number} addend The second number in an addition.
+     * @returns {number} Returns the total.
+     * @example
+     *
+     * _.add(6, 4);
+     * // => 10
+     */
+    var add = createMathOperation(function(augend, addend) {
+      return augend + addend;
+    }, 0);
+
+    /**
+     * Computes `number` rounded up to `precision`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.10.0
+     * @category Math
+     * @param {number} number The number to round up.
+     * @param {number} [precision=0] The precision to round up to.
+     * @returns {number} Returns the rounded up number.
+     * @example
+     *
+     * _.ceil(4.006);
+     * // => 5
+     *
+     * _.ceil(6.004, 2);
+     * // => 6.01
+     *
+     * _.ceil(6040, -2);
+     * // => 6100
+     */
+    var ceil = createRound('ceil');
+
+    /**
+     * Divide two numbers.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.7.0
+     * @category Math
+     * @param {number} dividend The first number in a division.
+     * @param {number} divisor The second number in a division.
+     * @returns {number} Returns the quotient.
+     * @example
+     *
+     * _.divide(6, 4);
+     * // => 1.5
+     */
+    var divide = createMathOperation(function(dividend, divisor) {
+      return dividend / divisor;
+    }, 1);
+
+    /**
+     * Computes `number` rounded down to `precision`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.10.0
+     * @category Math
+     * @param {number} number The number to round down.
+     * @param {number} [precision=0] The precision to round down to.
+     * @returns {number} Returns the rounded down number.
+     * @example
+     *
+     * _.floor(4.006);
+     * // => 4
+     *
+     * _.floor(0.046, 2);
+     * // => 0.04
+     *
+     * _.floor(4060, -2);
+     * // => 4000
+     */
+    var floor = createRound('floor');
+
+    /**
+     * Computes the maximum value of `array`. If `array` is empty or falsey,
+     * `undefined` is returned.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Math
+     * @param {Array} array The array to iterate over.
+     * @returns {*} Returns the maximum value.
+     * @example
+     *
+     * _.max([4, 2, 8, 6]);
+     * // => 8
+     *
+     * _.max([]);
+     * // => undefined
+     */
+    function max(array) {
+      return (array && array.length)
+        ? baseExtremum(array, identity, baseGt)
+        : undefined;
+    }
+
+    /**
+     * This method is like `_.max` except that it accepts `iteratee` which is
+     * invoked for each element in `array` to generate the criterion by which
+     * the value is ranked. The iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Math
+     * @param {Array} array The array to iterate over.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {*} Returns the maximum value.
+     * @example
+     *
+     * var objects = [{ 'n': 1 }, { 'n': 2 }];
+     *
+     * _.maxBy(objects, function(o) { return o.n; });
+     * // => { 'n': 2 }
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.maxBy(objects, 'n');
+     * // => { 'n': 2 }
+     */
+    function maxBy(array, iteratee) {
+      return (array && array.length)
+        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
+        : undefined;
+    }
+
+    /**
+     * Computes the mean of the values in `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Math
+     * @param {Array} array The array to iterate over.
+     * @returns {number} Returns the mean.
+     * @example
+     *
+     * _.mean([4, 2, 8, 6]);
+     * // => 5
+     */
+    function mean(array) {
+      return baseMean(array, identity);
+    }
+
+    /**
+     * This method is like `_.mean` except that it accepts `iteratee` which is
+     * invoked for each element in `array` to generate the value to be averaged.
+     * The iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.7.0
+     * @category Math
+     * @param {Array} array The array to iterate over.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {number} Returns the mean.
+     * @example
+     *
+     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
+     *
+     * _.meanBy(objects, function(o) { return o.n; });
+     * // => 5
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.meanBy(objects, 'n');
+     * // => 5
+     */
+    function meanBy(array, iteratee) {
+      return baseMean(array, getIteratee(iteratee, 2));
+    }
+
+    /**
+     * Computes the minimum value of `array`. If `array` is empty or falsey,
+     * `undefined` is returned.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Math
+     * @param {Array} array The array to iterate over.
+     * @returns {*} Returns the minimum value.
+     * @example
+     *
+     * _.min([4, 2, 8, 6]);
+     * // => 2
+     *
+     * _.min([]);
+     * // => undefined
+     */
+    function min(array) {
+      return (array && array.length)
+        ? baseExtremum(array, identity, baseLt)
+        : undefined;
+    }
+
+    /**
+     * This method is like `_.min` except that it accepts `iteratee` which is
+     * invoked for each element in `array` to generate the criterion by which
+     * the value is ranked. The iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Math
+     * @param {Array} array The array to iterate over.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {*} Returns the minimum value.
+     * @example
+     *
+     * var objects = [{ 'n': 1 }, { 'n': 2 }];
+     *
+     * _.minBy(objects, function(o) { return o.n; });
+     * // => { 'n': 1 }
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.minBy(objects, 'n');
+     * // => { 'n': 1 }
+     */
+    function minBy(array, iteratee) {
+      return (array && array.length)
+        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
+        : undefined;
+    }
+
+    /**
+     * Multiply two numbers.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.7.0
+     * @category Math
+     * @param {number} multiplier The first number in a multiplication.
+     * @param {number} multiplicand The second number in a multiplication.
+     * @returns {number} Returns the product.
+     * @example
+     *
+     * _.multiply(6, 4);
+     * // => 24
+     */
+    var multiply = createMathOperation(function(multiplier, multiplicand) {
+      return multiplier * multiplicand;
+    }, 1);
+
+    /**
+     * Computes `number` rounded to `precision`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.10.0
+     * @category Math
+     * @param {number} number The number to round.
+     * @param {number} [precision=0] The precision to round to.
+     * @returns {number} Returns the rounded number.
+     * @example
+     *
+     * _.round(4.006);
+     * // => 4
+     *
+     * _.round(4.006, 2);
+     * // => 4.01
+     *
+     * _.round(4060, -2);
+     * // => 4100
+     */
+    var round = createRound('round');
+
+    /**
+     * Subtract two numbers.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Math
+     * @param {number} minuend The first number in a subtraction.
+     * @param {number} subtrahend The second number in a subtraction.
+     * @returns {number} Returns the difference.
+     * @example
+     *
+     * _.subtract(6, 4);
+     * // => 2
+     */
+    var subtract = createMathOperation(function(minuend, subtrahend) {
+      return minuend - subtrahend;
+    }, 0);
+
+    /**
+     * Computes the sum of the values in `array`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.4.0
+     * @category Math
+     * @param {Array} array The array to iterate over.
+     * @returns {number} Returns the sum.
+     * @example
+     *
+     * _.sum([4, 2, 8, 6]);
+     * // => 20
+     */
+    function sum(array) {
+      return (array && array.length)
+        ? baseSum(array, identity)
+        : 0;
+    }
+
+    /**
+     * This method is like `_.sum` except that it accepts `iteratee` which is
+     * invoked for each element in `array` to generate the value to be summed.
+     * The iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Math
+     * @param {Array} array The array to iterate over.
+     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
+     * @returns {number} Returns the sum.
+     * @example
+     *
+     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
+     *
+     * _.sumBy(objects, function(o) { return o.n; });
+     * // => 20
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.sumBy(objects, 'n');
+     * // => 20
+     */
+    function sumBy(array, iteratee) {
+      return (array && array.length)
+        ? baseSum(array, getIteratee(iteratee, 2))
+        : 0;
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    // Add methods that return wrapped values in chain sequences.
+    lodash.after = after;
+    lodash.ary = ary;
+    lodash.assign = assign;
+    lodash.assignIn = assignIn;
+    lodash.assignInWith = assignInWith;
+    lodash.assignWith = assignWith;
+    lodash.at = at;
+    lodash.before = before;
+    lodash.bind = bind;
+    lodash.bindAll = bindAll;
+    lodash.bindKey = bindKey;
+    lodash.castArray = castArray;
+    lodash.chain = chain;
+    lodash.chunk = chunk;
+    lodash.compact = compact;
+    lodash.concat = concat;
+    lodash.cond = cond;
+    lodash.conforms = conforms;
+    lodash.constant = constant;
+    lodash.countBy = countBy;
+    lodash.create = create;
+    lodash.curry = curry;
+    lodash.curryRight = curryRight;
+    lodash.debounce = debounce;
+    lodash.defaults = defaults;
+    lodash.defaultsDeep = defaultsDeep;
+    lodash.defer = defer;
+    lodash.delay = delay;
+    lodash.difference = difference;
+    lodash.differenceBy = differenceBy;
+    lodash.differenceWith = differenceWith;
+    lodash.drop = drop;
+    lodash.dropRight = dropRight;
+    lodash.dropRightWhile = dropRightWhile;
+    lodash.dropWhile = dropWhile;
+    lodash.fill = fill;
+    lodash.filter = filter;
+    lodash.flatMap = flatMap;
+    lodash.flatMapDeep = flatMapDeep;
+    lodash.flatMapDepth = flatMapDepth;
+    lodash.flatten = flatten;
+    lodash.flattenDeep = flattenDeep;
+    lodash.flattenDepth = flattenDepth;
+    lodash.flip = flip;
+    lodash.flow = flow;
+    lodash.flowRight = flowRight;
+    lodash.fromPairs = fromPairs;
+    lodash.functions = functions;
+    lodash.functionsIn = functionsIn;
+    lodash.groupBy = groupBy;
+    lodash.initial = initial;
+    lodash.intersection = intersection;
+    lodash.intersectionBy = intersectionBy;
+    lodash.intersectionWith = intersectionWith;
+    lodash.invert = invert;
+    lodash.invertBy = invertBy;
+    lodash.invokeMap = invokeMap;
+    lodash.iteratee = iteratee;
+    lodash.keyBy = keyBy;
+    lodash.keys = keys;
+    lodash.keysIn = keysIn;
+    lodash.map = map;
+    lodash.mapKeys = mapKeys;
+    lodash.mapValues = mapValues;
+    lodash.matches = matches;
+    lodash.matchesProperty = matchesProperty;
+    lodash.memoize = memoize;
+    lodash.merge = merge;
+    lodash.mergeWith = mergeWith;
+    lodash.method = method;
+    lodash.methodOf = methodOf;
+    lodash.mixin = mixin;
+    lodash.negate = negate;
+    lodash.nthArg = nthArg;
+    lodash.omit = omit;
+    lodash.omitBy = omitBy;
+    lodash.once = once;
+    lodash.orderBy = orderBy;
+    lodash.over = over;
+    lodash.overArgs = overArgs;
+    lodash.overEvery = overEvery;
+    lodash.overSome = overSome;
+    lodash.partial = partial;
+    lodash.partialRight = partialRight;
+    lodash.partition = partition;
+    lodash.pick = pick;
+    lodash.pickBy = pickBy;
+    lodash.property = property;
+    lodash.propertyOf = propertyOf;
+    lodash.pull = pull;
+    lodash.pullAll = pullAll;
+    lodash.pullAllBy = pullAllBy;
+    lodash.pullAllWith = pullAllWith;
+    lodash.pullAt = pullAt;
+    lodash.range = range;
+    lodash.rangeRight = rangeRight;
+    lodash.rearg = rearg;
+    lodash.reject = reject;
+    lodash.remove = remove;
+    lodash.rest = rest;
+    lodash.reverse = reverse;
+    lodash.sampleSize = sampleSize;
+    lodash.set = set;
+    lodash.setWith = setWith;
+    lodash.shuffle = shuffle;
+    lodash.slice = slice;
+    lodash.sortBy = sortBy;
+    lodash.sortedUniq = sortedUniq;
+    lodash.sortedUniqBy = sortedUniqBy;
+    lodash.split = split;
+    lodash.spread = spread;
+    lodash.tail = tail;
+    lodash.take = take;
+    lodash.takeRight = takeRight;
+    lodash.takeRightWhile = takeRightWhile;
+    lodash.takeWhile = takeWhile;
+    lodash.tap = tap;
+    lodash.throttle = throttle;
+    lodash.thru = thru;
+    lodash.toArray = toArray;
+    lodash.toPairs = toPairs;
+    lodash.toPairsIn = toPairsIn;
+    lodash.toPath = toPath;
+    lodash.toPlainObject = toPlainObject;
+    lodash.transform = transform;
+    lodash.unary = unary;
+    lodash.union = union;
+    lodash.unionBy = unionBy;
+    lodash.unionWith = unionWith;
+    lodash.uniq = uniq;
+    lodash.uniqBy = uniqBy;
+    lodash.uniqWith = uniqWith;
+    lodash.unset = unset;
+    lodash.unzip = unzip;
+    lodash.unzipWith = unzipWith;
+    lodash.update = update;
+    lodash.updateWith = updateWith;
+    lodash.values = values;
+    lodash.valuesIn = valuesIn;
+    lodash.without = without;
+    lodash.words = words;
+    lodash.wrap = wrap;
+    lodash.xor = xor;
+    lodash.xorBy = xorBy;
+    lodash.xorWith = xorWith;
+    lodash.zip = zip;
+    lodash.zipObject = zipObject;
+    lodash.zipObjectDeep = zipObjectDeep;
+    lodash.zipWith = zipWith;
+
+    // Add aliases.
+    lodash.entries = toPairs;
+    lodash.entriesIn = toPairsIn;
+    lodash.extend = assignIn;
+    lodash.extendWith = assignInWith;
+
+    // Add methods to `lodash.prototype`.
+    mixin(lodash, lodash);
+
+    /*------------------------------------------------------------------------*/
+
+    // Add methods that return unwrapped values in chain sequences.
+    lodash.add = add;
+    lodash.attempt = attempt;
+    lodash.camelCase = camelCase;
+    lodash.capitalize = capitalize;
+    lodash.ceil = ceil;
+    lodash.clamp = clamp;
+    lodash.clone = clone;
+    lodash.cloneDeep = cloneDeep;
+    lodash.cloneDeepWith = cloneDeepWith;
+    lodash.cloneWith = cloneWith;
+    lodash.conformsTo = conformsTo;
+    lodash.deburr = deburr;
+    lodash.defaultTo = defaultTo;
+    lodash.divide = divide;
+    lodash.endsWith = endsWith;
+    lodash.eq = eq;
+    lodash.escape = escape;
+    lodash.escapeRegExp = escapeRegExp;
+    lodash.every = every;
+    lodash.find = find;
+    lodash.findIndex = findIndex;
+    lodash.findKey = findKey;
+    lodash.findLast = findLast;
+    lodash.findLastIndex = findLastIndex;
+    lodash.findLastKey = findLastKey;
+    lodash.floor = floor;
+    lodash.forEach = forEach;
+    lodash.forEachRight = forEachRight;
+    lodash.forIn = forIn;
+    lodash.forInRight = forInRight;
+    lodash.forOwn = forOwn;
+    lodash.forOwnRight = forOwnRight;
+    lodash.get = get;
+    lodash.gt = gt;
+    lodash.gte = gte;
+    lodash.has = has;
+    lodash.hasIn = hasIn;
+    lodash.head = head;
+    lodash.identity = identity;
+    lodash.includes = includes;
+    lodash.indexOf = indexOf;
+    lodash.inRange = inRange;
+    lodash.invoke = invoke;
+    lodash.isArguments = isArguments;
+    lodash.isArray = isArray;
+    lodash.isArrayBuffer = isArrayBuffer;
+    lodash.isArrayLike = isArrayLike;
+    lodash.isArrayLikeObject = isArrayLikeObject;
+    lodash.isBoolean = isBoolean;
+    lodash.isBuffer = isBuffer;
+    lodash.isDate = isDate;
+    lodash.isElement = isElement;
+    lodash.isEmpty = isEmpty;
+    lodash.isEqual = isEqual;
+    lodash.isEqualWith = isEqualWith;
+    lodash.isError = isError;
+    lodash.isFinite = isFinite;
+    lodash.isFunction = isFunction;
+    lodash.isInteger = isInteger;
+    lodash.isLength = isLength;
+    lodash.isMap = isMap;
+    lodash.isMatch = isMatch;
+    lodash.isMatchWith = isMatchWith;
+    lodash.isNaN = isNaN;
+    lodash.isNative = isNative;
+    lodash.isNil = isNil;
+    lodash.isNull = isNull;
+    lodash.isNumber = isNumber;
+    lodash.isObject = isObject;
+    lodash.isObjectLike = isObjectLike;
+    lodash.isPlainObject = isPlainObject;
+    lodash.isRegExp = isRegExp;
+    lodash.isSafeInteger = isSafeInteger;
+    lodash.isSet = isSet;
+    lodash.isString = isString;
+    lodash.isSymbol = isSymbol;
+    lodash.isTypedArray = isTypedArray;
+    lodash.isUndefined = isUndefined;
+    lodash.isWeakMap = isWeakMap;
+    lodash.isWeakSet = isWeakSet;
+    lodash.join = join;
+    lodash.kebabCase = kebabCase;
+    lodash.last = last;
+    lodash.lastIndexOf = lastIndexOf;
+    lodash.lowerCase = lowerCase;
+    lodash.lowerFirst = lowerFirst;
+    lodash.lt = lt;
+    lodash.lte = lte;
+    lodash.max = max;
+    lodash.maxBy = maxBy;
+    lodash.mean = mean;
+    lodash.meanBy = meanBy;
+    lodash.min = min;
+    lodash.minBy = minBy;
+    lodash.stubArray = stubArray;
+    lodash.stubFalse = stubFalse;
+    lodash.stubObject = stubObject;
+    lodash.stubString = stubString;
+    lodash.stubTrue = stubTrue;
+    lodash.multiply = multiply;
+    lodash.nth = nth;
+    lodash.noConflict = noConflict;
+    lodash.noop = noop;
+    lodash.now = now;
+    lodash.pad = pad;
+    lodash.padEnd = padEnd;
+    lodash.padStart = padStart;
+    lodash.parseInt = parseInt;
+    lodash.random = random;
+    lodash.reduce = reduce;
+    lodash.reduceRight = reduceRight;
+    lodash.repeat = repeat;
+    lodash.replace = replace;
+    lodash.result = result;
+    lodash.round = round;
+    lodash.runInContext = runInContext;
+    lodash.sample = sample;
+    lodash.size = size;
+    lodash.snakeCase = snakeCase;
+    lodash.some = some;
+    lodash.sortedIndex = sortedIndex;
+    lodash.sortedIndexBy = sortedIndexBy;
+    lodash.sortedIndexOf = sortedIndexOf;
+    lodash.sortedLastIndex = sortedLastIndex;
+    lodash.sortedLastIndexBy = sortedLastIndexBy;
+    lodash.sortedLastIndexOf = sortedLastIndexOf;
+    lodash.startCase = startCase;
+    lodash.startsWith = startsWith;
+    lodash.subtract = subtract;
+    lodash.sum = sum;
+    lodash.sumBy = sumBy;
+    lodash.template = template;
+    lodash.times = times;
+    lodash.toFinite = toFinite;
+    lodash.toInteger = toInteger;
+    lodash.toLength = toLength;
+    lodash.toLower = toLower;
+    lodash.toNumber = toNumber;
+    lodash.toSafeInteger = toSafeInteger;
+    lodash.toString = toString;
+    lodash.toUpper = toUpper;
+    lodash.trim = trim;
+    lodash.trimEnd = trimEnd;
+    lodash.trimStart = trimStart;
+    lodash.truncate = truncate;
+    lodash.unescape = unescape;
+    lodash.uniqueId = uniqueId;
+    lodash.upperCase = upperCase;
+    lodash.upperFirst = upperFirst;
+
+    // Add aliases.
+    lodash.each = forEach;
+    lodash.eachRight = forEachRight;
+    lodash.first = head;
+
+    mixin(lodash, (function() {
+      var source = {};
+      baseForOwn(lodash, function(func, methodName) {
+        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
+          source[methodName] = func;
+        }
+      });
+      return source;
+    }()), { 'chain': false });
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * The semantic version number.
+     *
+     * @static
+     * @memberOf _
+     * @type {string}
+     */
+    lodash.VERSION = VERSION;
+
+    // Assign default placeholders.
+    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
+      lodash[methodName].placeholder = lodash;
+    });
+
+    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
+    arrayEach(['drop', 'take'], function(methodName, index) {
+      LazyWrapper.prototype[methodName] = function(n) {
+        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
+
+        var result = (this.__filtered__ && !index)
+          ? new LazyWrapper(this)
+          : this.clone();
+
+        if (result.__filtered__) {
+          result.__takeCount__ = nativeMin(n, result.__takeCount__);
+        } else {
+          result.__views__.push({
+            'size': nativeMin(n, MAX_ARRAY_LENGTH),
+            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
+          });
+        }
+        return result;
+      };
+
+      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
+        return this.reverse()[methodName](n).reverse();
+      };
+    });
+
+    // Add `LazyWrapper` methods that accept an `iteratee` value.
+    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
+      var type = index + 1,
+          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
+
+      LazyWrapper.prototype[methodName] = function(iteratee) {
+        var result = this.clone();
+        result.__iteratees__.push({
+          'iteratee': getIteratee(iteratee, 3),
+          'type': type
+        });
+        result.__filtered__ = result.__filtered__ || isFilter;
+        return result;
+      };
+    });
+
+    // Add `LazyWrapper` methods for `_.head` and `_.last`.
+    arrayEach(['head', 'last'], function(methodName, index) {
+      var takeName = 'take' + (index ? 'Right' : '');
+
+      LazyWrapper.prototype[methodName] = function() {
+        return this[takeName](1).value()[0];
+      };
+    });
+
+    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
+    arrayEach(['initial', 'tail'], function(methodName, index) {
+      var dropName = 'drop' + (index ? '' : 'Right');
+
+      LazyWrapper.prototype[methodName] = function() {
+        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
+      };
+    });
+
+    LazyWrapper.prototype.compact = function() {
+      return this.filter(identity);
+    };
+
+    LazyWrapper.prototype.find = function(predicate) {
+      return this.filter(predicate).head();
+    };
+
+    LazyWrapper.prototype.findLast = function(predicate) {
+      return this.reverse().find(predicate);
+    };
+
+    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
+      if (typeof path == 'function') {
+        return new LazyWrapper(this);
+      }
+      return this.map(function(value) {
+        return baseInvoke(value, path, args);
+      });
+    });
+
+    LazyWrapper.prototype.reject = function(predicate) {
+      return this.filter(negate(getIteratee(predicate)));
+    };
+
+    LazyWrapper.prototype.slice = function(start, end) {
+      start = toInteger(start);
+
+      var result = this;
+      if (result.__filtered__ && (start > 0 || end < 0)) {
+        return new LazyWrapper(result);
+      }
+      if (start < 0) {
+        result = result.takeRight(-start);
+      } else if (start) {
+        result = result.drop(start);
+      }
+      if (end !== undefined) {
+        end = toInteger(end);
+        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
+      }
+      return result;
+    };
+
+    LazyWrapper.prototype.takeRightWhile = function(predicate) {
+      return this.reverse().takeWhile(predicate).reverse();
+    };
+
+    LazyWrapper.prototype.toArray = function() {
+      return this.take(MAX_ARRAY_LENGTH);
+    };
+
+    // Add `LazyWrapper` methods to `lodash.prototype`.
+    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
+      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
+          isTaker = /^(?:head|last)$/.test(methodName),
+          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
+          retUnwrapped = isTaker || /^find/.test(methodName);
+
+      if (!lodashFunc) {
+        return;
+      }
+      lodash.prototype[methodName] = function() {
+        var value = this.__wrapped__,
+            args = isTaker ? [1] : arguments,
+            isLazy = value instanceof LazyWrapper,
+            iteratee = args[0],
+            useLazy = isLazy || isArray(value);
+
+        var interceptor = function(value) {
+          var result = lodashFunc.apply(lodash, arrayPush([value], args));
+          return (isTaker && chainAll) ? result[0] : result;
+        };
+
+        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
+          // Avoid lazy use if the iteratee has a "length" value other than `1`.
+          isLazy = useLazy = false;
+        }
+        var chainAll = this.__chain__,
+            isHybrid = !!this.__actions__.length,
+            isUnwrapped = retUnwrapped && !chainAll,
+            onlyLazy = isLazy && !isHybrid;
+
+        if (!retUnwrapped && useLazy) {
+          value = onlyLazy ? value : new LazyWrapper(this);
+          var result = func.apply(value, args);
+          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
+          return new LodashWrapper(result, chainAll);
+        }
+        if (isUnwrapped && onlyLazy) {
+          return func.apply(this, args);
+        }
+        result = this.thru(interceptor);
+        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
+      };
+    });
+
+    // Add `Array` methods to `lodash.prototype`.
+    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
+      var func = arrayProto[methodName],
+          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
+          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
+
+      lodash.prototype[methodName] = function() {
+        var args = arguments;
+        if (retUnwrapped && !this.__chain__) {
+          var value = this.value();
+          return func.apply(isArray(value) ? value : [], args);
+        }
+        return this[chainName](function(value) {
+          return func.apply(isArray(value) ? value : [], args);
+        });
+      };
+    });
+
+    // Map minified method names to their real names.
+    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
+      var lodashFunc = lodash[methodName];
+      if (lodashFunc) {
+        var key = (lodashFunc.name + ''),
+            names = realNames[key] || (realNames[key] = []);
+
+        names.push({ 'name': methodName, 'func': lodashFunc });
+      }
+    });
+
+    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
+      'name': 'wrapper',
+      'func': undefined
+    }];
+
+    // Add methods to `LazyWrapper`.
+    LazyWrapper.prototype.clone = lazyClone;
+    LazyWrapper.prototype.reverse = lazyReverse;
+    LazyWrapper.prototype.value = lazyValue;
+
+    // Add chain sequence methods to the `lodash` wrapper.
+    lodash.prototype.at = wrapperAt;
+    lodash.prototype.chain = wrapperChain;
+    lodash.prototype.commit = wrapperCommit;
+    lodash.prototype.next = wrapperNext;
+    lodash.prototype.plant = wrapperPlant;
+    lodash.prototype.reverse = wrapperReverse;
+    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
+
+    // Add lazy aliases.
+    lodash.prototype.first = lodash.prototype.head;
+
+    if (symIterator) {
+      lodash.prototype[symIterator] = wrapperToIterator;
+    }
+    return lodash;
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  // Export lodash.
+  var _ = runInContext();
+
+  // Some AMD build optimizers, like r.js, check for condition patterns like:
+  if (true) {
+    // Expose Lodash on the global object to prevent errors when Lodash is
+    // loaded by a script tag in the presence of an AMD loader.
+    // See http://requirejs.org/docs/errors.html#mismatch for more details.
+    // Use `_.noConflict` to remove Lodash from the global object.
+    root._ = _;
+
+    // Define as an anonymous module so, through path mapping, it can be
+    // referenced as the "underscore" module.
+    !(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
+      return _;
+    }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+  }
+  // Check for `exports` after `define` in case a build optimizer adds it.
+  else if (freeModule) {
+    // Export for Node.js.
+    (freeModule.exports = _)._ = _;
+    // Export for CommonJS support.
+    freeExports._ = _;
+  }
+  else {
+    // Export to the global object.
+    root._ = _;
+  }
+}.call(this));
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(14), __webpack_require__(15)(module)))
+
+/***/ },
+/* 14 */
+/***/ function(module, exports) {
+
+var g;
+
+// This works in non-strict mode
+g = (function() { return this; })();
+
+try {
+	// This works if eval is allowed (see CSP)
+	g = g || Function("return this")() || (1,eval)("this");
+} catch(e) {
+	// This works if the window reference is available
+	if(typeof window === "object")
+		g = window;
+}
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+module.exports = g;
+
+
+/***/ },
+/* 15 */
+/***/ function(module, exports) {
+
+module.exports = function(module) {
+	if(!module.webpackPolyfill) {
+		module.deprecate = function() {};
+		module.paths = [];
+		// module.parent = undefined by default
+		if(!module.children) module.children = [];
+		Object.defineProperty(module, "loaded", {
+			enumerable: true,
+			configurable: false,
+			get: function() { return module.l; }
+		});
+		Object.defineProperty(module, "id", {
+			enumerable: true,
+			configurable: false,
+			get: function() { return module.i; }
+		});
+		module.webpackPolyfill = 1;
+	}
+	return module;
+}
+
+
+/***/ },
+/* 16 */
+/***/ function(module, exports, __webpack_require__) {
+
+"use strict";
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+"use strict";
+exports.__esModule = true;
+/// <reference path="../typings/index.d.ts" />
+var angular = __webpack_require__(0);
+__webpack_require__(3);
+__webpack_require__(2);
+__webpack_require__(1);
+__webpack_require__(7);
+var routes_1 = __webpack_require__(6);
+var engMap_component_1 = __webpack_require__(5);
+var eline_side_component_1 = __webpack_require__(4);
+angular.module('vnaasgui', [
+    'ui.router',
+    'app',
+    'ngMap'
+])
+    .config(routes_1["default"])
+    .component('engMap', engMap_component_1.engMap)
+    .component('elineSide', eline_side_component_1.elineSide)
+    .run(["$log", "$state", "XosNavigationService", "XosComponentInjector", function ($log, $state, XosNavigationService, XosComponentInjector) {
+    $log.info('[vnaasgui] App is running');
+    XosNavigationService.add({
+        label: 'vNaaS GUI',
+        state: 'xos.vnaasgui'
+    });
+}]);
+
+
+/***/ }
+/******/ ]);
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/xos/gui/.tmp/index.js.map b/xos/gui/.tmp/index.js.map
new file mode 100755
index 0000000..db57b97
--- /dev/null
+++ b/xos/gui/.tmp/index.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///webpack/bootstrap d343910db03588c47a4b","webpack:///./~/angular/index.js","webpack:///./~/angular-cookies/index.js","webpack:///./~/angular-resource/index.js","webpack:///./~/angular-ui-router/release/angular-ui-router.js","webpack:///./src/app/components/eline-side.component.ts?6cfa","webpack:///./src/app/components/eline-side.component.ts","webpack:///./src/app/components/engMap.component.ts?2f5c","webpack:///./src/app/components/engMap.component.ts","webpack:///./src/routes.ts?c833","webpack:///./src/routes.ts","webpack:///./~/ngmap/build/scripts/ng-map.js","webpack:///./~/angular-cookies/angular-cookies.js","webpack:///./~/angular-resource/angular-resource.js","webpack:///./~/angular/angular.js","webpack:///./src/app/components/eline-side.component.html","webpack:///./src/app/components/engMap.component.html","webpack:///./~/lodash/lodash.js","webpack:///(webpack)/buildin/global.js","webpack:///(webpack)/buildin/module.js","webpack:///./src/index.ts?fe78","webpack:///./src/index.ts"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA,mDAA2C,cAAc;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA,YAAI;AACJ;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;AC9DA;AACA;;;;;;;ACDA;AACA;;;;;;;ACDA;AACA;;;;;;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,cAAc;AAC7D;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,UAAU;AAC5C,6BAA6B,kBAAkB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,6BAA6B;AAC3D,4CAA4C,yCAAyC,EAAE;AACvF,mCAAmC,2CAA2C,EAAE;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,EAAE,GAAG,oBAAoB;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,mCAAmC,eAAe;AAClD,qCAAqC,aAAa;AAClD;AACA;AACA,0BAA0B,SAAS;AACnC;AACA;AACA;AACA,0CAA0C,kCAAkC;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,WAAW;AACtC;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA,yCAAyC;AACzC,6BAA6B,2BAA2B;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,MAAM;AACN;AACA;AACA;AACA;AACA,yCAAyC,mCAAmC;AAC5E;AACA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,YAAY,MAAM;AAClB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,2BAA2B,uBAAuB;AAClD,oBAAoB,iBAAiB;AACrC;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gFAAgF;AACrG;AACA;AACA,qBAAqB,2FAA2F;AAChH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,uBAAuB,EAAE,sBAAsB,wBAAwB;AAC7G;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,sCAAsC,EAAE;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,2BAA2B;AAC3B;AACA;AACA,kCAAkC,6CAA6C,iBAAiB,EAAE,EAAE;AACpG;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,gCAAgC;AAChC;AACA;AACA,gCAAgC;AAChC;AACA;AACA,2CAA2C,qBAAqB;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA,gCAAgC;AAChC;AACA;AACA,2CAA2C,qBAAqB;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wGAAwG;AACnJ;AACA,2BAA2B,eAAe,YAAY;AACtD;AACA;AACA,wCAAwC,8DAA8D;AACtG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,wCAAwC;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,yCAAyC;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA,mEAAmE;AACnE;AACA;AACA;AACA,6BAA6B,2BAA2B;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,wBAAwB;AACnC;AACA;AACA,oCAAoC,gDAAgD,2BAA2B,EAAE,EAAE;AACnH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,+BAA+B;AAC/B;AACA;AACA;AACA;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA,wDAAwD,kCAAkC,EAAE,oBAAoB;AAChH,0EAA0E,sCAAsC,iBAAiB,EAAE,EAAE,EAAE;AACvI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E;AAC5E,sBAAsB;AACtB;AACA;AACA,gDAAgD;AAChD,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,yBAAyB,EAAE;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,0BAA0B,EAAE;AAC1E;AACA,gCAAgC,2CAA2C,4BAA4B,EAAE,EAAE,WAAW;AACtH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,4DAA4D,uBAAuB,EAAE;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,iCAAiC,EAAE;AAC3F;AACA;AACA;AACA,wCAAwC,UAAU,EAAE;AACpD;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,yBAAyB,sBAAsB,yBAAyB,GAAG;AAC3E;AACA;AACA,gCAAgC,mBAAmB;AACnD;AACA;AACA;AACA,kCAAkC,4CAA4C;AAC9E;AACA,iCAAiC,0CAA0C,EAAE;AAC7E,mCAAmC,4CAA4C,EAAE;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,iCAAiC,wBAAwB,yBAAyB,GAAG;AACrF;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,mDAAmD,iCAAiC,EAAE;AACtF;AACA;AACA,eAAe,oBAAoB,wBAAwB;AAC3D;AACA;AACA;AACA;AACA;AACA,kCAAkC,4DAA4D;AAC9F;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,wBAAwB,oCAAoC,sBAAsB,EAAE,QAAQ,GAAG;AAC9H,+BAA+B,wBAAwB,oCAAoC,sBAAsB,EAAE,SAAS,GAAG;AAC/H;AACA;AACA,+BAA+B,wBAAwB,yEAAyE,GAAG;AACnI;AACA,8BAA8B,0BAA0B,sBAAsB,GAAG;AACjF;AACA,6BAA6B,qBAAqB,UAAU,GAAG;AAC/D;AACA,4BAA4B,qCAAqC;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,MAAM;AAC/E;AACA;AACA,yDAAyD,MAAM;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C,mCAAmC;AACnC,sCAAsC;AACtC;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,UAAU;AACrB,WAAW,iBAAiB;AAC5B,yCAAyC;AACzC;AACA,GAAG;AACH;AACA;AACA;AACA,iBAAiB;AACjB,uBAAuB;AACvB;AACA;AACA;AACA;AACA,8BAA8B,qDAAqD,EAAE;AACrF;AACA,8BAA8B,2DAA2D,EAAE;;;AAG3F,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,OAAO;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,iCAAiC,eAAe;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,yBAAyB,EAAE;AACxE,6CAA6C,+BAA+B,EAAE,EAAE;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,0CAA0C,EAAE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,oBAAoB,EAAE;AACzE;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;;AAGH,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,gDAAgD;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,8FAA8F;AACxI;AACA;AACA;AACA;AACA,iEAAiE,6BAA6B;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,mBAAmB;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,2BAA2B;AACpE,sCAAsC,2CAA2C;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,2BAA2B;AACrE;AACA;AACA;AACA,8EAA8E,mBAAmB,EAAE;AACnG;AACA;AACA,yEAAyE,eAAe,EAAE;AAC1F,kEAAkE,cAAc,EAAE;AAClF,sEAAsE,cAAc,EAAE;AACtF,sEAAsE,uBAAuB,EAAE;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA,kFAAkF,UAAU;AAC5F;AACA;AACA,iFAAiF,UAAU;AAC3F;AACA;AACA,gFAAgF,UAAU;AAC1F;AACA;AACA,kFAAkF,UAAU;AAC5F;AACA;AACA,iFAAiF,UAAU;AAC3F;AACA;AACA,kFAAkF,UAAU;AAC5F;AACA;AACA,mFAAmF,UAAU;AAC7F;AACA;AACA,iFAAiF,UAAU;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,qDAAqD;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,iBAAiB;AACpD,qGAAqG;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E,0DAA0D,EAAE;AACzI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0EAA0E,iBAAiB;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,YAAY;AAC5C;AACA;AACA,iEAAiE,sCAAsC,EAAE;AACzG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,uBAAuB;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,0CAA0C,iBAAiB;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,yBAAyB,EAAE;AAC9E,kDAAkD,+BAA+B,sBAAsB,EAAE,EAAE,EAAE;AAC7G;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,kBAAkB,EAAE;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,UAAU,EAAE,EAAE;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,8BAA8B,EAAE;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gPAAgP;AAChP;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,MAAM,sBAAsB;AACxC,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,4CAA4C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,+BAA+B,EAAE;AACxE,sCAAsC,sBAAsB,EAAE;AAC9D;AACA,oEAAoE,2CAA2C,EAAE;AACjH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,YAAY;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,MAAM;AAClB;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,6DAA6D;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,kFAAkF,EAAE;AAClI;AACA,4CAA4C,iFAAiF,EAAE;AAC/H;AACA,sEAAsE,iEAAiE,EAAE;AACzI;AACA,0DAA0D,yDAAyD,EAAE;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,2BAA2B;AACvE;AACA,wBAAwB,kBAAkB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oGAAoG;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,uCAAuC,EAAE;AACzF;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,YAAY;AACxB;AACA,YAAY,OAAO;AACnB,YAAY,cAAc;AAC1B,YAAY,kBAAkB;AAC9B;AACA;AACA;AACA,kCAAkC,cAAc;AAChD,mCAAmC,eAAe;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,wBAAwB,wBAAwB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD;AACA,+CAA+C,sEAAsE;AACrH;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,0CAA0C,EAAE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,sBAAsB,EAAE;AAC3D;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,sCAAsC;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4FAA4F,kCAAkC,EAAE;AAChI;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,8DAA8D,eAAe,EAAE;AAC7H,6CAA6C,4DAA4D;AACzG,4CAA4C,qEAAqE,kBAAkB,EAAE;AACrI,8CAA8C,yEAAyE,kBAAkB,EAAE;AAC3I,6CAA6C,wEAAwE,kBAAkB,EAAE;AACzI,8CAA8C,6DAA6D;AAC3G,+CAA+C,+DAA+D,0CAA0C,EAAE;AAC1J,6CAA6C,6DAA6D,0CAA0C,EAAE;AACtJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,8BAA8B,oCAAoC,EAAE;AACrH;AACA;AACA;AACA,yBAAyB;AACzB,cAAc;AACd;AACA;AACA;AACA;AACA,oCAAoC,6BAA6B,EAAE;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,+BAA+B,EAAE;AACnE;AACA;AACA,sCAAsC,kCAAkC,EAAE,EAAE;AAC5E;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,sDAAsD,gBAAgB,EAAE,GAAG,EAAE;AACrI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,yBAAyB,EAAE;AACnF;AACA,mCAAmC,0BAA0B,EAAE;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kGAAkG,6BAA6B,EAAE;AACjI;AACA;AACA;AACA;AACA,qEAAqE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,gBAAgB,EAAE;AACvE,kEAAkE,qCAAqC,EAAE;AACzG;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,+BAA+B,eAAe;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C,yCAAyC,UAAU,+BAA+B,EAAE,EAAE,EAAE;AACxF;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,uDAAuD,EAAE;AACpH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF,mBAAmB,EAAE;AACxG;AACA,2CAA2C,qCAAqC,EAAE;AAClF,qCAAqC,2BAA2B,EAAE,EAAE;AACpE;AACA,sEAAsE,0BAA0B,EAAE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE,qBAAqB,EAAE;AAC3F;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;;;AAGF,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,eAAe,EAAE;AAC1E;AACA;AACA;AACA;AACA,mGAAmG,UAAU;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0HAA0H;AAC1H;AACA;AACA;AACA,gEAAgE,4DAA4D,EAAE;AAC9H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,6CAA6C,EAAE;AACrF,mEAAmE;AACnE,mEAAmE,mBAAmB,EAAE;AACxF,8DAA8D,8CAA8C,EAAE;AAC9G;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,0BAA0B,iBAAiB,iEAAiE;AAC1J,mDAAmD,uDAAuD;AAC1G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,0CAA0C,+CAA+C,EAAE,IAAI,EAAE;AACjJ;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA,kDAAkD,iBAAiB;AACnE;AACA,sEAAsE,oBAAoB,EAAE;AAC5F;AACA;AACA;AACA;AACA,gDAAgD,2DAA2D;AAC3G,2EAA2E,qDAAqD,EAAE,IAAI;AACtI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,+CAA+C;AAC9E,2CAA2C,wFAAwF;AACnI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sCAAsC;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,oFAAoF,gBAAgB;AACvI;AACA;AACA;AACA;AACA,EAAE,0CAA0C;AAC5C;AACA;AACA,gCAAgC,aAAa;AAC7C;AACA,+EAA+E,kBAAkB;AACjG,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,2DAA2D;AACrE,UAAU;AACV;AACA;AACA;AACA,uBAAuB,8BAA8B;AACrD;AACA,4DAA4D,iDAAiD,EAAE;AAC/G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC,+DAA+D,cAAc;AAC7E;AACA;AACA,gCAAgC,uJAAuJ;AACvL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,wGAAwG;AAC1H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,6CAA6C,kDAAkD,EAAE,gCAAgC;AACjI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD,kCAAkC,cAAc;AAChD,gDAAgD,iEAAiE,EAAE;AACnH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,6CAA6C,0CAA0C,EAAE;AACzF;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA,wCAAwC;AACxC;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,qFAAqF;AACnH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qFAAqF,WAAW,EAAE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,iBAAiB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,0BAA0B,EAAE;AACzD,6BAA6B,8BAA8B,EAAE;AAC7D,8BAA8B,8BAA8B,EAAE;AAC9D,yBAAyB,gEAAgE,EAAE;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA,uDAAuD,YAAY;AACnE;AACA,uDAAuD,YAAY;AACnE;AACA,mDAAmD,eAAe;AAClE;AACA;AACA;AACA;AACA;AACA,kBAAkB,4BAA4B;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,iBAAiB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,qFAAqF;AACjH,8BAA8B,oFAAoF;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,eAAe,EAAE;AAC3D,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,yCAAyC,0BAA0B,EAAE;AACrE,qCAAqC,2EAA2E,EAAE;AAClH;AACA,cAAc;AACd;AACA,yCAAyC,sBAAsB,EAAE;AACjE,yCAAyC,gCAAgC,EAAE;AAC3E;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,qCAAqC,qDAAqD,EAAE;AAC5F;AACA;AACA,qDAAqD,mCAAmC,EAAE;AAC1F,kBAAkB;AAClB,iCAAiC,EAAE;AACnC,kCAAkC,EAAE;AACpC,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,8CAA8C,aAAa,eAAe;AAC/H,oFAAoF;AACpF;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,aAAa;AAC/E;AACA,kCAAkC,gCAAgC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,4DAA4D;AAC5F;AACA;AACA;AACA;AACA,qEAAqE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iFAAiF;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,sCAAsC;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gFAAgF,MAAM;AACtF;AACA;AACA;AACA,iBAAiB,mBAAmB;AACpC;AACA;AACA;AACA,gFAAgF,UAAU;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,GAAG;AAClB,eAAe,SAAS;AACxB,eAAe,eAAe,KAAK;AACnC;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,gBAAgB,oBAAoB;AACpC;AACA;AACA;AACA,iBAAiB,8BAA8B;AAC/C;AACA,mBAAmB;AACnB;AACA,iBAAiB,OAAO,YAAY;AACpC,gDAAgD,2BAA2B,WAAW,OAAO,YAAY,OAAO,+CAA+C,6BAA6B,WAAW,OAAO,YAAY,OAAO;AACjO;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,yCAAyC,EAAE;AACpG;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,gEAAgE,EAAE;AAC7H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,GAAG;AAClC;AACA,SAAS;AACT,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,wCAAwC,iBAAiB;AACzD,4FAA4F,0BAA0B,EAAE,qDAAqD,yBAAyB,EAAE,sEAAsE,kCAAkC,EAAE,0BAA0B,cAAc,EAAE;AAC5V;AACA;AACA;AACA,iDAAiD,yCAAyC;AAC1F,iDAAiD,iCAAiC;AAClF;AACA;AACA;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA,4BAA4B,0BAA0B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,0BAA0B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,cAAc;AAChC;AACA;AACA;AACA,+BAA+B,WAAW;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,+BAA+B,WAAW;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,uCAAuC;AAC3F,2CAA2C;AAC3C;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,GAAG,aAAa,oBAAoB;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,+DAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,+BAA+B,EAAE;AACjF,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,oEAAoE,8DAA8D,EAAE;AACpI;AACA;AACA;AACA;AACA,+DAA+D,4CAA4C,EAAE;AAC7G,qIAAqI,8CAA8C,EAAE;AACrL;AACA;AACA;AACA,qDAAqD,8CAA8C,EAAE;AACrG;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA,sCAAsC,IAAI;AAC1C;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,sDAAsD,4CAA4C;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,uEAAuE,aAAa,EAAE;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,8DAA8D,sCAAsC,EAAE;AACtG;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oFAAoF,wFAAwF,EAAE;AAC9K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,qBAAqB,OAAO;AAC5B;AACA,oBAAoB,OAAO,eAAe;AAC1C;AACA,0BAA0B,OAAO;AACjC;AACA,uBAAuB,OAAO;AAC9B;AACA,sBAAsB,OAAO;AAC7B;AACA;AACA;AACA;AACA;AACA,0BAA0B,OAAO;AACjC;AACA,qBAAqB,OAAO;AAC5B;AACA,yBAAyB,OAAO;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,SAAS;AACT;AACA;AACA;AACA,6BAA6B,+BAA+B;AAC5D,6BAA6B;AAC7B;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB;AACA;AACA,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,iBAAiB;AAC7C;AACA;AACA;AACA;AACA;AACA,aAAa,UAAU,WAAW;AAClC;AACA;AACA;AACA;AACA,+BAA+B,iBAAiB;AAChD;AACA;AACA;AACA;AACA,aAAa,UAAU,WAAW;AAClC;AACA;AACA;AACA;AACA,oCAAoC,UAAU;AAC9C;AACA;AACA;AACA;AACA,8BAA8B,iBAAiB;AAC/C;AACA;AACA;AACA;AACA,sCAAsC,UAAU;AAChD;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA,2BAA2B,WAAW,oBAAoB,EAAE;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,uBAAuB,gBAAgB;AACvC;AACA;AACA;AACA;AACA;AACA,uBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA,0BAA0B,QAAQ;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;AACjC;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA,wHAAwH;AACxH;AACA;AACA;AACA,0BAA0B,QAAQ;AAClC;AACA,wHAAwH;AACxH;AACA;AACA;AACA,yCAAyC,SAAS;AAClD;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA,gEAAgE;AAChE;AACA;AACA;AACA,2BAA2B;AAC3B,4BAA4B;AAC5B,+BAA+B;AAC/B;AACA;AACA,gBAAgB,OAAO;AACvB;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB;AACA,gDAAgD,YAAY;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,2BAA2B,aAAa;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,uBAAuB,2BAA2B,EAAE,EAAE;AAC9F;AACA,mCAAmC,4BAA4B,uBAAuB,EAAE,EAAE;AAC1F,uCAAuC,6BAA6B,yBAAyB,EAAE,EAAE;AACjG,qCAAqC,6BAA6B,wBAAwB,EAAE,EAAE;AAC9F;AACA,2CAA2C,+BAA+B,iBAAiB;AAC3F,yCAAyC,4BAA4B,+BAA+B,iBAAiB;AACrH;AACA,wCAAwC;AACxC,8CAA8C;AAC9C;AACA,0CAA0C,oBAAoB,iBAAiB;AAC/E;AACA;AACA,yFAAyF,UAAU;AACnG;AACA;AACA,wFAAwF,UAAU;AAClG;AACA;AACA,uFAAuF,UAAU;AACjG;AACA;AACA,yFAAyF,UAAU;AACnG;AACA;AACA,wFAAwF,UAAU;AAClG;AACA;AACA,yFAAyF,UAAU;AACnG;AACA;AACA,0FAA0F,UAAU;AACpG;AACA;AACA,wFAAwF,UAAU;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,oBAAoB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,uBAAuB,oBAAoB;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,qBAAqB;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E,oBAAoB,EAAE;AACpG;AACA;AACA;AACA;AACA;AACA,oDAAoD,iBAAiB;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,uCAAuC,EAAE;AAClF,0CAA0C,qCAAqC,EAAE;AACjF;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,oDAAoD,aAAa;AACjE;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,oCAAoC,gBAAgB;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,qCAAqC,cAAc;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,wCAAwC,gBAAgB;AAC1G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,uCAAuC,eAAe;AACvG;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,uBAAuB;AAC5C;AACA;AACA,6BAA6B,0CAA0C,wCAAwC,EAAE,QAAQ;AACzH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,uBAAuB,EAAE,gCAAgC;AAC3H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,qDAAqD,WAAW,EAAE;AACpF,kBAAkB,qDAAqD,YAAY,EAAE;AACrF,kBAAkB,qDAAqD,cAAc;AACrF,kBAAkB,qDAAqD,gBAAgB;AACvF;AACA;AACA;AACA;AACA,gCAAgC;AAChC,gCAAgC;AAChC,gCAAgC;AAChC,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qFAAqF,kDAAkD,EAAE;AACzI;AACA;AACA;AACA,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,SAAS;AACzB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,0CAA0C,+BAA+B;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,kBAAkB;AACxD;AACA;AACA;AACA;AACA,yDAAyD;AACzD,oGAAoG;AACpG;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D,mDAAmD;AACnD;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA,uFAAuF,sBAAsB,EAAE;AAC/G;AACA;AACA,iBAAiB;AACjB;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,gCAAgC,EAAE;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,uCAAuC,cAAc;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA,oEAAoE,GAAG,gBAAgB;AACvF;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,mDAAmD;AACrG,yDAAyD,iBAAiB;AAC1E,qFAAqF;AACrF,6DAA6D,kBAAkB,EAAE,gCAAgC;AACjH;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,oBAAoB,EAAE;AACtD;AACA;AACA,8CAA8C,kDAAkD;AAChG;AACA,qBAAqB;AACrB,uDAAuD,uCAAuC;AAC9F;AACA,qBAAqB;AACrB,qDAAqD,sCAAsC;AAC3F;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,qBAAqB;AACtE,oDAAoD,uCAAuC;AAC3F,OAAO,qDAAqD,gCAAgC;AAC5F;AACA;AACA;AACA,8BAA8B;AAC9B,sCAAsC,6BAA6B,wBAAwB,UAAU,iDAAiD,EAAE,EAAE,EAAE;AAC5J;AACA,mCAAmC,iHAAiH;AACpJ;AACA,4CAA4C,uCAAuC;AACnF;AACA,6CAA6C,8GAA8G;AAC3J;AACA,0CAA0C,oIAAoI;AAC9K;AACA,+BAA+B,6BAA6B;AAC5D;AACA;AACA,iDAAiD,6EAA6E,EAAE;AAChI,kDAAkD,kGAAkG,EAAE;AACtJ,gDAAgD,2DAA2D,yBAAyB,EAAE,gBAAgB,EAAE;AACxJ,gDAAgD,2DAA2D,mBAAmB,EAAE,4BAA4B,EAAE;AAC9J,mDAAmD,4DAA4D,UAAU,EAAE,6BAA6B,EAAE;AAC1J;AACA;AACA,kFAAkF,+DAA+D,UAAU,EAAE,6BAA6B,EAAE;AAC5L,iFAAiF,iHAAiH,EAAE;AACpM,oFAAoF,+FAA+F,EAAE;AACrL;AACA;AACA,2DAA2D,UAAU,EAAE;AACvE;AACA;AACA;AACA,6CAA6C,yEAAyE,EAAE;AACxH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,yBAAyB;AAC1D,wCAAwC,0BAA0B;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,qEAAqE;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,2BAA2B,+BAA+B,GAAG,EAAE;AACxI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,WAAW,MAAM;AAC/D,mFAAmF;AACnF;AACA;AACA,oCAAoC,oBAAoB;AACxD,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,WAAW;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,iCAAiC;AAC1F;AACA,cAAc;AACd;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,MAAM;AACxB;AACA;AACA;AACA;AACA;AACA,yCAAyC,gBAAgB;AACzD;AACA;AACA;AACA;AACA,+BAA+B,WAAW;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF,oCAAoC,EAAE;AACzH;AACA;AACA;AACA,2BAA2B,uCAAuC,EAAE;AACpE;AACA;AACA,MAAM;AACN;AACA,2BAA2B,mCAAmC,EAAE;AAChE;AACA;AACA,MAAM;AACN;AACA,2BAA2B,oCAAoC,EAAE;AACjE;AACA;AACA,MAAM;AACN;AACA,2BAA2B,qCAAqC,EAAE;AAClE;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,6CAA6C;AACrF;AACA;AACA;AACA;AACA,mDAAmD,kDAAkD,6BAA6B,GAAG;AACrI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gGAAgG,uCAAuC,EAAE;AACzI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,gBAAgB,gBAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,kBAAkB,QAAQ;AAC1B,SAAS,kDAAkD;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,yEAAyE;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA,4BAA4B,qBAAqB;AACjD;AACA,2BAA2B,aAAa;AACxC,4BAA4B,uBAAuB;AACnD;AACA,0BAA0B,aAAa;AACvC,mCAAmC,cAAc;AACjD;AACA;AACA;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,QAAQ;AACxB;AACA,gBAAgB,QAAQ;AACxB;AACA,4BAA4B,qBAAqB;AACjD;AACA,2BAA2B,cAAc;AACzC,4BAA4B,QAAQ;AACpC;AACA,0BAA0B,aAAa;AACvC,mCAAmC,cAAc;AACjD;AACA;AACA;AACA,kBAAkB,QAAQ;AAC1B,SAAS,kDAAkD;AAC3D;AACA;AACA;AACA,mCAAmC,eAAe;AAClD,kCAAkC,cAAc;AAChD;AACA;AACA;AACA;AACA,6CAA6C,oDAAoD;AACjG;AACA;AACA,qCAAqC,iEAAiE;AACtG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,gEAAgE;AAChE;AACA,sDAAsD,yBAAyB;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,8DAA8D;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C,gDAAgD;AAChD;AACA;AACA;AACA,wBAAwB,gCAAgC;AACxD;AACA;AACA,gBAAgB,cAAc;AAC9B,gBAAgB,QAAQ,+BAA+B,sBAAsB;AAC7E;AACA,gBAAgB,QAAQ;AACxB;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA,+CAA+C,0BAA0B;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC,4CAA4C;AAC5C,iDAAiD;AACjD,yCAAyC;AACzC,iCAAiC;AACjC;AACA;AACA;AACA,wBAAwB,sCAAsC;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC,wCAAwC;AACxC,sCAAsC;AACtC,8CAA8C;AAC9C,2CAA2C;AAC3C,uCAAuC;AACvC,mCAAmC;AACnC;AACA;AACA,gBAAgB,OAAO;AACvB;AACA,gBAAgB,QAAQ,+BAA+B,sBAAsB;AAC7E;AACA,gBAAgB,QAAQ;AACxB;AACA,4BAA4B,eAAe;AAC3C;AACA;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA,+CAA+C,0BAA0B;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,gBAAgB;AAC5D;AACA;AACA,gBAAgB,cAAc;AAC9B,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB;AACA,yBAAyB,aAAa;AACtC;AACA;AACA,2BAA2B,aAAa;AACxC,4BAA4B,uBAAuB;AACnD;AACA,4BAA4B,cAAc;AAC1C;AACA,kBAAkB,OAAO;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,sBAAsB,kBAAkB;AAC9E,uDAAuD;AACvD,yCAAyC;AACzC;AACA;AACA,sCAAsC;AACtC;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB;AACA;AACA,sFAAsF;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gBAAgB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gBAAgB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gBAAgB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA,4CAA4C,WAAW,EAAE;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,oDAAoD;AACjF;AACA;AACA;AACA;AACA;AACA,kEAAkE,4CAA4C,gBAAgB,EAAE,EAAE,EAAE;AACpI;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,kCAAkC,sBAAsB,EAAE;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E,EAAE;AAChF;AACA,sGAAsG,iCAAiC,EAAE;AACzI,4FAA4F,EAAE;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E,EAAE;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,EAAE;AACvE;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,qDAAqD,iCAAiC;AACtF;AACA;AACA;AACA;AACA,2FAA2F,gDAAgD,EAAE;AAC7I;AACA,2DAA2D,2BAA2B,EAAE;AACxF;AACA;AACA;AACA,4DAA4D,sBAAsB,EAAE;AACpF;AACA;AACA,oCAAoC,oCAAoC,EAAE;AAC1E;AACA;AACA;AACA;AACA;AACA,6CAA6C,2CAA2C,EAAE;AAC1F,iDAAiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ,YAAY;AACZ;AACA;AACA,2FAA2F;AAC3F;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,uEAAuE,WAAW,mBAAmB;AACrG,iEAAiE,WAAW,mBAAmB;AAC/F;AACA,mEAAmE,sBAAsB;AACzF;AACA,8CAA8C,2CAA2C,kDAAkD,qBAAqB,cAAc,GAAG,EAAE,GAAG,EAAE;AACxL;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,sCAAsC,EAAE,EAAE;AAC7G;AACA,kEAAkE;AAClE;AACA;AACA;AACA,uCAAuC,iBAAiB;;;AAGxD,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,sCAAsC;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA,mBAAmB,gCAAgC;AACnD;AACA,gCAAgC,MAAM,cAAc;AACpD;AACA,gCAAgC;AAChC;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA,iDAAiD,4CAA4C,EAAE;AAC/F;AACA;AACA;AACA;AACA,sDAAsD,uDAAuD;AAC7G;AACA;AACA;AACA;AACA;AACA,oDAAoD,4CAA4C;AAChG;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,0CAA0C;AAC1C,0EAA0E,gBAAgB;AAC1F,6CAA6C,qCAAqC;AAClF,0BAA0B,yDAAyD,EAAE;AACrF,+BAA+B,0EAA0E,EAAE;AAC3G,4BAA4B,UAAU,mDAAmD,EAAE,EAAE,EAAE,GAAG,KAAK;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,+CAA+C,EAAE,IAAI;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,4BAA4B;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,gBAAgB;AAChC;AACA,gBAAgB,OAAO;AACvB,iBAAiB,wBAAwB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,iBAAiB,wBAAwB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0FAA0F,iBAAiB;AAC3G;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,GAAG,GAAG;AAC5C;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E,QAAQ;AACrF;AACA;AACA;AACA,yCAAyC,iBAAiB,KAAK,gBAAgB;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mIAAmI,QAAQ;AAC3I;AACA;AACA;AACA,6DAA6D,iBAAiB;AAC9E;AACA;AACA,6DAA6D,iBAAiB;AAC9E;AACA;AACA,6DAA6D,iBAAiB;AAC9E;AACA;AACA;AACA,qCAAqC,aAAa;AAClD;AACA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA,kIAAkI;AAClI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE;AACjE,qCAAqC,EAAE;AACvC;AACA;AACA;AACA;AACA;AACA,+FAA+F,YAAY,EAAE;AAC7G;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,iBAAiB;AACrD;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,sBAAsB,EAAE;AACrF,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,YAAY,EAAE;AAC7G;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,qBAAqB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,qBAAqB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,oBAAoB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,oBAAoB,2CAA2C,EAAE;AACpI;AACA;AACA;AACA;AACA,8CAA8C,kBAAkB;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,OAAO;AACvC,gCAAgC,cAAc;AAC9C,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,mBAAmB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,uBAAuB,wBAAwB,EAAE,EAAE;AAC1G,0DAA0D,2BAA2B;AACrF,uDAAuD,4CAA4C;AACnG,yDAAyD,sCAAsC;AAC/F;AACA,kBAAkB;AAClB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,+DAA+D;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,wFAAwF;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA,YAAY,QAAQ;AACpB;AACA,cAAc,oCAAoC;AAClD;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,+FAA+F;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,gCAAgC;AACrE;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,YAAY,gCAAgC,EAAE;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,wBAAwB;AACvE;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,aAAa;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wFAAwF,WAAW,oCAAoC;AACvI;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,oCAAoC;AACvG,iGAAiG,oCAAoC;AACrI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,qEAAqE,EAAE;AAC3H;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E,yBAAyB,EAAE;AAC1G,mFAAmF,yBAAyB,EAAE;AAC9G;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,uEAAuE,aAAa,EAAE;AACtF;AACA,qGAAqG,0CAA0C,EAAE;AACjJ;AACA;AACA,yDAAyD;AACzD;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;;;AAGA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,oCAAoC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,8GAA8G;AACtJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,UAAU;AACV;AACA;;;AAGA;AACA;AACA,CAAC;AACD;AACA,6C;;;;;;;ACpzPA;;;;;;;;;;;;;;;ACcA;AACA,QAAQ,aAAa;ADErB,IAAI;AAEJ;IAIE,mBACU,cACA,eACA,OACA,MACA,QAAW;QAJX;QACA;QACA;QACA;QACA;QAER,OAAO;;IAGF,gCAAP,UAAiB,MAAS;QAA1B;QACE,IAAI,OAAO,KAAK;QAChB,OAAO,KAAK;QACZ,KAAK,QAAQ,KAAK,UAAC,KAAG;YACpB,KAAK,OAAO;YACZ,MAAK,OAAO,QAAW,KAAK,OAAI;WAE/B,SAAM,UAAC,OAAK;YACX,MAAK,OAAO,MAAM,wBAAsB,KAAK,OAAI,OAAK,MAAM;;;IAI3D,kCAAP,UAAmB,MAAS;QAA5B;QACE,IAAI,OAAO,KAAK;QAChB,KAAK,UAAU,KAAK,UAAC,KAAG;YACtB,MAAK,OAAO,QAAW,OAAI;WAE5B,SAAM,UAAC,OAAK;YACT,MAAK,OAAO,MAAM,0BAAwB,OAAI,OAAK,MAAM;;;IAKjE;;AAnCS,oBAAU,CAAC,gBAAgB,iBAAiB,SAAS,QAAQ;AAqCzD,oBAAuC;IAClD,UAAU,oBAAQ;IAClB,cAAc;IACd,YAAY;IACZ,UAAU;QACR,KAAK;;;;;;;;;;AE/DT;;;;;;;;;;;;;;;ACcA;AACA,QAAQ,aAAa;ADIrB;AAIA,IAAI;AAEJ;IA8BE,gBACU,OACA,eACA,WACA,WACA,cACA,oBACA,WACA,WAAc;QAPd;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QAzBH,YAAO;QACP,cAAS;QACT,iBAAY,IAAI;QAChB,aAAQ;QACR,YAAO;QAEP,iBAAY;QACZ,kBAAa;QACb,sBAAiB;QAGjB,iBAAY,CAAC,EAAC,eAAe,kBAAkB,eAAe,oBAAoB,WAAW,CAAC,EAAC,SAAS,gBAAc,EAAC,eAAe,aAAa,eAAe,OAAO,WAAW,CAAC,EAAC,SAAS,gBAAc,EAAC,eAAe,OAAO,eAAe,OAAO,WAAW,CAAC,EAAC,cAAc,YAAU,EAAC,eAAe,QAAQ,eAAe,OAAO,WAAW,CAAC,EAAC,cAAc,CAAC,OAAM,EAAC,aAAa,SAAO,EAAC,eAAe,gBAAgB,eAAe,OAAO,WAAW,CAAC,EAAC,cAAc,mBAAiB,EAAC,eAAe,iBAAiB,eAAe,eAAe,WAAW,CAAC,EAAC,cAAc,YAAU,EAAC,eAAe,WAAW,eAAe,OAAO,WAAW,CAAC,EAAC,cAAc,YAAU,EAAC,eAAe,SAAS,eAAe,OAAO,WAAW,CAAC,EAAC,SAAS,aAAY,EAAC,cAAc;QAgBrwB,OAAO;;IAGT;QAAA;QACE,KAAK,MAAM,SAAS,KAAK,eAAG;YAC1B,MAAK,MAAM;YACX,MAAK,kBAAkB,MAAK,cAAc,MAAM,wBAAwB,gCAAgC,UACtG,eAAG;gBACD,MAAK,OAAO;gBACZ,MAAK,UAAU;;YAGnB,MAAK,oBAAoB,MAAK,cAAc,MAAM,SAAS,iBAAiB,UAC1E,eAAG;gBACD,MAAK,SAAS;gBACd,MAAK;gBACL,MAAK,UAAU;;YAGnB,MAAK,kBAAkB,MAAK,cAAc,MAAM,oBAAoB,4BAA4B,UAC9F,eAAG;gBACD,MAAK,OAAO;;;;IAMpB;QACE,IAAI,KAAK,iBAAiB;YACxB,KAAK,gBAAgB;;;IAIlB,6BAAP,UAAiB,KAAU;QAEzB,IAAI,SAAS,IAAI,OAAO,KAAK;QAE7B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,KAAK;YACzC,KAAK,KAAK,GAAG,cAAc;YAC3B,IAAI,OAAO,KAAK,MAAM,KAAK,KAAK,GAAG;YACnC,KAAK,UAAU,IAAI,KAAK,KAAK,GAAG,QAAQ;YACxC,IAAI,SAAS,IAAI,OAAO,KAAK,OAAO,KAAK,IAAI,KAAK;YAClD,OAAO,OAAO;;QAEhB,IAAI,UAAU,OAAO;QACrB,IAAI,UAAU;;IAIT,+BAAP;QAAA;QACE,KAAK,OAAO,QAAQ,UAAC,OAAU;YAC7B,IAAI,eAAe,MAAK,UAAU,IAAI,MAAM;YAC5C,IAAI,aAAa,MAAK,UAAU,IAAI,MAAM;YAC1C,MAAM,OAAO,CAAC,cAAc;;;IAKzB,6BAAP,UAAiB,cAAkB;QACjC,IAAI,SAAS,SAAS,cAAc;QACpC,QAAQ;YACN,KAAK;gBACH,OAAO;YACT,KAAK;gBACH,OAAO;YACT;gBACE,OAAO;;;IAKN,2BAAP,UAAe,GAAQ,KAAQ;QAC7B,KAAK,cAAc;QACnB,KAAK,IAAI,eAAe,YAAY;;;IAK/B,8BAAP,UAAkB,GAAQ,OAAY,QAAe;QACnD,KAAK,YAAY,CAAC,KAAK;QACvB,IAAI,QAAQ;YACV,KAAK,QAAQ,EAAE,KAAK,KAAK,QAAQ,EAAC,IAAI,MAAM;;QAE9C,KAAK,aAAa,gBAAgB,aAAa,EAAC,OAAO,KAAK,OAAO,SAAS,KAAK,MAAM,KAAK,QAAO;QACnG,IAAI,CAAC,KAAK,aAAa,KAAK,YAAY;YACtC,KAAK,aAAa;YAClB,KAAK,iBAAiB;YACtB,KAAK,YAAY,cAAc;;;IAK5B,oCAAP,UAAwB,KAAQ;QAC9B,OAAO;YACL,KAAK,iBAAiB;YACtB,KAAK,aAAa;YAClB,IAAI,cAAc;YAClB,KAAK,cAAc;YACnB,KAAK,QAAQ;gBACX,MAAM,IAAI;gBACV,UAAU,IAAI;gBACd,oBAAoB,IAAI;;YAE1B,KAAK,WAAW,IAAI,KAAK,OAAO;;;IAK7B,oCAAP,UAAwB,KAAQ;QAC9B,KAAK,MAAM,qBAAqB,IAAI;QACpC,IAAI,KAAK,MAAM,SAAS,KAAK,MAAM,UAAU;YAC3C,KAAK,MAAM,OAAO,KAAK,MAAM,OAAO,IAAI;;QAE1C,OAAO,KAAK,MAAM;QAClB,IAAM,WAAW,KAAK,UAAU,YAAY;QAC5C,IAAI,MAAM,IAAI,SAAS;QACvB,KAAK,IAAI,QAAQ,KAAK,OAAO;YAC3B,IAAI,MAAM;gBACR,IAAI,QAAQ,KAAK,MAAM;;;QAI3B,KAAK,QAAQ;;IAGjB;;AAnKS,iBAAU;IACf;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;AAVS;AAuKA,iBAAoC;IAC/C,UAAU,oBAAQ;IAClB,cAAc;IACd,YAAY;;;;;;;;;AEnMd;;;;;;;;;;;;;;;ACcA;AACA,QAAQ,aAAa;ADErB,qBAAe;AAEf,sBAAsB,gBAA2C,mBAA4C;IAC3G,kBAAkB,UAAU,OAAO,WAAW;IAE9C;SACG,MAAM,eAAe;QACpB,KAAK;QACL,QAAQ;QACR,WAAW;;;;;;;;;AE3BjB;AACA;AACA;AACA,CAAC;AACD;AACA,CAAC;AACD;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kBAAkB;AAClB,iBAAiB;AACjB,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,KAAK;AACpB,eAAe,KAAK;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAyB;AAC5C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+BAA+B;AAC/B;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iDAAiD,YAAY;AAC7D;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,MAAM;AACN;AACA;;AAEA,2BAA2B;;AAE3B;AACA;AACA;AACA;AACA;AACA,wDAAwD,cAAc;AACtE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,gBAAgB,WAAW;AAC3B;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL,IAAI;;AAEJ;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+CAA+C,aAAa;AAC5D;;AAEA;;AAEA;AACA;AACA,4DAA4D;AAC5D;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,+CAA+C,aAAa;AAC5D;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB,UAAU,OAAO;AACjB,UAAU,QAAQ;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA,uCAAuC,QAAQ;AAC/C;AACA;AACA,sEAAsE;AACtE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA,uCAAuC;AACvC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,0EAA0E;AAC1E;AACA;;AAEA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iDAAiD,aAAa;AAC9D;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,2BAA2B;;AAE3B;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO;;AAEP;AACA,qCAAqC;AACrC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP,MAAM;AACN;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA,MAAM;AACN,IAAI;AACJ;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,YAAY;AACnC,qBAAqB,mCAAmC;AACxD,kBAAkB,QAAQ;AAC1B,uBAAuB,aAAa;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,iDAAiD,aAAa;AAC9D;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa,sCAAsC;AACnD,2DAA2D,cAAc;AACzE;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT,OAAO;;AAEP;AACA;AACA,OAAO;AACP;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA,CAAC;;;AAGD;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,eAAe,gBAAgB,iBAAiB,UAAU,eAAe;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA,2EAA2E,gCAAgC;AAC3G;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;AACT;AACA,MAAM;AACN,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mDAAmD,aAAa;AAChE;;AAEA;AACA;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,2BAA2B;AAC3B;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB;AACA,UAAU,QAAQ;AAClB;AACA,UAAU,WAAW;AACrB;AACA;AACA,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,eAAe,IAAI,eAAe;AACtD,8BAA8B,mBAAmB,IAAI,mBAAmB;AACxE,8BAA8B,mBAAmB,IAAI,mBAAmB;AACxE,6BAA6B,kBAAkB,IAAI,kBAAkB,iBAAiB;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,iDAAiD,aAAa;AAC9D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;;AAEA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,oCAAoC,oBAAoB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP,MAAM;;AAEN;AACA;AACA;AACA;AACA;;AAEA,IAAI;AACJ;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA,UAAU,IAAI;AACd,UAAU,gBAAgB;AAC1B;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA,mEAAmE;AACnE;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,OAAO;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,mDAAmD,aAAa;AAChE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,eAAe;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,sBAAsB;;AAEtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,Q;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,UAAU,WAAW;AACrB;AACA;AACA,UAAU,WAAW;AACrB;AACA;AACA,UAAU,MAAM;AAChB;AACA,UAAU,OAAO;AACjB;AACA,WAAW,4DAA4D;AACvE,wBAAwB,gBAAgB;AACxC;AACA,UAAU,QAAQ;AAClB;AACA;AACA,UAAU,QAAQ;AAClB;AACA,mBAAmB;AACnB,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,QAAQ;AAClB;AACA;AACA;AACA,UAAU,QAAQ;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO;AACjB;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,UAAU,WAAW;AACrB;AACA;AACA,UAAU,QAAQ;AAClB;AACA,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,4DAA4D,aAAa;AACzE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA,6DAA6D;;AAE7D;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,mHAAmH,aAAa;AAChI;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iDAAiD,aAAa;AAC9D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA,uDAAuD,aAAa;AACpE;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,UAAU,WAAW;AACrB;AACA;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,wBAAwB;AACxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,S;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,sDAAsD,aAAa;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;;AAEA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA,UAAU,OAAO,KAAK;AACtB;AACA,UAAU,OAAO,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iDAAiD,aAAa;AAC9D;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,OAAO;;AAEP,MAAM;;AAEN;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA,gEAAgE;AAChE;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,mDAAmD,aAAa;AAChE;AACA;;AAEA;AACA;AACA,gEAAgE;AAChE;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA,mCAAmC,qBAAqB;AACxD;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA;AACA,OAAO,WAAW;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAU,EAAE;;AAEZ;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,eAAe,YAAY;AAC3B,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C;AACA;AACA;AACA;AACA;;AAEA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,0C;AACA;AACA;AACA;AACA,2BAA2B,kBAAkB;AAC7C;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,aAAa;AACb;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iCAAiC;AACjC,aAAa;AACb;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qBAAqB,iBAAiB;AACtC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,qCAAqC;AACrC;AACA,yDAAyD,uBAAuB;AAChF;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,eAAe,KAAK;AACpB,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,KAAK;AACpB,eAAe,KAAK;AACpB,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA,WAAW,yCAAyC;AACpD;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,eAAe;AACf,0DAA0D,8BAA8B;AACxF;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,KAAK;AACpB,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D,+CAA+C;AAC/C;AACA,qCAAqC;AACrC,iCAAiC;AACjC;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA,uCAAuC;AACvC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,KAAK;AACpB,iBAAiB,KAAK;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qBAAqB;AACrB;;AAEA,oDAAoD,MAAM,KAAK;AAC/D;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,gDAAgD;AAChD;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA,mBAAmB;AACnB;;AAEA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;;AAEN;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,KAAK;AAClB;AACA;AACA;AACA,yBAAyB,wBAAwB;AACjD;AACA,QAAQ;AACR;AACA,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;;AAEA;;AAEA;AACA,iCAAiC;AACjC;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,CAAC;;;;AAID;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,OAAO;AACpB,YAAY,4DAA4D;AACxE,0BAA0B,gBAAgB;AAC1C;AACA,aAAa,SAAS;AACtB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,eAAe,YAAY;AAC3B;AACA;AACA;AACA;;AAEA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;;AAEA;AACA;AACA,iBAAiB,uBAAuB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAiC;AACjC;AACA,iBAAiB,uBAAuB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,YAAY;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,IAAI;AACjB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,wBAAwB;AAC1C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAuB;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,2BAA2B,eAAe;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,2BAA2B,eAAe;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,KAAK;AAClB;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,KAAK;AACL,wBAAwB,gBAAgB;AACxC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,UAAU;AACV;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,cAAc;AAC5E,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,YAAY;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,eAAe,KAAK;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,IAAI;AACjB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA,QAAQ;AACR,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,IAAI;AACjB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,CAAC;;AAED;AACA,CAAC,G;;;;;;ACx3GD;AACA;AACA;AACA;AACA;AACA,4BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,oCAAoC;AAC5C;;;AAGA;AACA,QAAQ,0BAA0B;AAClC;AACA;AACA;AACA;AACA,mEAAmE,kCAAkC;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,OAAO;AAC7B;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA,yBAAyB,YAAY;AACrC;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;;AAEA;AACA,wCAAwC;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,4BAA4B;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB;AACnB;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB;AACnB;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oCAAoC;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,4BAA4B;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAoB;AACpB,8BAA8B;AAC9B,uBAAuB;AACvB,8BAA8B;;AAE9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,CAAC;;;AAGD,CAAC;;;;;;;AC1UD;AACA;AACA;AACA;AACA;AACA,4BAA4B;;AAE5B;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,8DAA8D,EAAE;AAChE;AACA;AACA,mCAAmC,kCAAkC;AACrE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,mCAAmC,MAAM,2BAA2B;AAC5E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE;AAClE;AACA;AACA;AACA,iBAAiB,kBAAkB;AACnC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,qBAAqB;AACjE;AACA,iBAAiB,8BAA8B;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,iCAAiC;AACrF;AACA;AACA;AACA;AACA;AACA,oDAAoD,uBAAuB;AAC3E;AACA;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA;AACA;AACA;AACA,yDAAyD,kCAAkC;AAC3F;AACA,UAAU,UAAU,8CAA8C;AAClE,oBAAoB,8CAA8C;AAClE;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA,uBAAuB,OAAO;AAC9B;AACA,uBAAuB,QAAQ;AAC/B;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,SAAS,oEAAoE;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,oFAAoF;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,cAAc;AACrC;AACA,QAAQ,qCAAqC;AAC7C;AACA,yBAAyB,OAAO;AAChC,iCAAiC,kCAAkC,GAAG,qBAAqB;AAC3F;AACA;AACA,6BAA6B,QAAQ;AACrC;AACA;AACA;AACA,iCAAiC,QAAQ;AACzC;AACA;AACA;AACA,8BAA8B,OAAO;AACrC;AACA,6BAA6B,QAAQ;AACrC;AACA,yCAAyC,kCAAkC;AAC3E;AACA,WAAW,OAAO;AAClB;AACA;AACA,qCAAqC,QAAQ;AAC7C;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA,MAAM,YAAY,aAAa;AAC/B,kBAAkB,cAAc;AAChC,kBAAkB,2BAA2B;AAC7C,kBAAkB,gBAAgB;AAClC,kBAAkB,gBAAgB;AAClC;AACA;AACA,sCAAsC,eAAe;AACrD;AACA;AACA;AACA;AACA;AACA,4CAA4C,aAAa;AACzD,0BAA0B,WAAW;AACrC;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,oBAAoB;AAC5C;AACA;AACA;AACA;AACA,QAAQ,sEAAsE;AAC9E;AACA;AACA,qDAAqD,6BAA6B;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE,qBAAqB;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,yBAAyB;AAChC,gBAAgB,uBAAuB;AACvC,OAAO;;AAEP;AACA;AACA;AACA,6BAA6B,oCAAoC;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC,2BAA2B;;AAE3B;AACA,qBAAqB,YAAY;AACjC,4DAA4D;AAC5D,MAAM;;AAEN;AACA,mCAAmC,cAAc;AACjD;AACA;AACA,8BAA8B;AAC9B,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4CAA4C,aAAa;AACzD,eAAe,WAAW;AAC1B;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,aAAa;AACzD,eAAe,WAAW;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,4CAA4C,aAAa;AACzD,eAAe,WAAW;AAC1B;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,WAAW;AACX,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,qBAAqB;AACjD;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,UAAU;AACxD;AACA,eAAe;AACf,MAAM;;AAEN;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,2CAA2C,sBAAsB;AACjE;AACA;AACA;AACA;AACA;AACA,QAAQ,0BAA0B;AAClC;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,QAAQ;AAC9C;AACA;AACA,6BAA6B,QAAQ;AACrC;AACA,uCAAuC,2BAA2B;AAClE;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA;AACA;AACA,UAAU,2BAA2B;AACrC;AACA;AACA;AACA;AACA,iBAAiB,cAAc;AAC/B,kBAAkB,eAAe;AACjC,mBAAmB,6BAA6B;AAChD,oBAAoB,iBAAiB;AACrC,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,eAAe;AACvC,wBAAwB,cAAc;AACtC,wBAAwB,4BAA4B;AACpD,wBAAwB,cAAc;AACtC,wBAAwB;AACxB;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gBAAgB,cAAc;AAC9B,iBAAiB,eAAe;AAChC,kBAAkB,6BAA6B;AAC/C,mBAAmB,iBAAiB;AACpC,mBAAmB;AACnB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iCAAiC;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa;AACb;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,eAAe;AACf;AACA,WAAW;;AAEX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;;AAGA;AACA;;AAEA,2BAA2B;;AAE3B;AACA;AACA,kCAAkC;AAClC;AACA,oCAAoC,qBAAqB;AACzD;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;AACA,yCAAyC;AACzC;;AAEA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B;;AAE3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF,EAAE;AACrF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,uBAAuB,yCAAyC;AAChE;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oEAAoE,EAAE;AACtE,mCAAmC,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,EAAE;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB,iBAAiB;AACjB,+CAA+C;AAC/C;AACA,2CAA2C;AAC3C;AACA;AACA;;AAEA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA,8BAA8B,kBAAkB;AAChD;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA,+CAA+C;AAC/C;AACA;;AAEA;AACA;;AAEA;AACA,KAAK;AACL,GAAG;;;AAGH,CAAC;;;;;;;ACj1BD;AACA;AACA;AACA;AACA;AACA,mBAAmB;;AAEnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,EAAE,KAAK,EAAE;AAC9C;AACA;AACA;AACA,iCAAiC,EAAE,6BAA6B,EAAE;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB;AACA,aAAa,+DAA+D;AAC5E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA,mCAAmC,KAAK;AACxC;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;;AAEA,kCAAkC,yBAAyB;AAC3D;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA,0BAA0B,OAAO;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,YAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA,kCAAkC;;AAElC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA,kCAAkC;;;AAGlC;AACA;AACA;AACA,0CAA0C,mDAAmD;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,oDAAoD;AAC9F;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8DAA8D;AAC9D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA,WAAW,EAAE;AACb,YAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,WAAW,aAAa;AACxB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB,aAAa,aAAa;AAC1B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,wCAAwC,cAAc;AACtD;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;;;AAGA;AACA;AACA,WAAW,oBAAoB;AAC/B,aAAa;AACb;AACA;AACA,+BAA+B;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;;AAGA;AACA;;AAEA,mCAAmC,QAAQ;AAC3C;AACA;AACA;AACA,qCAAqC,QAAQ;AAC7C;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E;AAC5E;AACA;AACA,IAAI,oBAAoB;AACxB;AACA,WAAW,OAAO;AAClB,WAAW,UAAU;AACrB,aAAa,OAAO;AACpB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0EAA0E;AAC1E;AACA,UAAU,8BAA8B;AACxC;AACA;AACA,UAAU,OAAO;AACjB,UAAU,UAAU;AACpB,YAAY,OAAO;AACnB;AACA;AACA;AACA;;;;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,0BAA0B,cAAc,EAAE,MAAM;AAChD,uBAAuB;AACvB,4BAA4B;AAC5B;AACA;AACA,WAAW,EAAE;AACb,aAAa,EAAE;AACf;AACA,sBAAsB;AACtB;;;AAGA,yBAAyB,4BAA4B;;AAErD;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,6BAA6B;;;AAG7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,2BAA2B;;;AAG3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,0BAA0B;;;AAG1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,0BAA0B;;;AAG1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA,4BAA4B;;;AAG5B;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;;AAEA;AACA;AACA,aAAa,OAAO,iBAAiB;AACrC;AACA;AACA,cAAc;AACd,aAAa,kBAAkB;AAC/B;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb;AACA,WAAW,gBAAgB;AAC3B;AACA,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,aAAa;AACnC,wBAAwB,eAAe;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,QAAQ;AACjD;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,iDAAiD,kBAAkB;AACnE;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,yBAAyB,cAAc;AACvC,yBAAyB,cAAc;AACvC,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,qBAAqB,cAAc;AACnC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,WAAW;AACtB,WAAW,KAAK;AAChB,aAAa,WAAW;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,wCAAwC;AACnD,WAAW,eAAe;AAC1B;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,2BAA2B;AACxC;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,YAAY;AACf;AACA;AACA;AACA;AACA;AACA,2DAA2D,kCAAkC;AAC7F,GAAG;AACH;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;;AAGA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA,GAAG;AACH;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;;AAEA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,eAAe;AAC1B,MAAM,4BAA4B;AAClC,WAAW,SAAS;AACpB;AACA;AACA,SAAS,8CAA8C;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,wBAAwB;AAC9B;AACA,uCAAuC,4CAA4C;AACnF,uCAAuC,qBAAqB,GAAG,+BAA+B;AAC9F,MAAM,8BAA8B;AACpC,mCAAmC,qCAAqC,gBAAgB,8BAA8B;AACtH;AACA;AACA;AACA,mCAAmC,qBAAqB;AACxD;AACA,0BAA0B,qBAAqB;AAC/C;AACA;AACA,4FAA4F,OAAO;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,GAAG,KAAK,GAAG,MAAM;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,GAAG,KAAK,GAAG,MAAM;;AAEzC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,oBAAoB,MAAM;;AAE1B;AACA;AACA;AACA;AACA;;AAEA;AACA,wBAAwB,GAAG,KAAK,GAAG,MAAM;;AAEzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,sCAAsC;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,+BAA+B;AACjD;AACA;AACA;AACA,gFAAgF,4CAA4C;AAC5H,YAAY,qBAAqB,GAAG,+BAA+B,MAAM,8BAA8B;AACvG,iCAAiC,qCAAqC,gBAAgB,8BAA8B;AACpH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,8BAA8B;AACzC;AACA;AACA,aAAa;AACb,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA,aAAa,eAAe;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yDAAyD,EAAE;AAC3D,+BAA+B,oBAAoB;AACnD;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,2CAA2C;AACnD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gDAAgD;;AAEhD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,EAAE;AAC/B;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,2BAA2B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wCAAwC,EAAE,OAAO,EAAE;AACnD;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;AACA;AACA,8DAA8D,EAAE;AAChE;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,MAAM;AACjB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA,iBAAiB,+CAA+C;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,6BAA6B;AACnE;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,eAAe,gCAAgC;AAC/C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,qBAAqB;AACxE,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA,kDAAkD,+BAA+B;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,+BAA+B;AACvC,QAAQ,wBAAwB;AAChC;AACA,eAAe,QAAQ;AACvB,eAAe,iBAAiB;AAChC;AACA,eAAe,UAAU;AACzB,eAAe,4CAA4C;AAC3D,iBAAiB,eAAe,sBAAsB,qBAAqB;AAC3E;AACA;;AAEA;;AAEA;AACA;AACA,oEAAoE,EAAE;AACtE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,EAAE;AACtD;AACA;AACA;;AAEA,mBAAmB,mBAAmB;AACtC;;AAEA,mBAAmB,kBAAkB;AACrC;;AAEA,mBAAmB,kBAAkB;AACrC;;AAEA;;AAEA,mBAAmB,eAAe;AAClC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B,uBAAuB,cAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,mBAAmB;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,4CAA4C;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE,EAAE;AAC1E;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA;AACA,kBAAkB,iDAAiD;AACnE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA,kBAAkB,+CAA+C;AACjE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA,kBAAkB,+CAA+C;AACjE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,EAAE;AACvB;AACA,kBAAkB,2CAA2C;AAC7D;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,EAAE;AACvB;AACA;AACA,kBAAkB,iDAAiD;AACnE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA;AACA,kBAAkB,mDAAmD;AACrE;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,wBAAwB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB,+DAA+D;AACjF,cAAc,iCAAiC;AAC/C;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,SAAS;AAC9B;AACA,kBAAkB,6DAA6D;AAC/E;AACA;AACA,2DAA2D,iBAAiB;AAC5E;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,cAAc;AACnC;AACA,qBAAqB,SAAS;AAC9B;AACA,kBAAkB,qEAAqE;AACvF;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,cAAc;AACnC;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA,kBAAkB,iEAAiE;AACnF;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qBAAqB,OAAO;AAC5B,iBAAiB,0EAA0E;AAC3F;AACA;AACA,kBAAkB,iEAAiE;AACnF;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA,cAAc,gDAAgD;AAC9D;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oCAAoC,QAAQ;AAC5C;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA,sCAAsC;AACtC,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB,eAAe,OAAO;AACtB,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,aAAa;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,SAAS,0BAA0B;AACnC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAkB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,gCAAgC;AAChE,sCAAsC,uDAAuD;AAC7F;AACA,8CAA8C,gCAAgC;AAC9E;AACA;AACA,eAAe,uDAAuD;AACtE;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kBAAkB;AAC7B,aAAa,OAAO;AACpB;;AAEA;;AAEA,+BAA+B;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qBAAqB,eAAe;;;AAGpC;AACA;AACA,uBAAuB;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4BAA4B;AAC5B;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,2CAA2C,OAAO;AAClD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA,yCAAyC,UAAU,UAAU;AAC7D;;AAEA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,yBAAyB;AACzB;AACA,KAAK;AACL,uBAAuB;AACvB;AACA,OAAO;AACP,6BAA6B;AAC7B;AACA;AACA,SAAS,OAAO,uBAAuB,uBAAuB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;;AAGA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,yBAAyB,YAAY;AACrC;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,sCAAsC,QAAQ;AAC9C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,qBAAqB;AACpD;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA,CAAC;;AAED;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;AACL;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,mBAAmB,eAAe;AAClC;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,uBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,iBAAiB,eAAe;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,mBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;;AAEA,qCAAqC,QAAQ;AAC7C;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;;AAEA,6CAA6C,QAAQ;AACrD;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,GAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,oCAAoC,8BAA8B,EAAE;AACpE,wCAAwC,uCAAuC,EAAE;AACjF,8CAA8C,yCAAyC,EAAE;AACzF,mDAAmD,kDAAkD,EAAE;AACvG;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;;AAEA,qCAAqC,QAAQ;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,oCAAoC;AAClE;AACA,WAAW,wBAAwB;AACnC,QAAQ,qBAAqB;AAC7B,WAAW,SAAS;AACpB;AACA,aAAa,SAAS,uBAAuB,+BAA+B;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,mCAAmC,sBAAsB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,eAAe;AAC9D;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,+BAA+B;AAC1F;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,EAAE;AAChB;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,6BAA6B;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,IAAI,+CAA+C;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,YAAY,EAAE;AACd;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,gCAAgC,kCAAkC;AAClE,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA,aAAa,EAAE;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB;AACA,aAAa,OAAO;AACpB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,gFAAgF;AAChF;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C;AACA;AACA,WAAW,SAAS;AACpB;AACA,aAAa,eAAe;AAC5B;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,6BAA6B;AACrC,aAAa,+BAA+B;AAC5C,IAAI,qBAAqB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,+BAA+B;AACnE;AACA;AACA;AACA;AACA;AACA,oBAAoB,6BAA6B;AACjD;AACA;AACA,MAAM,sDAAsD;AAC5D,QAAQ;AACR,MAAM,iDAAiD;AACvD;AACA,MAAM,2CAA2C;AACjD;AACA,MAAM,8CAA8C;AACpD;AACA;AACA,MAAM,8CAA8C;AACpD;AACA;AACA,MAAM,uDAAuD;AAC7D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8CAA8C,+BAA+B;AAC7E;AACA;AACA;AACA;AACA,qBAAqB,mBAAmB;AACxC,IAAI,mCAAmC;AACvC;AACA;AACA;AACA,2DAA2D,mCAAmC;AAC9F,WAAW;AACX,uCAAuC,mBAAmB;AAC1D;AACA;AACA,WAAW,OAAO;AAClB;AACA,WAAW,oBAAoB;AAC/B;AACA;AACA,QAAQ,+CAA+C;AACvD;AACA,QAAQ,yDAAyD;AACjE;AACA,aAAa,OAAO;;AAEpB;AACA;AACA;AACA,IAAI,iDAAiD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,aAAa;AACrE,OAAO;AACP,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oDAAoD;AACvE;AACA;AACA,WAAW,OAAO;AAClB,WAAW,iCAAiC;AAC5C,sFAAsF,aAAa;AACnG,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oDAAoD;AACvE;AACA;AACA,WAAW,OAAO;AAClB,WAAW,iCAAiC;AAC5C;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA,IAAI,oDAAoD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,0CAA0C,+BAA+B;AACzE;AACA;AACA;AACA;AACA;AACA,uCAAuC,4BAA4B;AACnE,eAAe,wCAAwC;AACvD;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,iCAAiC;AACpE;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,6CAA6C,+BAA+B;AAC5E,0DAA0D,gCAAgC;AAC1F;AACA;AACA,eAAe,gCAAgC;AAC/C,uDAAuD,4BAA4B;AACnF,gCAAgC,wCAAwC;AACxE;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,+CAA+C,+BAA+B;AAC9E;AACA;AACA;AACA;AACA,wDAAwD,uBAAuB;AAC/E;AACA,WAAW,OAAO;AAClB,WAAW,iCAAiC;AAC5C;AACA,WAAW,4CAA4C;AACvD;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,mBAAmB;AAC5C,aAAa,gCAAgC;AAC7C;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;;AAGA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,8DAA8D,EAAE;AAChE,WAAW;AACX,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA,iDAAiD;AACjD;AACA;AACA;AACA;AACA,mCAAmC,qCAAqC,EAAE;;AAE1E;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,EAAE;AACnD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,oDAAoD,EAAE;AACtD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA,6BAA6B,2CAA2C;;AAExE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,qDAAqD,wBAAwB;AAC7E;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sCAAsC,QAAQ;AAC9C;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,EAAE,WAAW,EAAE;AACxF;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,qEAAqE,EAAE;AACvE;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA,oFAAoF,EAAE;AACtF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;;AAGA;AACA;AACA,mFAAmF;AACnF;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,yCAAyC;AAC7C;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAkB,uCAAuC;AACzD,MAAM,yCAAyC;AAC/C;AACA;AACA;AACA,MAAM,uCAAuC;AAC7C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,yCAAyC;AAChE;AACA;AACA;AACA,0BAA0B,yCAAyC;AACnE;AACA,MAAM,iGAAiG;AACvG;AACA,oCAAoC,uCAAuC;AAC3E;AACA;AACA,aAAa,QAAQ;AACrB,4BAA4B,yCAAyC;AACrE;AACA,gBAAgB,yBAAyB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,qDAAqD;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA,0BAA0B,GAAG;AAC7B,oBAAoB,GAAG;AACvB;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB,SAAS;AAC3B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,oDAAoD,yBAAyB;AAC7E;AACA;AACA;;AAEA;AACA;AACA,WAAW;AACX,SAAS;AACT;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,oBAAoB;AACrC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,OAAO;AACP;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA,2FAA2F,EAAE;AAC7F;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kJAAkJ,EAAE;AACpJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,sCAAsC;AAC9C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,WAAW;AAC5B;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAkB;AACnC;AACA;AACA,iBAAiB,YAAY;AAC7B,iBAAiB,UAAU;AAC3B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+GAA+G;AAC/G;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,WAAW;AAC5B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,YAAY;AAC7B,iBAAiB,SAAS;AAC1B;AACA,kBAAkB,QAAQ;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,WAAW;AAC5B;AACA,iBAAiB,YAAY;AAC7B,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,WAAW;AAC5B;AACA,iBAAiB,YAAY;AAC7B,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,OAAO;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,OAAO;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,iBAAiB,WAAW;AAC5B,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,OAAO;AACrC,0BAA0B,OAAO;AACjC,iCAAiC,OAAO;AACxC,wBAAwB,OAAO;AAC/B;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uBAAuB,sBAAsB;AAC7C;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;;AAEP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb,WAAW;AACX;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,sEAAsE;AACrF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,0CAA0C;AACnE;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,kDAAkD,2BAA2B;;AAE7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,WAAW;AACxB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C;AACA,aAAa,OAAO;AACpB,aAAa,SAAS;AACtB,aAAa,QAAQ;AACrB;AACA;AACA,+DAA+D;AAC/D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C;AACA,aAAa,iBAAiB;AAC9B,cAAc,iBAAiB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,WAAW;AACxB,aAAa,QAAQ;AACrB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,gCAAgC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,uBAAuB;AACzD;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA,SAAS,QAAQ;AACjB;AACA,aAAa,OAAO;AACpB;AACA,OAAO,OAAO;AACd,QAAQ,GAAG,QAAQ,OAAO,OAAO,EAAE;AACnC;AACA,QAAQ,GAAG,QAAQ,OAAO;AAC1B,OAAO,KAAK,WAAW,OAAO;AAC9B,OAAO,KAAK;AACZ,OAAO,KAAK;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,yDAAyD,EAAE;AAC3D;;AAEA;AACA,2BAA2B,YAAY,YAAY;AACnD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,kBAAkB,UAAU,iCAAiC;AACvE;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,gCAAgC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,EAAE;AACrB;AACA,qBAAqB,EAAE;AACvB;AACA;AACA;AACA;AACA,4DAA4D,SAAS;;AAErE;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,gCAAgC;AAC/E;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,EAAE;AACvB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,gCAAgC;AACtE;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gCAAgC;AACzD,iCAAiC,kCAAkC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,gCAAgC;AACxF;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,UAAU,WAAW;AAC/C;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD,iDAAiD;AACjD;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,mCAAmC;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,qCAAqC;AAC7C;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,kCAAkC;AAC/D;AACA;AACA,IAAI,+CAA+C;AACnD;AACA;AACA;AACA;AACA,YAAY,sCAAsC;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,mCAAmC;AAC7C,UAAU,mCAAmC,sDAAsD,MAAM;AACzG;AACA,aAAa,yCAAyC,yDAAyD,MAAM;AACrH,UAAU,uCAAuC;AACjD,UAAU,mCAAmC;AAC7C,UAAU,qDAAqD;AAC/D,UAAU,6BAA6B;AACvC,UAAU,uCAAuC,qEAAqE,MAAM;AAC5H,UAAU,2CAA2C;AACrD,UAAU,mDAAmD;AAC7D,UAAU,iCAAiC;AAC3C,UAAU,2CAA2C;AACrD,UAAU,iCAAiC;AAC3C;AACA,eAAe,wCAAwC,yDAAyD,MAAM;AACtH,eAAe,0CAA0C,0DAA0D;AACnH;AACA;AACA,+CAA+C;AAC/C,UAAU;AACV;AACA,aAAa,2BAA2B;AACxC,cAAc,wCAAwC,yDAAyD,MAAM;AACrH,cAAc,0CAA0C,0DAA0D;AAClH;AACA;AACA,aAAa,2BAA2B,4BAA4B;AACpE;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D;AAC3D;AACA;AACA;AACA,6DAA6D;AAC7D,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA,0BAA0B,+CAA+C;AACzE;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,cAAc;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,sBAAsB,YAAY;AAClC;AACA,qBAAqB,oBAAoB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,aAAa;AACpC;AACA,sBAAsB,oBAAoB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE;AACjE,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,+CAA+C,cAAc;AAC7D,sDAAsD,gBAAgB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,IAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA,sBAAsB,MAAM,8CAA8C,sBAAsB;AAChG;AACA,OAAO,MAAM;AACb;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA,gDAAgD,oDAAoD;AACpG;AACA,qDAAqD;AACrD;AACA;AACA,iDAAiD,qBAAqB;AACtE,kDAAkD;AAClD,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,uBAAuB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,0CAA0C;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA,gFAAgF,WAAW;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4FAA4F;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,gBAAgB,qBAAqB,yBAAyB;AACzF,YAAY,iCAAiC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,YAAY;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF;AACtF;AACA;AACA;AACA,6FAA6F;AAC7F,yDAAyD;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,yCAAyC;AAC7C;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE;AACvE;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,gCAAgC;AAClD,kCAAkC,yCAAyC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,uDAAuD;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kEAAkE;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,mBAAmB;AACxD;AACA;AACA;AACA;AACA,YAAY,sFAAsF;AAClG;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,IAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA,wCAAwC,4BAA4B;AACpE,sFAAsF,mBAAmB;AACzG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,mBAAmB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,MAAM;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,WAAW,GAAG,eAAe,MAAM;AACzF;AACA,yBAAyB,mBAAmB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,kDAAkD;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,KAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,+BAA+B,MAAM;AACrC,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,MAAM;AAClC;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,wCAAwC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,aAAa,0CAA0C;AACvD;AACA;AACA,mBAAmB,gCAAgC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,OAAO;AAC1D;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,2CAA2C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD,iCAAiC;AACjC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,iDAAiD,MAAM;AACvD;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sBAAsB,EAAE,kBAAkB,EAAE;AAC5C,2BAA2B,KAAK,EAAE,KAAK,EAAE,OAAO;AAChD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,EAAE;AAC9D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kEAAkE,EAAE;AACpE;AACA;AACA;AACA,yCAAyC,EAAE;AAC3C;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA,gCAAgC,EAAE,mBAAmB,EAAE;AACvD;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,cAAc;AAC3B;AACA;AACA,aAAa,eAAe;AAC5B,SAAS,sCAAsC,UAAU,2BAA2B;AACpF,eAAe,oBAAoB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb;AACA,WAAW;AACX;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,SAAS,0EAA0E;AACnF;AACA;AACA,2BAA2B,oBAAoB;AAC/C,gEAAgE;AAChE,gCAAgC;AAChC,6BAA6B,QAAQ;AACrC;AACA;AACA,yBAAyB,oBAAoB;AAC7C;AACA;AACA;AACA,mDAAmD,qCAAqC;AACxF;AACA;AACA;AACA;AACA;AACA,4BAA4B,oBAAoB;AAChD;AACA;AACA,sDAAsD,qCAAqC;AAC3F;AACA;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;AACjC;AACA,eAAe,wDAAwD;AACvE,2BAA2B,SAAS,aAAa,iDAAiD;AAClG;AACA,wBAAwB,wBAAwB;AAChD;AACA,0DAA0D,sCAAsC;AAChG;AACA;AACA;AACA,eAAe,oBAAoB;AACnC;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,YAAY;AAClD;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,sCAAsC,YAAY;AAClD,oBAAoB;AACpB,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,QAAQ;AACR;AACA;AACA,wDAAwD,sCAAsC;AAC9F;AACA;AACA,eAAe,iEAAiE;AAChF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+CAA+C,mCAAmC;AAClF;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,gDAAgD;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,2BAA2B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,2BAA2B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iEAAiE;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,cAAc;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,EAAE;AAC9C;AACA;AACA;AACA;AACA,qDAAqD,QAAQ;AAC7D;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD;AACzD;AACA,iBAAiB,OAAO;AACxB;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,eAAe;AAChC,iBAAiB,SAAS;AAC1B;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,yBAAyB,uBAAuB;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,iBAAiB,4BAA4B;AAC7C;AACA,yBAAyB;AACzB,sBAAsB;AACtB,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;;AAGA;AACA;AACA,kDAAkD,uBAAuB;AACzE;AACA;AACA,yCAAyC,EAAE,4BAA4B;AACvE,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,wCAAwC;AACvD;AACA,eAAe,YAAY;AAC3B;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,qBAAqB,qBAAqB;AAC1C;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,oBAAoB;AACzC;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA,wCAAwC,QAAQ;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;;AAEA,aAAa;AACb;;AAEA,aAAa;AACb;;AAEA,aAAa;AACb;AACA;;AAEA;;AAEA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uDAAuD,QAAQ;AAC/D;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,EAAE,sBAAsB,EAAE;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA,eAAe,KAAK;AACpB,eAAe,OAAO;AACtB,eAAe,wCAAwC;AACvD;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA,eAAe,QAAQ;AACvB;AACA,eAAe,iBAAiB;AAChC,eAAe,iBAAiB;AAChC,eAAe,OAAO;AACtB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,QAAQ;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,gBAAgB;AAChB;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+CAA+C,oDAAoD;AACnG;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC,WAAW;;AAEX;;AAEA;AACA;AACA,aAAa;;AAEb;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe;;AAEf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,eAAe;;AAEf;AACA;AACA;AACA,gFAAgF,EAAE;AAClF;AACA,eAAe;;AAEf;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAiC;AACjC;AACA,4BAA4B,iEAAiE;AAC7F;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,6CAA6C,EAAE,wCAAwC,EAAE;AACzF;AACA;;AAEA;;AAEA,oCAAoC;;AAEpC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,mBAAmB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,mBAAmB;AAChE;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,+CAA+C,+BAA+B,EAAE;AAChF;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,SAAS;;AAET;AACA,2CAA2C,QAAQ;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,kFAAkF,EAAE;AACpF,0BAA0B,EAAE;AAC5B;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,6BAA6B,EAAE,6BAA6B,EAAE;AAC9D;AACA;AACA,OAAO;AACP;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,QAAQ;AACrD,gDAAgD,mDAAmD;AACnG;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,QAAQ;AAClD;AACA;AACA;AACA;AACA,8CAA8C,2CAA2C;AACzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA,0CAA0C,QAAQ;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,6CAA6C,EAAE,wCAAwC,EAAE;AACzF;AACA;;AAEA,iCAAiC;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,gEAAgE,GAAG,EAAE,GAAG,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE;AACrG;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,SAAS;AACT;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,+EAA+E,EAAE;AACjF;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA,OAAO;AACP;;;AAGA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,KAAK;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,QAAQ;AACrD;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB,iBAAiB;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA;;;AAGA;AACA,gCAAgC,kCAAkC,EAAE;AACpE;;;AAGA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACA,sDAAsD,wCAAwC;AAC9F;AACA;AACA;AACA;AACA;AACA,iCAAiC,EAAE,mBAAmB,EAAE,0BAA0B,EAAE;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,4DAA4D,QAAQ;AACpE;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,mDAAmD,oDAAoD;;;AAGvG;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,GAAG;AACtE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,0CAA0C;AAC1C;AACA,WAAW,OAAO;AAClB;;;;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,oBAAoB;AACrC;AACA,mBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yCAAyC;AACjD;AACA;AACA;AACA,IAAI,+CAA+C;AACnD;AACA;AACA,sBAAsB;AACtB;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,cAAc;AAC3B;AACA,aAAa,eAAe;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA,mCAAmC,+BAA+B;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+CAA+C,EAAE;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,6CAA6C,EAAE;AAC/C;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,uCAAuC,EAAE,SAAS,EAAE;AACpD;AACA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,uCAAuC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,sDAAsD;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA,SAAS,MAAM,WAAW,sBAAsB,EAAE;AAClD;AACA,WAAW,MAAM;AACjB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA,qCAAqC,qCAAqC;AAC1E,yBAAyB,KAAK;AAC9B;AACA;AACA,IAAI,KAAK;AACT;AACA,oCAAoC;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,oBAAoB;AAClC;AACA;AACA,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,SAAS,QAAQ,aAAa;AAC9B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,oBAAoB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM,6CAA6C;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA,KAAK;AACL;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B,aAAa,kBAAkB;AAC/B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,4BAA4B;AACvC,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;;;AAGA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,qBAAqB;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,qBAAqB;AACpE;AACA,+BAA+B,eAAe;AAC9C,MAAM,uCAAuC;AAC7C,sBAAsB,kCAAkC;AACxD;AACA,wCAAwC,OAAO;AAC/C;AACA;AACA,wCAAwC,OAAO;AAC/C;AACA;AACA,iCAAiC,OAAO;AACxC,eAAe,0CAA0C;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,8CAA8C;AACxF;AACA,mFAAmF,+BAA+B;AAClH,mBAAmB,mDAAmD;AACtE;AACA,6CAA6C,OAAO;AACpD;AACA,MAAM,sBAAsB;AAC5B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,6DAA6D;AACrF;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB;AACA;AACA;AACA,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,4CAA4C;AACpD;AACA,gEAAgE;AAChE,iBAAiB;AACjB;AACA,sCAAsC,kCAAkC;AACxE;AACA;AACA;AACA;AACA;AACA,4EAA4E,uCAAuC;AACnH,gEAAgE,oBAAoB;AACpF;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,YAAY;AACZ;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA,0BAA0B,OAAO;AACjC,2BAA2B,uBAAuB;AAClD,0BAA0B,OAAO;AACjC,8BAA8B,OAAO;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,UAAU;AACV,UAAU;AACV,UAAU;AACV,UAAU;AACV,UAAU;AACV,UAAU;AACV;AACA;AACA;AACA,iCAAiC,oBAAoB;AACrD,QAAQ,qDAAqD;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,SAAS;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,wBAAwB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,eAAe;AACf;AACA;AACA,kCAAkC,IAAI,aAAa,IAAI;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,QAAQ,uBAAuB;AAC/B;AACA,aAAa,uCAAuC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,+CAA+C;AACvD,QAAQ,4DAA4D;AACpE;AACA,iCAAiC,uBAAuB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yCAAyC;AACjD;AACA;AACA;AACA;AACA;AACA,gEAAgE;AAChE,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,yBAAyB;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wFAAwF;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gGAAgG;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA,2BAA2B,OAAO;AAClC,wBAAwB,qBAAqB;AAC7C;AACA,2BAA2B,uBAAuB;AAClD;AACA,yBAAyB,cAAc;AACvC,4BAA4B,OAAO;AACnC;AACA;AACA,kCAAkC,OAAO;AACzC;AACA;AACA,wCAAwC,OAAO;AAC/C;AACA;AACA,mCAAmC,OAAO;AAC1C,mCAAmC,OAAO;AAC1C;AACA,cAAc,oEAAoE;AAClF;AACA;AACA,iBAAiB;AACjB;AACA;AACA,cAAc,oFAAoF;AAClG;AACA;AACA,iBAAiB;AACjB;AACA,oCAAoC,8CAA8C;AAClF;AACA;AACA,aAAa,0BAA0B;AACvC,oCAAoC,oCAAoC;AACxE,2CAA2C;AAC3C,4CAA4C;AAC5C,0BAA0B,eAAe;AACzC,aAAa,uCAAuC;AACpD,iBAAiB,kCAAkC;AACnD,4BAA4B,eAAe,iCAAiC;AAC5E;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA,iCAAiC,OAAO;AACxC;AACA;AACA,iBAAiB,YAAY,YAAY,qBAAqB;AAC9D;AACA;AACA;AACA,kBAAkB,eAAe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,QAAQ;AACrC,+BAA+B,MAAM;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,iBAAiB,8DAA8D;AAC/E;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA,mGAAmG,EAAE;AACrG;;AAEA;AACA,+HAA+H,EAAE;AACjI;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;;AAEA;;;AAGA;AACA,iDAAiD,QAAQ;AACzD;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;;AAET;AACA;;AAEA;AACA;AACA,kCAAkC;AAClC;;AAEA,8BAA8B;;AAE9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,WAAW;AACjD;AACA,QAAQ,6FAA6F;AACrG,2CAA2C,6DAA6D;AACxG;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,+BAA+B;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,sBAAsB;AAChD;AACA,eAAe,qBAAqB;AACpC;AACA,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,EAAE;AAClB,gBAAgB,QAAQ;AACxB,kBAAkB,YAAY;AAC9B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;;AAGA;AACA;AACA;AACA,gCAAgC,cAAc;AAC9C;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;;;AAGA;AACA;AACA;AACA,gCAAgC,cAAc;AAC9C;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kCAAkC,EAAE;AACpC,2BAA2B,EAAE;AAC7B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,aAAa;AACb,gDAAgD;AAChD;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,eAAe;AACf;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,8EAA8E,EAAE;AAChF;;AAEA;AACA;AACA;AACA,wEAAwE,EAAE,aAAa,EAAE;AACzF;;AAEA;AACA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,gBAAgB;AACzD;AACA,IAAI;AACJ;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,uBAAuB;AACpD;AACA;AACA;AACA,IAAI,qBAAqB,KAAK,qCAAqC;AACnE;AACA,uDAAuD;AACvD,gBAAgB;AAChB;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,mCAAmC,EAAE;AACrC;AACA;AACA;;AAEA;AACA,4DAA4D,EAAE,GAAG,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,SAAS;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;;AAGH;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,uBAAuB;AACvB,qBAAqB;;AAErB;AACA;AACA;AACA;AACA,qFAAqF;AACrF;AACA,aAAa,QAAQ;AACrB,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uFAAuF;AACvF;AACA,aAAa,QAAQ;AACrB,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,2BAA2B;AACxC,QAAQ,mDAAmD;AAC3D;AACA;AACA;AACA;AACA,gCAAgC;AAChC,yCAAyC,kBAAkB;AAC3D,qBAAqB,eAAe;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC,wBAAwB;AACxB;AACA;AACA,mCAAmC,UAAU,GAAG,MAAM;AACtD;AACA;AACA;AACA,+BAA+B,UAAU,GAAG,MAAM;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,+CAA+C;AACvD;AACA;AACA,qCAAqC,MAAM,YAAY,GAAG,UAAU,GAAG;AACvE;AACA;AACA;AACA;AACA,WAAW,2BAA2B;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,UAAU,IAAI,EAAE,4BAA4B,GAAG;AACnG;AACA,yBAAyB,UAAU;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,IAAI,IAAI,wCAAwC,KAAK,SAAS;AAC7F,kFAAkF;AAClF;AACA;AACA,8DAA8D,KAAK;AACnE,oFAAoF;AACpF;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,WAAW,sBAAsB;AAC5D;AACA;AACA;AACA;AACA,2BAA2B,WAAW,qBAAqB,EAAE;AAC7D;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB;AACA;AACA,eAAe,QAAQ;AACvB,0BAA0B;AAC1B,0BAA0B,qCAAqC,mBAAmB;AAClF;AACA,eAAe,SAAS;AACxB;AACA,iBAAiB,kBAAkB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kDAAkD,QAAQ;AAC1D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,oBAAoB,QAAQ;AAC5B;AACA;;AAEA;AACA,aAAa;AACb;AACA;;AAEA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,SAAS;AACT;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,2FAA2F;AAC3F;AACA,YAAY,6EAA6E;AACzF;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,yFAAyF;AACzF;AACA,YAAY,yEAAyE;AACrF;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,uDAAuD;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,WAAW;AAC3B;AACA,gBAAgB,OAAO;AACvB,gBAAgB,QAAQ;AACxB;AACA,gBAAgB,SAAS;AACzB,uCAAuC,wCAAwC;AAC/E,gBAAgB,MAAM;AACtB,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,SAAS;AACrD,4CAA4C,SAAS;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,OAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,mBAAmB,OAAO;AAC1B;AACA,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,mBAAmB,QAAQ;AAC3B;AACA,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,mBAAmB,EAAE;AACrB;AACA,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;;AAEA;AACA,qBAAqB;AACrB;;;AAGA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,oCAAoC,GAAG;AACvC;;AAEA;AACA,oDAAoD,EAAE;AACtD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,uDAAuD,EAAE,yBAAyB,EAAE;AACpF;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,yDAAyD;;AAEzD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;;AAEA;;;AAGA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,qBAAqB,EAAE;AACvB;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B,cAAc,gBAAgB;AAC9B;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA,aAAa,+CAA+C;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,uCAAuC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,kCAAkC;AAClC;AACA;AACA;AACA,WAAW;;AAEX;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B,cAAc,OAAO;AACrB;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,kBAAkB;AAC/B;AACA;AACA,yBAAyB,QAAQ;AACjC;AACA;AACA,6BAA6B,QAAQ;AACrC;AACA;AACA,kBAAkB;AAClB,8BAA8B,eAAe;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,8BAA8B;AAC9E;AACA,MAAM,iEAAiE;AACvE;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,wBAAwB;AACxB;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;;AAGL;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;;AAEA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA,CAAC;AACD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,mDAAmD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA,yCAAyC;AACzC;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO,YAAY;;AAEnB;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,sBAAsB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA,wFAAwF,4BAA4B,EAAE;AACtH,cAAc;;;AAGd;;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO,2BAA2B,KAAK;AACvC,0BAA0B,4BAA4B;AACtD;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,+CAA+C;AAC3E;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,gDAAgD,EAAE,WAAW,EAAE,iBAAiB,EAAE;AAClF;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,EAAE;AACpC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;AACA,iDAAiD,UAAU;AAC3D;AACA,yBAAyB;AACzB,gBAAgB;AAChB;AACA;AACA,GAAG;;AAEH;AACA,YAAY;AACZ,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB;AAChB;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,cAAc;AACd,KAAK;AACL;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK,wBAAwB;AAC7B;AACA,KAAK;AACL;AACA,KAAK;AACL,iBAAiB;AACjB,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mBAAmB;AACnB;AACA,OAAO;AACP,mBAAmB;AACnB;AACA,OAAO;AACP,mBAAmB;AACnB,OAAO;AACP;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,kBAAkB;;AAElB;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ,GAAG;;AAEH;AACA;AACA,YAAY;AACZ,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA,YAAY;AACZ,GAAG;;AAEH;AACA;AACA,oCAAoC;AACpC;AACA,wBAAwB;AACxB;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA,mBAAmB;;AAEnB,YAAY;AACZ,GAAG;;AAEH;AACA;AACA,gCAAgC,EAAE,IAAI,EAAE,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE;AAC/F;AACA,GAAG;;AAEH;AACA;AACA,iEAAiE,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,iEAAiE,EAAE;AACnE;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA,aAAa,0BAA0B;AACvC,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,YAAY,sEAAsE,2BAA2B;AAC7G;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,WAAW,4BAA4B;AACvC,eAAe,4BAA4B;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,qDAAqD;AACrD;AACA;AACA,GAAG;;AAEH;AACA,qCAAqC;AACrC;AACA;AACA,WAAW;AACX,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,0DAA0D;AAC1D;AACA,GAAG;;AAEH;AACA,6FAA6F;AAC7F,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kFAAkF,cAAc,EAAE;AAClG;AACA,4CAA4C;AAC5C,SAAS;AACT;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,cAAc,EAAE;AACvF;AACA;AACA;AACA;AACA;AACA,mEAAmE,aAAa,EAAE;AAClF,oEAAoE,cAAc,EAAE;AACpF;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0EAA0E;AAC1E;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wHAAwH;AACxH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,yJAAyJ;AACzJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,WAAW;AACX;AACA,WAAW;AACX;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT,uBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,+CAA+C;AAC/C;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA,8CAA8C;AAC9C,GAAG;;AAEH;AACA;AACA;AACA,KAAK;AACL;AACA,gCAAgC;AAChC;AACA,kBAAkB;AAClB;AACA,wBAAwB;AACxB;AACA,oBAAoB;AACpB;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,yBAAyB,iBAAiB;AAC1C;AACA;AACA;AACA,4BAA4B,kDAAkD;AAC9E,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,2BAA2B,iBAAiB;AAC5C;AACA;AACA;AACA;AACA,4BAA4B,aAAa;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,WAAW;AACrC;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,uBAAuB,iBAAiB;AACxC;AACA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,WAAW;AACX,SAAS;AACT,qBAAqB;AACrB;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;AACA;AACA,uBAAuB,iBAAiB;AACxC;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA;AACA,0BAA0B,cAAc;AACxC;AACA;AACA;AACA,0BAA0B,cAAc;AACxC;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA,GAAG;AACH;AACA,uBAAuB,mBAAmB,kDAAkD,SAAS;AACrG,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,OAAO;AACP;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,OAAO;AACP;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,OAAO;AACP;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kCAAkC;AACvD;AACA;AACA;AACA;AACA,oBAAoB,MAAM;AAC1B,mBAAmB,MAAM;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,0BAA0B;AACvC;AACA,sBAAsB,OAAO;AAC7B;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA,yBAAyB,QAAQ;AACjC;AACA,uBAAuB,0BAA0B;AACjD;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,UAAU;AACtB;AACA,YAAY,UAAU;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,wDAAwD;AACxD;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;;AAEA;AACA;AACA,mDAAmD,QAAQ;AAC3D,6DAA6D;AAC7D;AACA;;AAEA;AACA;;AAEA,qDAAqD,QAAQ;AAC7D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;;AAEP;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,0BAA0B;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,uBAAuB,EAAE;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,WAAW,6BAA6B;AACxC;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,eAAe,sBAAsB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,mBAAmB;AAC9B,WAAW,eAAe;AAC1B;AACA,UAAU,SAAS;AACnB;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kCAAkC,8BAA8B;AAChE,oCAAoC,gCAAgC;AACpE,sCAAsC,kCAAkC;AACxE;;;AAGA;AACA,oBAAoB;AACpB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA,0CAA0C,QAAQ;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,qBAAqB,EAAE;AAChD;;AAEA;AACA;AACA;AACA;AACA;AACA,yEAAyE,EAAE;AAC3E;AACA,KAAK;AACL;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,8CAA8C,QAAQ;AACtD;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB,eAAe,QAAQ;AACvB;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,sBAAsB;AACrC;AACA,aAAa,EAAE;AACf,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB,aAAa,UAAU;AACvB,eAAe,QAAQ;AACvB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,iCAAiC;AAC9C,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,iCAAiC;AAC9C,eAAe,QAAQ;AACvB;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA,6DAA6D,EAAE;AAC/D;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,0BAA0B;AAC1B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA;;AAEA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D;AACA;AACA;AACA;AACA,8EAA8E;AAC9E;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,gCAAgC;AACxE;AACA;AACA;AACA,IAAI,4CAA4C;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gDAAgD,+BAA+B;AAC/E,QAAQ,+BAA+B;AACvC,QAAQ,sCAAsC;AAC9C,0DAA0D,+BAA+B;AACzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,2CAA2C;AAClF;AACA;AACA;AACA,eAAe,6BAA6B;AAC5C,0FAA0F,SAAS;AACnG,eAAe,oBAAoB;AACnC;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gCAAgC;AAC9D;AACA,8CAA8C,4CAA4C;AAC1F,kEAAkE,8CAA8C;AAChH;AACA,UAAU,8CAA8C;AACxD;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA,iBAAiB,MAAM,oBAAoB,kCAAkC;AAC7E;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D,qBAAqB;AACrB;AACA,qBAAqB,4CAA4C;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,qBAAqB;AAClD,kCAAkC,mBAAmB;AACrD;AACA;AACA,+GAA+G,kCAAkC;AACjJ;AACA;AACA;AACA;AACA;AACA,8CAA8C,0CAA0C;AACxF;AACA;AACA,iBAAiB,0CAA0C;AAC3D;AACA;AACA,eAAe,gDAAgD;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAY;AACZ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,aAAa,EAAE;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB,oBAAoB;AACrC,aAAa,0CAA0C;AACvD;AACA;AACA,sCAAsC;AACtC;AACA,iBAAiB,gCAAgC;AACjD;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,2DAA2D,qBAAqB;AAC1G;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0CAA0C;AACjE;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+BAA+B;AAChD,wBAAwB;AACxB;AACA,iBAAiB,sCAAsC;AACvD;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,SAAS;;AAET;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW;;AAEX;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAuB,mBAAmB,kCAAkC;AAC7F;AACA,aAAa,0CAA0C;AACvD;AACA;AACA,iBAAiB,8CAA8C;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,oCAAoC;AACpC;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,eAAe;AAC1C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,6BAA6B,qBAAqB;AAClD;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,0CAA0C;AACzE,kCAAkC,yCAAyC;AAC3E,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA,UAAU,4CAA4C;AACtD,UAAU,+CAA+C;AACzD,mCAAmC,0CAA0C;AAC7E,YAAY,8CAA8C;AAC1D;AACA;AACA;AACA,UAAU,0CAA0C;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAY;AACZ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA,0CAA0C,wCAAwC;AAClF;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX,uCAAuC;;AAEvC;AACA;AACA;AACA,kBAAkB,EAAE;AACpB,2DAA2D,EAAE;AAC7D;AACA;;AAEA,SAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA,wCAAwC;AACxC;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,4CAA4C;AACpE;AACA;AACA;AACA;AACA,UAAU,qCAAqC;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,gEAAgE,aAAa;AAC7E;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8CAA8C,0BAA0B,EAAE;AAC1E;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA,gEAAgE,kCAAkC;AAClG;AACA;AACA,iBAAiB,UAAU;AAC3B,mBAAmB,EAAE;AACrB;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,gDAAgD;AAC3E;AACA;AACA;AACA,UAAU,6CAA6C;AACvD;AACA;AACA;AACA;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA,+DAA+D,kCAAkC;AACjG;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA,yBAAyB,8CAA8C;AACvE,OAAO;;AAEP;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,8CAA8C;AACjE,UAAU,oDAAoD;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kCAAkC;AACnD,aAAa,wCAAwC;AACrD;AACA,aAAa,6CAA6C;AAC1D,iBAAiB,uCAAuC;AACxD,+CAA+C,4CAA4C;AAC3F;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA,+DAA+D,kCAAkC;AACjG;AACA;AACA,mBAAmB,EAAE;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA,+DAA+D,kCAAkC;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,sCAAsC;AACvF;AACA;AACA;AACA;AACA;AACA,+BAA+B,MAAM;AACrC;AACA,gCAAgC,MAAM;AACtC;AACA,wBAAwB,OAAO;AAC/B,mCAAmC,UAAU;AAC7C;AACA,kCAAkC,SAAS;AAC3C;AACA,oCAAoC,QAAQ;AAC5C;AACA,iBAAiB,OAAO;AACxB,iBAAiB,yBAAyB;AAC1C,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,8BAA8B;AACnD;AACA;AACA,UAAU,wCAAwC;AAClD;AACA;AACA;AACA;AACA,yCAAyC,wCAAwC;AACjF,mBAAmB,6CAA6C;AAChE;AACA,iBAAiB,OAAO;AACxB,iBAAiB,KAAK;AACtB,kBAAkB,OAAO,oBAAoB,8BAA8B;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wBAAwB;AACnE;AACA;AACA,eAAe;AACf;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;AACA,qDAAqD,YAAY;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;;AAEA;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,8BAA8B;AACnD;AACA;AACA,UAAU,wCAAwC;AAClD;AACA;AACA;AACA,yCAAyC,wCAAwC;AACjF,mBAAmB,6CAA6C;AAChE;AACA,iBAAiB,OAAO;AACxB,iBAAiB,KAAK;AACtB,kBAAkB,OAAO,oBAAoB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,gDAAgD,YAAY;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA;AACA;AACA,2CAA2C,EAAE;AAC7C;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,8EAA8E;AAC9E,4BAA4B;AAC5B,IAAI,wBAAwB;AAC5B,qCAAqC,+BAA+B;AACpE;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,2BAA2B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe,2BAA2B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,EAAE;AAC/D;AACA;AACA;AACA,4CAA4C;AAC5C;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E;AAC9E,6BAA6B;AAC7B;AACA,mDAAmD,mCAAmC;AACtF;AACA;AACA;AACA;AACA;AACA,UAAU,mDAAmD;AAC7D;AACA;AACA;AACA,4BAA4B,mDAAmD;AAC/E;AACA,sBAAsB;AACtB,6CAA6C,MAAM;AACnD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2EAA2E;AAC3E,gBAAgB;AAChB,uEAAuE;AACvE,0FAA0F;AAC1F,IAAI;AACJ;AACA,kFAAkF;AAClF,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA,gBAAgB,+CAA+C;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,MAAM;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA,gBAAgB,+CAA+C;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,MAAM;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kDAAkD,OAAO;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,OAAO;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,mBAAmB;AAC/B;AACA,eAAe,OAAO;AACtB;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE,GAAG,SAAS,EAAE;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8FAA8F,EAAE;AAChG;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,8BAA8B,6CAA6C;AAC3E,sDAAsD;AACtD;AACA,yEAAyE;AACzE,sDAAsD;AACtD;AACA,eAAe,EAAE,8BAA8B;AAC/C;AACA,iBAAiB,EAAE,8CAA8C;AACjE,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8BAA8B,qDAAqD;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE,qCAAqC;AACtD,kCAAkC;AAClC,iBAAiB,EAAE,2CAA2C;AAC9D,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,4FAA4F,EAAE;AAC9F;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA,YAAY;AACZ;AACA;AACA,GAAG;AACH;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,mBAAmB;AACpF;AACA;AACA;AACA,oBAAoB,+CAA+C;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD,mCAAmC,2CAA2C;AAC9E;AACA;AACA;AACA;AACA;AACA,2EAA2E;AAC3E,mCAAmC,qDAAqD;AACxF,gCAAgC;AAChC,IAAI,yCAAyC;AAC7C;AACA,mBAAmB,yCAAyC,OAAO;AACnE,4DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA,6BAA6B,0CAA0C;AACvE,iCAAiC,iCAAiC;AAClE;AACA;AACA,uCAAuC;AACvC,8BAA8B;AAC9B,8BAA8B;AAC9B,QAAQ,KAAK,yCAAyC;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yCAAyC;AACrD;AACA,iBAAiB,mCAAmC;AACpD;AACA;AACA,sEAAsE;AACtE,2DAA2D,MAAM;AACjE,2DAA2D;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF,yCAAyC,sFAAsF,2BAA2B;AAChP;AACA;AACA;AACA;AACA;AACA,0BAA0B,wEAAwE,EAAE,6DAA6D;AACjK;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,mDAAmD;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAkB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,sBAAsB;AAC9D;AACA,YAAY;AACZ;AACA,0DAA0D;AAC1D,mCAAmC;AACnC,UAAU;AACV;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,MAAM;AACN,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,wDAAwD;AACxD,iCAAiC;AACjC,QAAQ;AACR,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,+CAA+C,mCAAmC;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4DAA4D,cAAc;AAC1E;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAyB,kCAAkC,iCAAiC;AAC5F,wBAAwB;AACxB,0CAA0C;AAC1C;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB,qDAAqD;AAC1E;AACA;AACA;AACA,6CAA6C,mBAAmB;AAChE;AACA;AACA,eAAe,OAAO;AACtB;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE,kCAAkC;AACrD,sCAAsC;AACtC;AACA,4BAA4B,mCAAmC;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE,kCAAkC;AACrD,qCAAqC;AACrC;AACA,4BAA4B,mCAAmC;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE,kCAAkC;AACrD,6CAA6C;AAC7C;AACA,qBAAqB,mCAAmC;AACxD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE,kCAAkC;AACrD,oCAAoC;AACpC;AACA,4BAA4B,mCAAmC;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB,2DAA2D;AAChF,8BAA8B,qCAAqC;AACnE;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE,qCAAqC;AACtD;AACA,iBAAiB,EAAE;AACnB,qBAAqB,qCAAqC;AAC1D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,eAAe,OAAO;AACtB,iBAAiB,0BAA0B;AAC3C;AACA,0BAA0B,OAAO;AACjC;AACA,yBAAyB,QAAQ;AACjC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE,sDAAsD;AACtD,qCAAqC;AACrC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,YAAY;AAC5D;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,sCAAsC,YAAY;AAClD;AACA;AACA,UAAU,uBAAuB;AACjC;AACA;AACA,aAAa,QAAQ,0BAA0B,YAAY;AAC3D,eAAe,YAAY,cAAc,YAAY;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,2CAA2C;AACxE;AACA,aAAa,0BAA0B;AACvC,aAAa,SAAS;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA,2CAA2C,EAAE,gBAAgB,EAAE,EAAE,EAAE;AACnE;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uEAAuE;AACvE;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,6CAA6C;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,yCAAyC;AACvE;AACA;AACA;AACA;AACA;AACA,gBAAgB,YAAY;AAC5B,gBAAgB,QAAQ;AACxB,gBAAgB,SAAS;AACzB,uCAAuC,wCAAwC;AAC/E,gBAAgB,MAAM;AACtB,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,cAAc;AACzB;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,6CAA6C;AAC7C;;AAEA,iBAAiB,wBAAwB;AACzC;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,iBAAiB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,IAAI,2BAA2B;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,WAAW,OAAO;AAClB,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA,cAAc,gBAAgB;AAC9B,cAAc,gBAAgB;AAC9B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,cAAc;AAC3B;AACA;AACA;AACA,sDAAsD,iBAAiB;AACvE;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA,WAAW,yBAAyB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,oBAAoB;AACrD;AACA,gEAAgE,UAAU;AAC1E;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,SAAS,OAAO,4BAA4B,+BAA+B,aAAa;AACxF,gCAAgC,UAAU;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,sCAAsC;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,yCAAyC;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA,iCAAiC,8BAA8B;AAC/D,iCAAiC,kCAAkC;AACnE,iCAAiC,8BAA8B;AAC/D,iCAAiC,8BAA8B;AAC/D,iCAAiC,+BAA+B;AAChE,iCAAiC,kCAAkC;;AAEnE;AACA;AACA;AACA;AACA,iBAAiB,aAAa;AAC9B,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,gBAAgB;AACjC,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,0EAA0E,EAAE;AAC5E;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,oEAAoE,mBAAmB;AACvF,yEAAyE,0BAA0B;AACnG,8DAA8D,4BAA4B;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,cAAc;AACzB,WAAW,iBAAiB;AAC5B;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,yDAAyD,cAAc;AACvE,+BAA+B,gBAAgB;AAC/C,kCAAkC,iBAAiB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA,aAAa,gCAAgC,OAAO;;AAEpD;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,YAAY;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qDAAqD;AACrD;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,2BAA2B,mBAAmB;AAC9C;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,qBAAqB,aAAa;AAClC;;AAEA;AACA;AACA,uBAAuB,aAAa;AACpC;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA,UAAU,yCAAyC;;;AAGnD;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB,YAAY,OAAO;AACnB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gDAAgD,qBAAqB,EAAE;;AAEvE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,iDAAiD;;AAEjD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qBAAqB;AAChC;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA,+BAA+B,+BAA+B;AAC9D,mBAAmB,+BAA+B;AAClD,+BAA+B,8CAA8C;AAC7E,kBAAkB,8CAA8C;AAChE,+BAA+B,2CAA2C;AAC1E,kBAAkB,6CAA6C;AAC/D,+BAA+B,8CAA8C;AAC7E,kBAAkB,gDAAgD;AAClE;AACA;AACA;AACA;AACA,sCAAsC,IAAI,IAAI,EAAE,IAAI,EAAE;AACtD;AACA,oCAAoC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE;AAC/D;AACA,wCAAwC,IAAI,IAAI,EAAE;AAClD;AACA,yCAAyC,IAAI,IAAI,EAAE;AACnD,QAAQ;AACR;AACA;AACA;AACA;AACA;;;AAGA,4BAA4B,EAAE;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E,OAAO;AACtF;AACA;AACA,WAAW,EAAE;AACb,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,mCAAmC,EAAE,eAAe,UAAU;AAC9D,kCAAkC,EAAE,eAAe,YAAY;AAC/D;AACA;AACA;AACA,wEAAwE,IAAI,EAAE,mBAAmB;AACjG,uEAAuE,IAAI,EAAE,mBAAmB;AAChG,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC,WAAW,cAAc;AACzB;AACA;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA,aAAa,aAAa;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA,8BAA8B,8BAA8B;AAC5D;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA,8BAA8B,iCAAiC;AAC/D;AACA,oBAAoB,YAAY;AAChC;AACA;AACA,kCAAkC,wCAAwC;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU,GAAG,UAAU;AAC1C,MAAM,UAAU,GAAG,UAAU;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E,aAAa;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,oCAAoC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B,WAAW,2CAA2C;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,YAAY;AACvB;AACA;AACA,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA,4CAA4C,wBAAwB;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,mBAAmB,cAAc;AACjC,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc;AACd;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,eAAe,aAAa,SAAS;AAC/D;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA,oFAAoF,iBAAiB;AACrG;AACA;AACA;AACA,qFAAqF,iBAAiB;AACtG;AACA;AACA;AACA,mFAAmF,iBAAiB;AACpG;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,mBAAmB,cAAc;AACjC,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc;AACd;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B;AAC1B;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,eAAe,aAAa,SAAS;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oFAAoF,iBAAiB;AACrG;AACA;AACA;AACA,qFAAqF,iBAAiB;AACtG;AACA;AACA;AACA,mFAAmF,iBAAiB;AACpG;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,mBAAmB,cAAc;AACjC,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc,4CAA4C;AAC1D,cAAc;AACd;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B;AAC1B;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,aAAa;AAClC,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,aAAa;AAClC,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,oCAAoC;AAClD,cAAc,oCAAoC;AAClD,cAAc,oCAAoC;AAClD,cAAc,oCAAoC;AAClD,cAAc;AACd;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,yEAAyE,EAAE;AAC3E;;AAEA,kCAAkC,iCAAiC;AACnE,qCAAqC,uBAAuB;;AAE5D;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8CAA8C,mBAAmB,EAAE;;AAEnE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,2CAA2C;AAChE;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA,6CAA6C,QAAQ;AACrD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,mBAAmB;AACtD;AACA;AACA;AACA,cAAc;AACd,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,YAAY;AACZ;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,yBAAyB;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,MAAM;AACtC;AACA,0CAA0C,MAAM;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,MAAM;AACnD;AACA;AACA;AACA;AACA,gDAAgD,MAAM;AACtD;AACA;AACA;AACA,WAAW,SAAS,0CAA0C;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,OAAO;AAC1C;AACA;AACA,kCAAkC,OAAO;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb,WAAW;AACX,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,WAAW;AACX,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,MAAM;AACtC;AACA,WAAW,MAAM;AACjB,MAAM,MAAM;AACZ;AACA;AACA;AACA,8CAA8C,MAAM;AACpD;AACA;AACA;AACA;AACA,iDAAiD,MAAM;AACvD;AACA;AACA;AACA,WAAW,SAAS,yCAAyC;AAC7D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,MAAM;AACtC;AACA,WAAW,MAAM;AACjB,MAAM,MAAM;AACZ;AACA;AACA;AACA,iDAAiD,MAAM;AACvD;AACA;AACA;AACA;AACA,oDAAoD,MAAM;AAC1D;AACA;AACA;AACA,WAAW,SAAS,4CAA4C;AAChE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,kCAAkC;AACtC;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,WAAW,WAAW,oBAAoB,kCAAkC;AAC5E;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,wBAAwB;AACtF;AACA;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,WAAW,WAAW,mBAAmB,kCAAkC;AAC3E;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,WAAW,WAAW,oBAAoB,kCAAkC;AAC5E;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,WAAW,WAAW,oBAAoB,kCAAkC;AAC5E;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,8CAA8C;AACrE;AACA;AACA;AACA;AACA,uBAAuB,gBAAgB,MAAM,gBAAgB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,WAAW,WAAW,gBAAgB,kCAAkC;AACxE;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA,cAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,6BAA6B;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA,aAAa,OAAO,mCAAmC,0BAA0B;AACjF,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,aAAa,OAAO,mCAAmC,0BAA0B;AACjF,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,+BAA+B;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,yCAAyC;AAC7C;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,yBAAyB,mCAAmC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C,MAAM,mCAAmC;AACzC;AACA;AACA,oEAAoE;AACpE,OAAO,mCAAmC;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC,uCAAuC,qBAAqB;AAC5D,uCAAuC,qBAAqB;AAC5D,iCAAiC,eAAe;AAChD,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,eAAe;AACf;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA,+CAA+C;AAC/C,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B,GAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,MAAM,OAAO,KAAK,4BAA4B,EAAE,gCAAgC,EAAE,+BAA+B,KAAK,yCAAyC,KAAK;AAC9L;AACA,wBAAwB,GAAG,MAAM,EAAE,MAAM,EAAE;AAC3C,iCAAiC,GAAG,6CAA6C,IAAI;AACrF,wBAAwB,GAAG;AAC3B,yBAAyB,GAAG;AAC5B,iDAAiD,IAAI;;AAErD;AACA;AACA;AACA;AACA,CAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ,+DAA+D;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,cAAc;AACxC,yCAAyC,qBAAqB;AAC9D,yCAAyC,qBAAqB;AAC9D,mCAAmC,eAAe;AAClD,4CAA4C,0BAA0B;AACtE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,iDAAiD;AACzD;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,uBAAuB,6BAA6B;AACpD;AACA,eAAe,QAAQ;AACvB;AACA,uBAAuB,6BAA6B;AACpD;AACA,eAAe,eAAe;AAC9B;AACA,eAAe,eAAe;AAC9B;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,oCAAoC;AAC7D,uCAAuC,qBAAqB;AAC5D,uCAAuC,qBAAqB;AAC5D,iCAAiC,eAAe;AAChD,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,uEAAuE;AACvE,qCAAqC;AACrC,4DAA4D,iDAAiD,EAAE,EAAE;AACjH;AACA;;AAEA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,iDAAiD;AACxD;AACA,cAAc,OAAO;AACrB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA,4CAA4C,+CAA+C;AAC3F;AACA,cAAc,QAAQ;AACtB;AACA,4CAA4C,+CAA+C;AAC3F;AACA,cAAc,eAAe;AAC7B;AACA,cAAc,eAAe;AAC7B;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,6CAA6C;AACnE,oCAAoC,qBAAqB;AACzD,oCAAoC,qBAAqB;AACzD,8BAA8B,eAAe;AAC7C,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,mCAAmC;AACnC,0DAA0D,iDAAiD,EAAE,EAAE;AAC/G;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iDAAiD;AACvD;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,+BAA+B,2BAA2B;AAC1D;AACA,aAAa,QAAQ;AACrB;AACA,+BAA+B,2BAA2B;AAC1D;AACA,aAAa,eAAe;AAC5B;AACA,aAAa,eAAe;AAC5B;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,kCAAkC;AACxD,oCAAoC,qBAAqB;AACzD,oCAAoC,qBAAqB;AACzD,8BAA8B,eAAe;AAC7C,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,mCAAmC;AACnC,0DAA0D,iDAAiD,EAAE,EAAE;AAC/G;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,iDAAiD;AACxD;AACA,cAAc,OAAO;AACrB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA,gCAAgC,2BAA2B;AAC3D;AACA,cAAc,QAAQ;AACtB;AACA,gCAAgC,2BAA2B;AAC3D;AACA,cAAc,eAAe;AAC7B;AACA,cAAc,eAAe;AAC7B;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,kCAAkC;AACxD,oCAAoC,qBAAqB;AACzD,oCAAoC,qBAAqB;AACzD,8BAA8B,eAAe;AAC7C,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,mCAAmC;AACnC,0DAA0D,iDAAiD,EAAE,EAAE;AAC/G;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iDAAiD;AACvD;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,+BAA+B,2BAA2B;AAC1D;AACA,aAAa,QAAQ;AACrB;AACA,+BAA+B,2BAA2B;AAC1D;AACA,aAAa,eAAe;AAC5B;AACA,aAAa,eAAe;AAC5B;;AAEA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,iCAAiC;AACtD,mCAAmC,qBAAqB;AACxD,mCAAmC,qBAAqB;AACxD,6BAA6B,eAAe;AAC5C,sCAAsC,0BAA0B;AAChE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE,mCAAmC;AACnC,0DAA0D,iDAAiD,EAAE,EAAE;AAC/G;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,mDAAmD;AACxG;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ,+DAA+D;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,eAAe;AACxC,uCAAuC,qBAAqB;AAC5D,uCAAuC,qBAAqB;AAC5D,iCAAiC,eAAe;AAChD,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,8BAA8B;AACrE;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ,+DAA+D;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,UAAU;AAClC,uCAAuC,qBAAqB;AAC5D,uCAAuC,qBAAqB;AAC5D,iCAAiC,eAAe;AAChD,0CAA0C,0BAA0B;AACpE,qCAAqC,qBAAqB;AAC1D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA,WAAW;AACX;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,8BAA8B;AAChG;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,aAAa,QAAQ,+DAA+D;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,YAAY;AACtC,yCAAyC,qBAAqB;AAC9D,yCAAyC,qBAAqB;AAC9D,mCAAmC,eAAe;AAClD,4CAA4C,0BAA0B;AACtE,yCAAyC,uBAAuB;AAChE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;;AAEA;AACA,WAAW;AACX;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,mBAAmB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,QAAQ;AACrB;AACA,aAAa,YAAY;AACzB;AACA,oCAAoC,uCAAuC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;;AAEA,qFAAqF,KAAK,UAAU,KAAK;AACzG;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC,0CAA0C,qBAAqB;AAC/D,0CAA0C,qBAAqB;AAC/D;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC,0CAA0C,qBAAqB;AAC/D,0CAA0C,qBAAqB;AAC/D;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,aAAa,YAAY;AACzB,aAAa,YAAY;AACzB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,sBAAsB;AAChD,0BAA0B,sBAAsB;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;AACL;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,mDAAmD,EAAE;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,kDAAkD,EAAE;AACpD;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,mCAAmC,aAAa,EAAE;AAClD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,mCAAmC,aAAa,EAAE;AAClD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,2EAA2E,EAAE;AAC7E,sCAAsC,EAAE;AACxC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;AACH;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,uCAAuC;AAC3C;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ,+DAA+D;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,wBAAwB;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ,+DAA+D;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,MAAM;AAC5B,wCAAwC,wBAAwB;AAChE,wCAAwC,wBAAwB;AAChE,wCAAwC,wBAAwB;AAChE,wCAAwC,wBAAwB;AAChE,+BAA+B,eAAe;AAC9C,wCAAwC,0BAA0B;AAClE,yCAAyC,2BAA2B;AACpE,yCAAyC,2BAA2B;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,gCAAgC;AAC7E;AACA;AACA,SAAS;;AAET;AACA;AACA;;AAEA,6CAA6C,iBAAiB;AAC9D;AACA;AACA,SAAS;;AAET;AACA;AACA;;AAEA,6CAA6C,yBAAyB;AACtE;AACA;AACA,SAAS;;AAET;AACA;AACA;;AAEA,6CAA6C,eAAe;AAC5D;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;;AAEA,6CAA6C,eAAe;AAC5D;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;;;AAID;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,kCAAkC;AAC3D,8CAA8C,wBAAwB;AACtE,IAAI,sBAAsB;AAC1B,0CAA0C,0BAA0B;AACpE;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B,aAAa;AACb;AACA;AACA;AACA,oDAAoD,MAAM;AAC1D,gBAAgB;AAChB;AACA;AACA;AACA,2BAA2B,MAAM;AACjC;AACA;AACA,2BAA2B,aAAa;AACxC;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,cAAc;AACpB;AACA,kDAAkD,cAAc;AAChE;AACA;AACA;AACA;AACA,IAAI,mCAAmC;AACvC;AACA;AACA;AACA,WAAW,WAAW,SAAS,kCAAkC;AACjE;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,KAAK;AACtE;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,gCAAgC;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,iCAAiC,YAAY,GAAG,MAAM;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,qCAAqC;AAChG,mGAAmG;AACnG,cAAc,uEAAuE;AACrF;AACA;AACA;AACA,oCAAoC,2CAA2C;AAC/E,UAAU,6EAA6E;AACvF;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,aAAa,kCAAkC;AACrE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,WAAW,kCAAkC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,uBAAuB,WAAW;AAClC,yBAAyB,SAAS;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;AACA,mBAAmB,oBAAoB;AACvC;AACA,qBAAqB,oBAAoB;AACzC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA,8BAA8B,wBAAwB,EAAE;AACxD;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,wCAAwC;AAC/D;AACA,QAAQ,4CAA4C;AACpD;AACA;AACA;AACA;AACA,MAAM,oCAAoC;AAC1C,MAAM,0CAA0C;AAChD;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,qDAAqD;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gBAAgB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;;AAER;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;;;AAGA;AACA;AACA;AACA;AACA,wCAAwC,0CAA0C;AAClF,IAAI,gDAAgD;AACpD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,mCAAmC;AACvC;AACA;AACA;AACA,IAAI,qCAAqC;AACzC;AACA;AACA,WAAW,WAAW,aAAa,kCAAkC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,mCAAmC;AACvC;AACA;AACA;AACA,IAAI,qCAAqC;AACzC;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM,OAAO,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,+BAA+B;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,WAAW;AAClD,+CAA+C,WAAW;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA,4EAA4E;AAC5E;AACA;AACA;AACA,YAAY,4BAA4B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,IAAI,iDAAiD,QAAQ;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,gFAAgF;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qFAAqF,QAAQ;AAC7F;AACA;AACA;AACA,kFAAkF,QAAQ;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,6CAA6C;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,QAAQ;AAChE;AACA;AACA;AACA,iFAAiF,QAAQ;AACzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,mCAAmC;AAC7C,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,2CAA2C;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,aAAa;AAClF;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,cAAc,MAAM,aAAa;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,aAAa;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;;AAEA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC,mBAAmB;AACnB;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa;AACb;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE,YAAY,qEAAqE;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,cAAc;AACzC;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,aAAa,kCAAkC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE,gBAAgB,qEAAqE;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,YAAY,kCAAkC;AACpE,cAAc,qEAAqE;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE,gBAAgB,qEAAqE;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,eAAe,kCAAkC;AACvE,iBAAiB,qEAAqE;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,eAAe,kCAAkC;AACvE,iBAAiB,qEAAqE;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE,gBAAgB,qEAAqE;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,YAAY,kCAAkC;AACpE;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA,8EAA8E;;AAE9E;AACA;AACA,2BAA2B,iBAAiB;AAC5C,0BAA0B,gBAAgB;AAC1C;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,aAAa,kCAAkC;AACrE,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,WAAW,kCAAkC;AACnE,KAAK,qEAAqE;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA,oBAAoB,MAAM;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE,YAAY,qEAAqE;AACjF;AACA;AACA,QAAQ;AACR;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,SAAS,kCAAkC;AACjE,WAAW,qEAAqE;AAChF;AACA;AACA,QAAQ;AACR;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,SAAS,kCAAkC;AACjE,WAAW,qEAAqE;AAChF;AACA;AACA;AACA;AACA,yDAAyD;AACzD,gBAAgB;AAChB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,QAAQ,kCAAkC;AAChE,UAAU,qEAAqE;AAC/E;AACA;AACA;AACA;AACA,kDAAkD;AAClD,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,UAAU,kCAAkC;AAClE,YAAY,qEAAqE;AACjF;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,WAAW;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC;AACA;AACA;AACA;AACA,WAAW,WAAW,cAAc,kCAAkC;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD,8BAA8B;AAC9B,mBAAmB,kEAAkE;AACrF,IAAI,wCAAwC,wCAAwC;AACpF,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA,yCAAyC,4CAA4C;AACrF;AACA;AACA,WAAW,QAAQ,6CAA6C;AAChE,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,cAAc;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,+CAA+C;AAC7D,cAAc,+CAA+C;AAC7D;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;;AAEf;AACA;;AAEA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,WAAW;AACX;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,GAAG,8BAA8B;AAC5C;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,uCAAuC,4BAA4B;AACvE,mEAAmE;AACnE;AACA;AACA;AACA;AACA,8DAA8D,0BAA0B;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW,SAAS,kCAAkC;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,6CAA6C,YAAY,MAAM,YAAY,OAAO,QAAQ;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AACpE,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,OAAO;AAC7B,yCAAyC,0BAA0B;AACnE,yCAAyC,0BAA0B;AACnE,8BAA8B,eAAe;AAC7C,uCAAuC,0BAA0B;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C,aAAa,eAAe;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,cAAc,EAAE;AAChB,gBAAgB,8CAA8C;AAC9D;AACA;AACA,cAAc,EAAE;AAChB;AACA,cAAc,iBAAiB;AAC/B,0DAA0D;AAC1D,iBAAiB;AACjB,SAAS,gEAAgE;AACzE;;AAEA;AACA;AACA,KAAK,0DAA0D;;AAE/D,8CAA8C;AAC9C,iBAAiB;;AAEjB;AACA,QAAQ,0DAA0D;AAClE,uCAAuC;AACvC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc,iBAAiB;AAC/B;AACA;;AAEA,+CAA+C;AAC/C,kBAAkB;;AAElB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,0BAA0B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,0BAA0B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,cAAc,iBAAiB;AAC/B;AACA;AACA;AACA,cAAc,OAAO;AACrB,cAAc,OAAO;AACrB;AACA,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,QAAQ;AACtB,cAAc,OAAO;AACrB;AACA;AACA;AACA,6CAA6C,wBAAwB;AACrE;AACA;AACA;AACA;AACA;AACA,6CAA6C,oBAAoB;AACjE,2CAA2C;AAC3C,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,2BAA2B,+BAA+B;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;;AAEnC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe;AACf,qBAAqB;;AAErB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB,sBAAsB;AACtB,4BAA4B;AAC5B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,eAAe;AACpD,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL,sDAAsD,EAAE,gCAAgC,EAAE;AAC1F;AACA;AACA,GAAG;;;AAGH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,mBAAmB;AACrE;AACA;AACA;AACA;AACA,0BAA0B,gBAAgB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,gBAAgB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,mDAAmD;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E,EAAE;AAC9E;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,OAAO;AACP;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;AACA,qBAAqB,0BAA0B;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gFAAgF;AAChF,qEAAqE;AACrE,iEAAiE;AACjE;AACA;AACA;AACA,2DAA2D,qBAAqB;AAChF;AACA;AACA;AACA;AACA;AACA,kBAAkB,iDAAiD;AACnE;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,qBAAqB;AAC/B;AACA;AACA,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA,2CAA2C,qCAAqC;AAChF,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,kDAAkD;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,6BAA6B;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,SAAS;AACT,OAAO;AACP,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yCAAyC;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,qBAAqB;AAC5E,uEAAuE,qBAAqB;AAC5F;AACA,IAAI,mDAAmD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,qBAAqB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA,WAAW;AACX,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,2CAA2C,qBAAqB;AAChE;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,aAAa,OAAO;AACpB,cAAc,aAAa;AAC3B;AACA;AACA;;AAEA;AACA,uBAAuB;;AAEvB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA,yDAAyD,cAAc;AACvE,mFAAmF;AACnF;AACA;AACA;AACA;AACA,yDAAyD,gBAAgB;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,oCAAoC;AAC/D,8BAA8B,6CAA6C;AAC3E,iCAAiC,gDAAgD;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,oCAAoC;AAC/D,8BAA8B,oCAAoC;AAClE,iCAAiC,uCAAuC;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA,uBAAuB,mDAAmD;AAC1E;AACA;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,mBAAmB;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,iBAAiB;AACtD,oEAAoE;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,qBAAqB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO,qCAAqC,cAAc;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,gCAAgC;AAC9C;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF;AACtF;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,wCAAwC,OAAO;AAC/C;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,0CAA0C,iCAAiC;;AAE3E;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,qCAAqC;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,IAAI;AACJ;AACA;AACA,eAAe;AACf,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,yBAAyB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ;AACnB,IAAI,6EAA6E;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,2BAA2B;AAC1C,eAAe,+CAA+C;AAC9D,eAAe,yBAAyB;AACxC,eAAe,6CAA6C;AAC5D,eAAe;AACf;AACA,8CAA8C;AAC9C,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;AAIA,8CAA8C,qCAAqC;AACnF;AACA;AACA,gCAAgC,EAAE,uBAAuB;AACzD,6CAA6C;AAC7C,0BAA0B,gCAAgC;AAC1D;AACA;AACA;AACA;AACA;AACA,uCAAuC,uBAAuB;AAC9D;AACA;AACA,uCAAuC,uBAAuB;AAC9D;AACA;AACA,uCAAuC,uBAAuB;AAC9D,UAAU;AACV;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB,EAAE,cAAc,EAAE;AACvC;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uDAAuD,iCAAiC,EAAE;AAC1F,8DAA8D,uBAAuB;AACrF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,2BAA2B,4BAA4B;AACvD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,2BAA2B,4BAA4B;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,gFAAgF,QAAQ;AACxF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,WAAW;;AAEX;AACA;AACA,aAAa;AACb;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,wBAAwB,0DAA0D,EAAE;AACpF,wBAAwB,uBAAuB;AAC/C;AACA;;AAEA,OAAO;;AAEP;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,WAAW;AACX;AACA,WAAW;;AAEX;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe;AACf;AACA;;AAEA,SAAS;AACT;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,gDAAgD,QAAQ;AACxD;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,WAAW;;AAEX;AACA;AACA;AACA,SAAS;;AAET;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,8BAA8B;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE;AACpE,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA,oCAAoC,sBAAsB;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C,6EAA6E;AAC7E,4BAA4B,aAAa,+BAA+B;AACxE,+BAA+B,kBAAkB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,gCAAgC,SAAS;AACzC,gCAAgC,SAAS,OAAO,SAAS;AACzD,kCAAkC,SAAS,IAAI,SAAS;AACxD,oCAAoC,SAAS,IAAI,SAAS,OAAO,4BAA4B;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA,2CAA2C,sBAAsB;AACjE;;AAEA;AACA;AACA;AACA,+BAA+B;AAC/B,uCAAuC,SAAS;AAChD,uCAAuC,SAAS,OAAO,SAAS;AAChE,yCAAyC,SAAS,IAAI,SAAS;AAC/D,2CAA2C,SAAS,IAAI,SAAS,OAAO,4BAA4B;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;AACA,qFAAqF;AACrF;AACA,4CAA4C;AAC5C,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA,OAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,aAAa;AAC/B,kBAAkB,cAAc;AAChC,kBAAkB,cAAc;AAChC,kBAAkB,cAAc;AAChC,kBAAkB,cAAc;AAChC,kBAAkB,cAAc;AAChC;AACA;AACA,6DAA6D,mCAAmC;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,yBAAyB,MAAM,uBAAuB;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yDAAyD;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,0DAA0D;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,cAAc;AACd;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC,MAAM,6BAA6B;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kBAAkB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,uBAAuB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,gBAAgB;AACjC;AACA;AACA;AACA,eAAe,YAAY,IAAI,aAAa,UAAU,YAAY;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,qCAAqC;AAChD,WAAW,sCAAsC;AACjD,WAAW,kCAAkC;AAC7C,WAAW,mCAAmC;AAC9C,WAAW,mCAAmC;AAC9C,WAAW,uCAAuC;AAClD,WAAW,oCAAoC;AAC/C,WAAW,qCAAqC;AAChD,WAAW;AACX;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,2HAA2H,EAAE;AAC7H;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,wJAAwJ,EAAE;AAC1J;AACA;AACA;AACA;;AAEA;AACA;AACA,mDAAmD,EAAE;AACrD;AACA;;AAEA;AACA,0BAA0B;;AAE1B;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,yBAAyB,0BAA0B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,eAAe;AACf;AACA,4HAA4H,EAAE,kBAAkB,EAAE,oBAAoB,EAAE;AACxK;AACA,aAAa;AACb;AACA,uCAAuC;AACvC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+DAA+D,gBAAgB;AAC/E;AACA;AACA;AACA;AACA;;AAEA;AACA,yBAAyB,0BAA0B;AACnD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,eAAe;;AAEf;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,+BAA+B;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,2DAA2D;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,iEAAiE;AAC1E;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,+CAA+C;AAC/C,+BAA+B;AAC/B,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iCAAiC;AACvC,MAAM,uCAAuC;AAC7C;AACA;AACA,WAAW,WAAW,gBAAgB,kCAAkC;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,CAAC;;;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,+BAA+B;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,2DAA2D;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,iEAAiE;AAC1E;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,+CAA+C;AAC/C,+BAA+B;AAC/B,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iCAAiC;AACvC,MAAM,uCAAuC;AAC7C;AACA;AACA;AACA,WAAW,WAAW,gBAAgB,kCAAkC;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,wCAAwC;AAC/D;AACA,QAAQ,4CAA4C;AACpD;AACA;AACA,WAAW,WAAW;AACtB;AACA,IAAI,kCAAkC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,YAAY;AAC9E,uEAAuE,0BAA0B;AACjG,+DAA+D;AAC/D;AACA;AACA,uBAAuB,SAAS;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,yBAAyB;AACxE;AACA;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,WAAW;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,+CAA+C,QAAQ;AACvD;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;;AAE3B;AACA;AACA,aAAa;AACb,WAAW;AACX;AACA,OAAO;AACP;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,uCAAuC,qCAAqC;AAC5E;;AAEA;AACA;AACA,uCAAuC,4CAA4C;AACnF,KAAK;AACL;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,4CAA4C;AACtE;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,YAAY;AACnC,8DAA8D;AAC9D,kEAAkE,OAAO;AACzE;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,wBAAwB,OAAO,UAAU,MAAM;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D;AAC3D;AACA,qDAAqD;AACrD;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,MAAM,IAAI,OAAO;AACrD,0BAA0B,MAAM;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,2DAA2D;AAC3D;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,EAAE;AACvB;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,yCAAyC;AAC3F,4BAA4B,yCAAyC;AACrE,IAAI,wCAAwC,MAAM,iCAAiC;AACnF;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC;;AAED;;AAEA,6BAA6B;;AAE7B;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,2BAA2B;;AAE3B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;;AAGA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;;;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,wBAAwB;AACzE;AACA,8EAA8E,yBAAyB;AACvG,IAAI,4BAA4B;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,+BAA+B;AACzC,OAAO,wEAAwE;AAC/E,UAAU,2BAA2B;AACrC,qBAAqB,+EAA+E;AACpG;AACA,OAAO,4FAA4F;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E;AAC5E,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB,uCAAuC,4BAA4B;AACnE,WAAW,QAAQ;AACnB,IAAI,6EAA6E;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,cAAc;AACxC;AACA;AACA;AACA,4BAA4B,mBAAmB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,qBAAqB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE,WAAW,IAAI,aAAa;AAClG;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,0BAA0B;AACtC,YAAY,0BAA0B;AACtC,YAAY;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uFAAuF,aAAa;AACpG;AACA;AACA;AACA,oBAAoB,mBAAmB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,0BAA0B;AACtC,YAAY,6BAA6B;AACzC,YAAY,0BAA0B;AACtC,YAAY,QAAQ,cAAc,iBAAiB;AACnD,YAAY;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,wCAAwC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,0BAA0B;AACtC,YAAY,0BAA0B;AACtC,YAAY;AACZ;AACA,0BAA0B,0BAA0B;AACpD;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,+BAA+B;AAC/B,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;;AAEP;AACA,wCAAwC;AACxC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,WAAW;AACX;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;;AAEnD;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,wDAAwD,KAAK,wBAAwB;AACtH,8BAA8B,oBAAoB,MAAM,sBAAsB;AAC9E;AACA;AACA;AACA;AACA,wDAAwD;AACxD;AACA;AACA;AACA,YAAY,sEAAsE;AAClF,IAAI,gEAAgE;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,4BAA4B;AACrE,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;;AAE3B;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,wDAAwD,KAAK,wBAAwB;AACpH,yCAAyC,oBAAoB;AAC7D;AACA,sDAAsD;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,mBAAmB;AACrD,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,uBAAuB,EAAE,yBAAyB,EAAE,YAAY,EAAE;AAClE;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,wDAAwD,KAAK,wBAAwB;AACxH,yCAAyC,oBAAoB;AAC7D;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,mBAAmB;AACrD,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,wDAAwD,KAAK,wBAAwB;AACxH,yCAAyC,oBAAoB;AAC7D;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,mBAAmB;AACrD,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,2CAA2C,gBAAgB,mCAAmC,4BAA4B,+BAA+B,GAAG;AAC5J,CAAC;AACD,CAAC;;AAED;AACA;AACA,GAAG;;AAEH,CAAC;;AAED,gIAAgI,0GAA0G,yBAAyB,UAAU,eAAe,iBAAiB,mBAAmB,WAAW,mBAAmB,W;;;;;;AChkhC9V,gJAAgJ,grBAAgrB,iBAAiB,gWAAgW,6BAA6B,8lDAA8lD,kL;;;;;;ACA5yF,gJAAgJ,25BAA25B,cAAc,sHAAsH,QAAQ,2BAA2B,uBAAuB,uBAAuB,qBAAqB,qNAAqN,qBAAqB,uDAAuD,kCAAkC,sCAAsC,uBAAuB,sCAAsC,uBAAuB,weAAwe,UAAU,uBAAuB,YAAY,+BAA+B,oCAAoC,0GAA0G,OAAO,4O;;;;;;sDCA35E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2CAA2C;AAC3C;AACA,2DAA2D;;AAE3D;AACA,+CAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;;AAEA;AACA;AACA;AACA;;AAEA;AACA,yBAAyB;AACzB,yBAAyB;AACzB;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,0BAA0B,MAAM,aAAa,OAAO;;AAEpD;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,EAAE;AACnD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,2CAA2C,GAAG;;AAE9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe;AACf,cAAc;AACd,cAAc;AACd,gBAAgB;AAChB,eAAe;AACf;;AAEA;AACA;AACA,UAAU;AACV,SAAS;AACT,SAAS;AACT,WAAW;AACX,UAAU;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,EAAE;AACf,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,aAAa,EAAE;AACf,aAAa,MAAM;AACnB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,aAAa,SAAS;AACtB,aAAa,OAAO;AACpB,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,SAAS;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,MAAM;AACnB,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,aAAa,EAAE;AACf,aAAa,QAAQ;AACrB;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,aAAa,EAAE;AACf,aAAa,QAAQ;AACrB;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa,SAAS;AACtB,aAAa,SAAS;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,OAAO;AACpB,aAAa,SAAS;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,aAAa;AAC1B,aAAa,SAAS;AACtB,aAAa,EAAE;AACf,aAAa,QAAQ;AACrB;AACA,aAAa,SAAS;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,SAAS;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,SAAS;AACtB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,MAAM;AACnB,eAAe,OAAO;AACtB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,OAAO;AACpB,eAAe,EAAE;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,aAAa,SAAS;AACtB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB,aAAa,EAAE;AACf,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,OAAO;AACpB,eAAe,SAAS;AACxB;AACA;AACA,cAAc,2BAA2B;AACzC;AACA;AACA,mBAAmB,gCAAgC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,6BAA6B;AAC9D;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW;AACX;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA,oCAAoC,6BAA6B,EAAE;AACnE;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,aAAa;AAC9B;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,aAAa;AAC9B;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,EAAE;AACnB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,6BAA6B;AAC5C,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT,gBAAgB;AAChB,OAAO;;AAEP;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qEAAqE;AACrE;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,aAAa;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,YAAY;AAC3B,iBAAiB,YAAY;AAC7B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,mBAAmB;AAClC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,gBAAgB,QAAQ;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,gBAAgB,QAAQ;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,eAAe,OAAO,WAAW;AACjC,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,4BAA4B;;AAE5B;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO,WAAW;AACjC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO,WAAW;AACjC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,+CAA+C;AACpF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,oEAAoE;AACpE;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,0CAA0C;AAC1C,wCAAwC;AACxC,+DAA+D;AAC/D,iEAAiE;AACjE;AACA;AACA,cAAc;AACd;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB,MAAM;AACvB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,KAAK;AACpB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS,GAAG,SAAS,KAAK,SAAS;AAC3D,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB;AAC5D;AACA,mCAAmC,iBAAiB;AACpD,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,oCAAoC;AAC9C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,4CAA4C,kBAAkB,EAAE;AAChE;AACA;AACA;AACA,gCAAgC,qCAAqC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,qCAAqC;AAC/C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,uCAAuC,kBAAkB,EAAE;AAC3D;AACA;AACA;AACA,2BAA2B,oCAAoC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,qCAAqC;AAC/C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,uCAAuC,2BAA2B,EAAE;AACpE;AACA;AACA;AACA,2BAA2B,kCAAkC;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,oCAAoC;AAC9C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,2CAA2C,4BAA4B,EAAE;AACzE;AACA;AACA;AACA,+BAA+B,mCAAmC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,SAAS,KAAK,SAAS,GAAG,SAAS;AAC7D,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB;AAC5D,sBAAsB,iBAAiB,GAAG,iBAAiB;AAC3D;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,KAAK;AACpB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,qBAAqB,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS;AAClE;AACA,4BAA4B,SAAS,GAAG,SAAS;AACjD;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,qBAAqB,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB;AAC9E;AACA,8BAA8B,iBAAiB;AAC/C;AACA,eAAe,iBAAiB,GAAG,iBAAiB;AACpD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,qBAAqB;AACpC,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA,iCAAiC,SAAS,eAAe,YAAY,EAAE;AACvE;AACA;AACA;AACA,iCAAiC,SAAS;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA,qCAAqC,SAAS,eAAe,YAAY,EAAE;AAC3E;AACA;AACA;AACA,qCAAqC,SAAS;AAC9C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,oCAAoC;AAC9C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,4CAA4C,kBAAkB,EAAE;AAChE;AACA;AACA;AACA,gCAAgC,qCAAqC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,qCAAqC;AAC/C,UAAU,qCAAqC;AAC/C,UAAU;AACV;AACA;AACA,uCAAuC,kBAAkB,EAAE;AAC3D;AACA;AACA;AACA,2BAA2B,oCAAoC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS,KAAK,SAAS,GAAG,SAAS;AACtD,eAAe,SAAS,GAAG,SAAS;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB;AAC5D,sBAAsB,iBAAiB,GAAG,iBAAiB;AAC3D;AACA;AACA,eAAe,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB;AACxE;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,SAAS,GAAG,SAAS,GAAG,SAAS;AACnD,eAAe,SAAS,GAAG,SAAS;AACpC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB,GAAG,iBAAiB;AAChF;AACA;AACA,eAAe,iBAAiB,GAAG,iBAAiB;AACpD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,KAAK;AACpB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,KAAK,SAAS,GAAG,SAAS;AACpD,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA,uBAAuB,iBAAiB,GAAG,iBAAiB;AAC5D,sBAAsB,iBAAiB,GAAG,iBAAiB;AAC3D;AACA;AACA,eAAe,iBAAiB,GAAG,iBAAiB;AACpD;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc,OAAO,QAAQ,SAAS,GAAG,SAAS,GAAG;AACrD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,+BAA+B;AACzC,UAAU,+BAA+B;AACzC,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,8BAA8B;;AAExE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,8BAA8B;AACxC,UAAU;AACV;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAc;AACd;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,gBAAgB,OAAO;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,+CAA+C;AACzD,UAAU;AACV;AACA;AACA;AACA,uBAAuB,oCAAoC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,UAAU,8CAA8C;AACxD,UAAU;AACV;AACA;AACA,oCAAoC,kBAAkB,EAAE;AACxD;AACA;AACA;AACA,wBAAwB,4BAA4B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA,UAAU,+CAA+C;AACzD,UAAU,gDAAgD;AAC1D,UAAU;AACV;AACA;AACA,kCAAkC,mBAAmB,EAAE;AACvD;AACA;AACA;AACA,sBAAsB,2BAA2B;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,aAAa;AAC9B;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,kBAAkB,iBAAiB;AACnC;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,aAAa;AAC9B;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,oBAAoB;AACnC,eAAe,EAAE;AACjB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,sBAAsB;AACrC;AACA,eAAe,KAAK;AACpB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,UAAU,4BAA4B;AACtC,UAAU;AACV;AACA;AACA;AACA;AACA,QAAQ;AACR,cAAc,OAAO,4BAA4B,QAAQ,8BAA8B;AACvF;AACA;AACA,cAAc,UAAU,4BAA4B,YAAY,8BAA8B;AAC9F;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,iBAAiB;AAC/B;AACA;AACA;AACA,UAAU,mBAAmB;AAC7B,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,qCAAqC;AACpD;AACA,eAAe,SAAS;AACxB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,8BAA8B;AACxC,UAAU,8BAA8B;AACxC,UAAU,8BAA8B;AACxC,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,gDAAgD;AAC1D,UAAU,+CAA+C;AACzD,UAAU;AACV;AACA;AACA,uCAAuC,iBAAiB,EAAE;AAC1D;AACA;AACA;AACA,2BAA2B,4BAA4B;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc,iBAAiB,EAAE;;AAEtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,iBAAiB,yBAAyB;AAC1C;AACA;AACA,QAAQ,IAAI;AACZ,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA,UAAU,+CAA+C;AACzD,UAAU;AACV;AACA;AACA,oCAAoC,kBAAkB,EAAE;AACxD;AACA;AACA;AACA,wBAAwB,4BAA4B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,oBAAoB;AACnC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,gBAAgB,OAAO;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,mCAAmC;AAC7C,UAAU;AACV;AACA;AACA;AACA,sBAAsB,oCAAoC;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,yBAAyB;AACxC;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA,UAAU,8BAA8B;AACxC,UAAU,8BAA8B;AACxC,UAAU,8BAA8B;AACxC,UAAU;AACV;AACA;AACA,qCAAqC,eAAe,EAAE;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,oBAAoB,iCAAiC;AACrD,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,QAAQ;AACvB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,kDAAkD,kBAAkB;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,KAAK;AACpB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,KAAK;AACpB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA,qBAAqB;AACrB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,yBAAyB;AACxC;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,qBAAqB;AACpC,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,oBAAoB;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB;AACrB;AACA,6BAA6B,mBAAmB,cAAc,EAAE,EAAE;AAClE;AACA;AACA,6BAA6B,mBAAmB,cAAc,EAAE,EAAE;AAClE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB;AACrB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA,iCAAiC,kBAAkB,EAAE;AACrD;AACA;AACA;AACA;AACA;AACA,kDAAkD,kBAAkB,EAAE;AACtE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,SAAS;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB;AACrB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB;AACrB;AACA,0BAA0B,SAAS;AACnC;AACA;AACA,0BAA0B,SAAS;AACnC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,MAAM;AACvB;AACA;AACA,kBAAkB,iBAAiB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS;AAC1B,cAAc;AACd;AACA,iBAAiB,SAAS;AAC1B,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS;AAC1B,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,GAAG,SAAS,GAAG,SAAS;AAClD,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,GAAG,SAAS,GAAG,SAAS;AAClD,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,qBAAqB;AACpC,iBAAiB,MAAM;AACvB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,mBAAmB,SAAS,GAAG,SAAS,GAAG,SAAS;AACpD,cAAc;AACd;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,uBAAuB,OAAO,SAAS,EAAE,GAAG,OAAO,iBAAiB,EAAE;AACtE,cAAc,OAAO,iBAAiB;AACtC;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA,qBAAqB,4BAA4B;AACjD,qBAAqB,6BAA6B;AAClD,qBAAqB;AACrB;AACA;AACA,qCAAqC,mBAAmB,EAAE;AAC1D;AACA;AACA;AACA,yBAAyB,2BAA2B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA,qBAAqB,4BAA4B;AACjD,qBAAqB,6BAA6B;AAClD,qBAAqB;AACrB;AACA;AACA,yCAAyC,mBAAmB,EAAE;AAC9D;AACA;AACA;AACA,6BAA6B,4BAA4B;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB,OAAO,SAAS;AACrC,6BAA6B,gBAAgB,SAAS,GAAG;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA,8BAA8B,gBAAgB,SAAS,GAAG;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,QAAQ;AACR,cAAc;AACd;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,KAAK;AACpB,iBAAiB,EAAE;AACnB;AACA;AACA,qBAAqB,QAAQ,OAAO,oBAAoB,EAAE;AAC1D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,kBAAkB,iBAAiB;AACnC;AACA,QAAQ;AACR,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,qBAAqB,+BAA+B;AACpD,qBAAqB;AACrB;AACA;AACA,uCAAuC,cAAc,EAAE;AACvD,cAAc,2BAA2B;AACzC;AACA;AACA;AACA,cAAc,2BAA2B;AACzC;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,gBAAgB,SAAS,GAAG,SAAS;AACrC;AACA;AACA;AACA,gBAAgB,SAAS,GAAG,SAAS;AACrC;AACA;AACA;AACA,cAAc,QAAQ,iBAAiB,GAAG,iBAAiB;AAC3D;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,oBAAoB;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,KAAK;;AAEL;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,qBAAqB;AACpC,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,qBAAqB;AACpC,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA,gCAAgC;AAChC,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB;AACrB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA,qBAAqB,QAAQ,OAAO,+BAA+B,EAAE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO,WAAW;AAChC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,oBAAoB,yBAAyB;AAC7C;AACA,QAAQ,IAAI;AACZ,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,iBAAiB,QAAQ;AACzB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA;AACA;AACA;AACA,cAAc,QAAQ,QAAQ,EAAE;AAChC;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ,QAAQ,EAAE;AAChC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,qBAAqB,QAAQ,OAAO,SAAS,EAAE;AAC/C;AACA,iDAAiD,cAAc,EAAE;AACjE;AACA;AACA;AACA,iDAAiD,sBAAsB,EAAE;AACzE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,aAAa;AAC5B,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO,WAAW;AAChC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kCAAkC,KAAK;AACvC;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,cAAc;AAC7B,eAAe,gBAAgB;AAC/B,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,cAAc;AAC7B,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA,gBAAgB,OAAO;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA,iBAAiB,sBAAsB;AACvC,qBAAqB,UAAU;AAC/B;AACA;AACA,sEAAsE,2BAA2B,EAAE;AACnG,iBAAiB,8BAA8B;AAC/C;AACA;AACA;AACA,4DAA4D;AAC5D,iBAAiB,mBAAmB;AACpC;AACA;AACA;AACA;AACA,0CAA0C,OAAO;AACjD,iBAAiB,oBAAoB;AACrC;AACA;AACA;AACA;AACA,iBAAiB,qBAAqB;AACtC;AACA;AACA;AACA,qDAAqD,2BAA2B,EAAE;AAClF,wCAAwC,aAAa,eAAe,EAAE;AACtE,iBAAiB,8BAA8B;AAC/C;AACA;AACA;AACA,wDAAwD,qCAAqC;AAC7F;AACA;AACA;AACA;AACA,0DAA0D,qBAAqB;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,YAAY;AACvD,0CAA0C,QAAQ;AAClD,iBAAiB,qBAAqB;AACtC;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,+BAA+B;;AAE/B,mCAAmC;AACnC;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,wBAAwB;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;;AAEP,mBAAmB;;AAEnB;AACA;AACA;AACA;AACA,8BAA8B,mBAAmB;AACjD;AACA;AACA;AACA;AACA,4CAA4C;;AAE5C;AACA,uDAAuD;AACvD;AACA;AACA,6BAA6B,EAAE;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C,+BAA+B,iCAAiC;AAChE,cAAc;AACd;AACA;AACA,sBAAsB;;AAEtB;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,cAAc;AAC7B,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iCAAiC;AACjC,aAAa,QAAQ,QAAQ,UAAU,aAAa;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,cAAc;AAC7B,gBAAgB,OAAO;AACvB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,KAAK;AACpB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,qBAAqB;AACpC,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B,sBAAsB,kBAAkB;AACxC;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA,aAAa,qBAAqB;AAClC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,iBAAiB;AAC3B,UAAU;AACV;AACA;AACA,qCAAqC,mBAAmB,cAAc,EAAE,EAAE;AAC1E,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA,4CAA4C,SAAS;AACrD;AACA;AACA,eAAe,SAAS,GAAG,SAAS;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,EAAE;AACnB;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,8CAA8C;AACxD,UAAU;AACV;AACA;AACA;AACA,mCAAmC,mCAAmC;AACtE,eAAe,8CAA8C;AAC7D;AACA;AACA;AACA,eAAe,4BAA4B;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,yBAAyB;AACnC,UAAU;AACV;AACA;AACA,oCAAoC,iBAAiB;AACrD,eAAe,yBAAyB;AACxC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,EAAE;AACjB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,yBAAyB;AACnC,UAAU;AACV;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,OAAO,qBAAqB,EAAE;AACxC,UAAU,OAAO,qBAAqB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,KAAK;AACpB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,OAAO;AACtB,eAAe,OAAO,YAAY;AAClC,eAAe,QAAQ;AACvB,iBAAiB,gBAAgB;AACjC;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,gBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAmB,GAAG,iBAAiB;AACvD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,4BAA4B,qDAAqD;AACjF;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB;AACxC;AACA,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,UAAU,OAAO,SAAS,EAAE;AAC5B,UAAU,OAAO,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,gBAAgB,IAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kEAAkE;AAClE;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,EAAE;AACjB,iBAAiB,MAAM;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA,qCAAqC,YAAY,EAAE;AACnD,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS;AACpE;AACA,sCAAsC,YAAY,EAAE;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,EAAE;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,EAAE;AACnB;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS;AAC5C;AACA,qCAAqC,YAAY,EAAE;AACnD,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA,uBAAuB,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS;AACpE;AACA,qCAAqC,YAAY,EAAE;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK,MAAM,iBAAiB;;AAE5B;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,mCAAmC,4DAA4D;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAoB,yCAAyC;AAC7D;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;;;;;;;AC3rhBD;;AAEA;AACA,iBAAiB,aAAa,EAAE;;AAEhC;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;;AAEA;AACA;AACA,4CAA4C;;AAE5C;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC,GAAG;AACH;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC,GAAG;AACH;AACA;AACA;AACA;;;;;;;;AClBA;;;;;;;;;;;;;;;ACcA;AACA,QAAQ,aAAa;;ADGrB;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA,QAAQ,OAAO,WAAW;IACtB;IACA;IACA;;KAED,OAAO;KACP,UAAU,UAAU;KACpB,UAAU,aAAa;KACvB,uEAAI,UACH,MACA,QACA,sBACA,sBAAyB;IACzB,KAAK,KAAK;IAEV,qBAAqB,IAAI;QACvB,OAAO;QACP,OAAO","file":"index.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmory imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmory exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tObject.defineProperty(exports, name, {\n \t\t\tconfigurable: false,\n \t\t\tenumerable: true,\n \t\t\tget: getter\n \t\t});\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 16);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap d343910db03588c47a4b","require('./angular');\nmodule.exports = angular;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular/index.js\n// module id = 0\n// module chunks = 0","require('./angular-cookies');\nmodule.exports = 'ngCookies';\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-cookies/index.js\n// module id = 1\n// module chunks = 0","require('./angular-resource');\nmodule.exports = 'ngResource';\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-resource/index.js\n// module id = 2\n// module chunks = 0","/*!\n * State-based routing for AngularJS\n * @version v1.0.0-beta.1\n * @link https://ui-router.github.io\n * @license MIT License, http://www.opensource.org/licenses/MIT\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"angular-ui-router\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"angular-ui-router\"] = factory();\n\telse\n\t\troot[\"angular-ui-router\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Main entry point for angular 1.x build\n\t * @module ng1\n\t */\n\t/** for typedoc */\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t__export(__webpack_require__(1));\n\t__export(__webpack_require__(53));\n\t__export(__webpack_require__(55));\n\t__webpack_require__(58);\n\t__webpack_require__(59);\n\t__webpack_require__(60);\n\t__webpack_require__(61);\n\tObject.defineProperty(exports, \"__esModule\", { value: true });\n\texports.default = \"ui.router\";\n\n\n/***/ },\n/* 1 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module common */ /** */\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t__export(__webpack_require__(2));\n\t__export(__webpack_require__(46));\n\t__export(__webpack_require__(47));\n\t__export(__webpack_require__(48));\n\t__export(__webpack_require__(49));\n\t__export(__webpack_require__(50));\n\t__export(__webpack_require__(51));\n\t__export(__webpack_require__(52));\n\t__export(__webpack_require__(44));\n\tvar router_1 = __webpack_require__(26);\n\texports.UIRouter = router_1.UIRouter;\n\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module common */ /** for typedoc */\n\t__export(__webpack_require__(3));\n\t__export(__webpack_require__(6));\n\t__export(__webpack_require__(7));\n\t__export(__webpack_require__(5));\n\t__export(__webpack_require__(4));\n\t__export(__webpack_require__(8));\n\t__export(__webpack_require__(9));\n\t__export(__webpack_require__(12));\n\n\n/***/ },\n/* 3 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * Random utility functions used in the UI-Router code\n\t *\n\t * @preferred @module common\n\t */ /** for typedoc */\n\t\"use strict\";\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar w = typeof window === 'undefined' ? {} : window;\n\tvar angular = w.angular || {};\n\texports.fromJson = angular.fromJson || JSON.parse.bind(JSON);\n\texports.toJson = angular.toJson || JSON.stringify.bind(JSON);\n\texports.copy = angular.copy || _copy;\n\texports.forEach = angular.forEach || _forEach;\n\texports.extend = angular.extend || _extend;\n\texports.equals = angular.equals || _equals;\n\texports.identity = function (x) { return x; };\n\texports.noop = function () { return undefined; };\n\texports.abstractKey = 'abstract';\n\t/**\n\t * Binds and copies functions onto an object\n\t *\n\t * Takes functions from the 'from' object, binds those functions to the _this object, and puts the bound functions\n\t * on the 'to' object.\n\t *\n\t * This example creates an new class instance whose functions are prebound to the new'd object.\n\t * @example\n\t * ```\n\t *\n\t * class Foo {\n\t *   constructor(data) {\n\t *     // Binds all functions from Foo.prototype to 'this',\n\t *     // then copies them to 'this'\n\t *     bindFunctions(Foo.prototype, this, this);\n\t *     this.data = data;\n\t *   }\n\t *\n\t *   log() {\n\t *     console.log(this.data);\n\t *   }\n\t * }\n\t *\n\t * let myFoo = new Foo([1,2,3]);\n\t * var logit = myFoo.log;\n\t * logit(); // logs [1, 2, 3] from the myFoo 'this' instance\n\t * ```\n\t *\n\t * This example creates a bound version of a service function, and copies it to another object\n\t * @example\n\t * ```\n\t *\n\t * var SomeService = {\n\t *   this.data = [3, 4, 5];\n\t *   this.log = function() {\n\t *     console.log(this.data);\n\t *   }\n\t * }\n\t *\n\t * // Constructor fn\n\t * function OtherThing() {\n\t *   // Binds all functions from SomeService to SomeService,\n\t *   // then copies them to 'this'\n\t *   bindFunctions(SomeService, this, SomeService);\n\t * }\n\t *\n\t * let myOtherThing = new OtherThing();\n\t * myOtherThing.log(); // logs [3, 4, 5] from SomeService's 'this'\n\t * ```\n\t *\n\t * @param from The object which contains the functions to be bound\n\t * @param to The object which will receive the bound functions\n\t * @param bindTo The object which the functions will be bound to\n\t * @param fnNames The function names which will be bound (Defaults to all the functions found on the 'from' object)\n\t */\n\tfunction bindFunctions(from, to, bindTo, fnNames) {\n\t    if (fnNames === void 0) { fnNames = Object.keys(from); }\n\t    return fnNames.filter(function (name) { return typeof from[name] === 'function'; })\n\t        .forEach(function (name) { return to[name] = from[name].bind(bindTo); });\n\t}\n\texports.bindFunctions = bindFunctions;\n\t/**\n\t * prototypal inheritance helper.\n\t * Creates a new object which has `parent` object as its prototype, and then copies the properties from `extra` onto it\n\t */\n\texports.inherit = function (parent, extra) {\n\t    return exports.extend(new (exports.extend(function () { }, { prototype: parent }))(), extra);\n\t};\n\t/**\n\t * Given an arguments object, converts the arguments at index idx and above to an array.\n\t * This is similar to es6 rest parameters.\n\t *\n\t * Optionally, the argument at index idx may itself already be an array.\n\t *\n\t * For example,\n\t * given either:\n\t *        arguments = [ obj, \"foo\", \"bar\" ]\n\t * or:\n\t *        arguments = [ obj, [\"foo\", \"bar\"] ]\n\t * then:\n\t *        restArgs(arguments, 1) == [\"foo\", \"bar\"]\n\t *\n\t * This allows functions like pick() to be implemented such that it allows either a bunch\n\t * of string arguments (like es6 rest parameters), or a single array of strings:\n\t *\n\t * given:\n\t *        var obj = { foo: 1, bar: 2, baz: 3 };\n\t * then:\n\t *        pick(obj, \"foo\", \"bar\");   // returns { foo: 1, bar: 2 }\n\t *        pick(obj, [\"foo\", \"bar\"]); // returns { foo: 1, bar: 2 }\n\t */\n\tvar restArgs = function (args, idx) {\n\t    if (idx === void 0) { idx = 0; }\n\t    return Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(args, idx));\n\t};\n\t/** Given an array, returns true if the object is found in the array, (using indexOf) */\n\texports.inArray = function (array, obj) { return array.indexOf(obj) !== -1; };\n\t/** Given an array, and an item, if the item is found in the array, it removes it (in-place).  The same array is returned */\n\texports.removeFrom = hof_1.curry(function (array, obj) {\n\t    var idx = array.indexOf(obj);\n\t    if (idx >= 0)\n\t        array.splice(idx, 1);\n\t    return array;\n\t});\n\t/**\n\t * Applies a set of defaults to an options object.  The options object is filtered\n\t * to only those properties of the objects in the defaultsList.\n\t * Earlier objects in the defaultsList take precedence when applying defaults.\n\t */\n\tfunction defaults(opts) {\n\t    if (opts === void 0) { opts = {}; }\n\t    var defaultsList = [];\n\t    for (var _i = 1; _i < arguments.length; _i++) {\n\t        defaultsList[_i - 1] = arguments[_i];\n\t    }\n\t    var defaults = merge.apply(null, [{}].concat(defaultsList));\n\t    return exports.extend({}, defaults, pick(opts || {}, Object.keys(defaults)));\n\t}\n\texports.defaults = defaults;\n\t/**\n\t * Merges properties from the list of objects to the destination object.\n\t * If a property already exists in the destination object, then it is not overwritten.\n\t */\n\tfunction merge(dst) {\n\t    var objs = [];\n\t    for (var _i = 1; _i < arguments.length; _i++) {\n\t        objs[_i - 1] = arguments[_i];\n\t    }\n\t    exports.forEach(objs, function (obj) {\n\t        exports.forEach(obj, function (value, key) {\n\t            if (!dst.hasOwnProperty(key))\n\t                dst[key] = value;\n\t        });\n\t    });\n\t    return dst;\n\t}\n\texports.merge = merge;\n\t/** Reduce function that merges each element of the list into a single object, using extend */\n\texports.mergeR = function (memo, item) { return exports.extend(memo, item); };\n\t/**\n\t * Finds the common ancestor path between two states.\n\t *\n\t * @param {Object} first The first state.\n\t * @param {Object} second The second state.\n\t * @return {Array} Returns an array of state names in descending order, not including the root.\n\t */\n\tfunction ancestors(first, second) {\n\t    var path = [];\n\t    for (var n in first.path) {\n\t        if (first.path[n] !== second.path[n])\n\t            break;\n\t        path.push(first.path[n]);\n\t    }\n\t    return path;\n\t}\n\texports.ancestors = ancestors;\n\t/**\n\t * Performs a non-strict comparison of the subset of two objects, defined by a list of keys.\n\t *\n\t * @param {Object} a The first object.\n\t * @param {Object} b The second object.\n\t * @param {Array} keys The list of keys within each object to compare. If the list is empty or not specified,\n\t *                     it defaults to the list of keys in `a`.\n\t * @return {Boolean} Returns `true` if the keys match, otherwise `false`.\n\t */\n\tfunction equalForKeys(a, b, keys) {\n\t    if (keys === void 0) { keys = Object.keys(a); }\n\t    for (var i = 0; i < keys.length; i++) {\n\t        var k = keys[i];\n\t        if (a[k] != b[k])\n\t            return false; // Not '===', values aren't necessarily normalized\n\t    }\n\t    return true;\n\t}\n\texports.equalForKeys = equalForKeys;\n\tfunction pickOmitImpl(predicate, obj) {\n\t    var objCopy = {}, keys = restArgs(arguments, 2);\n\t    for (var key in obj) {\n\t        if (predicate(keys, key))\n\t            objCopy[key] = obj[key];\n\t    }\n\t    return objCopy;\n\t}\n\t/** Return a copy of the object only containing the whitelisted properties. */\n\tfunction pick(obj) { return pickOmitImpl.apply(null, [exports.inArray].concat(restArgs(arguments))); }\n\texports.pick = pick;\n\t/** Return a copy of the object omitting the blacklisted properties. */\n\tfunction omit(obj) { return pickOmitImpl.apply(null, [hof_1.not(exports.inArray)].concat(restArgs(arguments))); }\n\texports.omit = omit;\n\t/**\n\t * Maps an array, or object to a property (by name)\n\t */\n\tfunction pluck(collection, propName) {\n\t    return map(collection, hof_1.prop(propName));\n\t}\n\texports.pluck = pluck;\n\t/** Filters an Array or an Object's properties based on a predicate */\n\tfunction filter(collection, callback) {\n\t    var arr = predicates_1.isArray(collection), result = arr ? [] : {};\n\t    var accept = arr ? function (x) { return result.push(x); } : function (x, key) { return result[key] = x; };\n\t    exports.forEach(collection, function (item, i) {\n\t        if (callback(item, i))\n\t            accept(item, i);\n\t    });\n\t    return result;\n\t}\n\texports.filter = filter;\n\t/** Finds an object from an array, or a property of an object, that matches a predicate */\n\tfunction find(collection, callback) {\n\t    var result;\n\t    exports.forEach(collection, function (item, i) {\n\t        if (result)\n\t            return;\n\t        if (callback(item, i))\n\t            result = item;\n\t    });\n\t    return result;\n\t}\n\texports.find = find;\n\t/** Given an object, returns a new object, where each property is transformed by the callback function */\n\texports.mapObj = map;\n\t/** Maps an array or object properties using a callback function */\n\tfunction map(collection, callback) {\n\t    var result = predicates_1.isArray(collection) ? [] : {};\n\t    exports.forEach(collection, function (item, i) { return result[i] = callback(item, i); });\n\t    return result;\n\t}\n\texports.map = map;\n\t/**\n\t * Given an object, return its enumerable property values\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let foo = { a: 1, b: 2, c: 3 }\n\t * let vals = values(foo); // [ 1, 2, 3 ]\n\t * ```\n\t */\n\texports.values = function (obj) { return Object.keys(obj).map(function (key) { return obj[key]; }); };\n\t/**\n\t * Reduce function that returns true if all of the values are truthy.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let vals = [ 1, true, {}, \"hello world\"];\n\t * vals.reduce(allTrueR, true); // true\n\t *\n\t * vals.push(0);\n\t * vals.reduce(allTrueR, true); // false\n\t * ```\n\t */\n\texports.allTrueR = function (memo, elem) { return memo && elem; };\n\t/**\n\t * Reduce function that returns true if any of the values are truthy.\n\t *\n\t *  * @example\n\t * ```\n\t *\n\t * let vals = [ 0, null, undefined ];\n\t * vals.reduce(anyTrueR, true); // false\n\t *\n\t * vals.push(\"hello world\");\n\t * vals.reduce(anyTrueR, true); // true\n\t * ```\n\t */\n\texports.anyTrueR = function (memo, elem) { return memo || elem; };\n\t/**\n\t * Reduce function which un-nests a single level of arrays\n\t * @example\n\t * ```\n\t *\n\t * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n\t * input.reduce(unnestR, []) // [ \"a\", \"b\", \"c\", \"d\", [ \"double, \"nested\" ] ]\n\t * ```\n\t */\n\texports.unnestR = function (memo, elem) { return memo.concat(elem); };\n\t/**\n\t * Reduce function which recursively un-nests all arrays\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n\t * input.reduce(unnestR, []) // [ \"a\", \"b\", \"c\", \"d\", \"double, \"nested\" ]\n\t * ```\n\t */\n\texports.flattenR = function (memo, elem) { return predicates_1.isArray(elem) ? memo.concat(elem.reduce(exports.flattenR, [])) : pushR(memo, elem); };\n\t/** Reduce function that pushes an object to an array, then returns the array.  Mostly just for [[flattenR]] */\n\tfunction pushR(arr, obj) { arr.push(obj); return arr; }\n\texports.pushR = pushR;\n\t/** Reduce function that filters out duplicates */\n\texports.uniqR = function (acc, token) { return exports.inArray(acc, token) ? acc : pushR(acc, token); };\n\t/**\n\t * Return a new array with a single level of arrays unnested.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n\t * unnest(input) // [ \"a\", \"b\", \"c\", \"d\", [ \"double, \"nested\" ] ]\n\t * ```\n\t */\n\texports.unnest = function (arr) { return arr.reduce(exports.unnestR, []); };\n\t/**\n\t * Return a completely flattened version of an array.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let input = [ [ \"a\", \"b\" ], [ \"c\", \"d\" ], [ [ \"double\", \"nested\" ] ] ];\n\t * flatten(input) // [ \"a\", \"b\", \"c\", \"d\", \"double, \"nested\" ]\n\t * ```\n\t */\n\texports.flatten = function (arr) { return arr.reduce(exports.flattenR, []); };\n\t/**\n\t * Given a .filter Predicate, builds a .filter Predicate which throws an error if any elements do not pass.\n\t * @example\n\t * ```\n\t *\n\t * let isNumber = (obj) => typeof(obj) === 'number';\n\t * let allNumbers = [ 1, 2, 3, 4, 5 ];\n\t * allNumbers.filter(assertPredicate(isNumber)); //OK\n\t *\n\t * let oneString = [ 1, 2, 3, 4, \"5\" ];\n\t * oneString.filter(assertPredicate(isNumber, \"Not all numbers\")); // throws Error(\"\"Not all numbers\"\");\n\t * ```\n\t */\n\tfunction assertPredicate(predicate, errMsg) {\n\t    if (errMsg === void 0) { errMsg = \"assert failure\"; }\n\t    return function (obj) {\n\t        if (!predicate(obj)) {\n\t            throw new Error(predicates_1.isFunction(errMsg) ? errMsg(obj) : errMsg);\n\t        }\n\t        return true;\n\t    };\n\t}\n\texports.assertPredicate = assertPredicate;\n\t/**\n\t * Like _.pairs: Given an object, returns an array of key/value pairs\n\t *\n\t * @example\n\t * ```\n\t *\n\t * pairs({ foo: \"FOO\", bar: \"BAR }) // [ [ \"foo\", \"FOO\" ], [ \"bar\": \"BAR\" ] ]\n\t * ```\n\t */\n\texports.pairs = function (object) { return Object.keys(object).map(function (key) { return [key, object[key]]; }); };\n\t/**\n\t * Given two or more parallel arrays, returns an array of tuples where\n\t * each tuple is composed of [ a[i], b[i], ... z[i] ]\n\t *\n\t * @example\n\t * ```\n\t *\n\t * let foo = [ 0, 2, 4, 6 ];\n\t * let bar = [ 1, 3, 5, 7 ];\n\t * let baz = [ 10, 30, 50, 70 ];\n\t * arrayTuples(foo, bar);       // [ [0, 1], [2, 3], [4, 5], [6, 7] ]\n\t * arrayTuples(foo, bar, baz);  // [ [0, 1, 10], [2, 3, 30], [4, 5, 50], [6, 7, 70] ]\n\t * ```\n\t */\n\tfunction arrayTuples() {\n\t    var arrayArgs = [];\n\t    for (var _i = 0; _i < arguments.length; _i++) {\n\t        arrayArgs[_i - 0] = arguments[_i];\n\t    }\n\t    if (arrayArgs.length === 0)\n\t        return [];\n\t    var length = arrayArgs.reduce(function (min, arr) { return Math.min(arr.length, min); }, 9007199254740991); // aka 2^53 − 1 aka Number.MAX_SAFE_INTEGER\n\t    return Array.apply(null, Array(length)).map(function (ignored, idx) { return arrayArgs.map(function (arr) { return arr[idx]; }); });\n\t}\n\texports.arrayTuples = arrayTuples;\n\t/**\n\t * Reduce function which builds an object from an array of [key, value] pairs.\n\t *\n\t * Each iteration sets the key/val pair on the memo object, then returns the memo for the next iteration.\n\t *\n\t * Each keyValueTuple should be an array with values [ key: string, value: any ]\n\t *\n\t * @example\n\t * ```\n\t *\n\t * var pairs = [ [\"fookey\", \"fooval\"], [\"barkey\", \"barval\"] ]\n\t *\n\t * var pairsToObj = pairs.reduce((memo, pair) => applyPairs(memo, pair), {})\n\t * // pairsToObj == { fookey: \"fooval\", barkey: \"barval\" }\n\t *\n\t * // Or, more simply:\n\t * var pairsToObj = pairs.reduce(applyPairs, {})\n\t * // pairsToObj == { fookey: \"fooval\", barkey: \"barval\" }\n\t * ```\n\t */\n\tfunction applyPairs(memo, keyValTuple) {\n\t    var key, value;\n\t    if (predicates_1.isArray(keyValTuple))\n\t        key = keyValTuple[0], value = keyValTuple[1];\n\t    if (!predicates_1.isString(key))\n\t        throw new Error(\"invalid parameters to applyPairs\");\n\t    memo[key] = value;\n\t    return memo;\n\t}\n\texports.applyPairs = applyPairs;\n\t/** Get the last element of an array */\n\tfunction tail(arr) {\n\t    return arr.length && arr[arr.length - 1] || undefined;\n\t}\n\texports.tail = tail;\n\t/**\n\t * shallow copy from src to dest\n\t *\n\t * note: This is a shallow copy, while angular.copy is a deep copy.\n\t * ui-router uses `copy` only to make copies of state parameters.\n\t */\n\tfunction _copy(src, dest) {\n\t    if (dest)\n\t        Object.keys(dest).forEach(function (key) { return delete dest[key]; });\n\t    if (!dest)\n\t        dest = {};\n\t    return exports.extend(dest, src);\n\t}\n\tfunction _forEach(obj, cb, _this) {\n\t    if (predicates_1.isArray(obj))\n\t        return obj.forEach(cb, _this);\n\t    Object.keys(obj).forEach(function (key) { return cb(obj[key], key); });\n\t}\n\tfunction _copyProps(to, from) { Object.keys(from).forEach(function (key) { return to[key] = from[key]; }); return to; }\n\tfunction _extend(toObj, rest) {\n\t    return restArgs(arguments, 1).filter(exports.identity).reduce(_copyProps, toObj);\n\t}\n\tfunction _equals(o1, o2) {\n\t    if (o1 === o2)\n\t        return true;\n\t    if (o1 === null || o2 === null)\n\t        return false;\n\t    if (o1 !== o1 && o2 !== o2)\n\t        return true; // NaN === NaN\n\t    var t1 = typeof o1, t2 = typeof o2;\n\t    if (t1 !== t2 || t1 !== 'object')\n\t        return false;\n\t    var tup = [o1, o2];\n\t    if (hof_1.all(predicates_1.isArray)(tup))\n\t        return _arraysEq(o1, o2);\n\t    if (hof_1.all(predicates_1.isDate)(tup))\n\t        return o1.getTime() === o2.getTime();\n\t    if (hof_1.all(predicates_1.isRegExp)(tup))\n\t        return o1.toString() === o2.toString();\n\t    if (hof_1.all(predicates_1.isFunction)(tup))\n\t        return true; // meh\n\t    var predicates = [predicates_1.isFunction, predicates_1.isArray, predicates_1.isDate, predicates_1.isRegExp];\n\t    if (predicates.map(hof_1.any).reduce(function (b, fn) { return b || !!fn(tup); }, false))\n\t        return false;\n\t    var key, keys = {};\n\t    for (key in o1) {\n\t        if (!_equals(o1[key], o2[key]))\n\t            return false;\n\t        keys[key] = true;\n\t    }\n\t    for (key in o2) {\n\t        if (!keys[key])\n\t            return false;\n\t    }\n\t    return true;\n\t}\n\tfunction _arraysEq(a1, a2) {\n\t    if (a1.length !== a2.length)\n\t        return false;\n\t    return arrayTuples(a1, a2).reduce(function (b, t) { return b && _equals(t[0], t[1]); }, true);\n\t}\n\t// issue #2676\n\texports.silenceUncaughtInPromise = function (promise) {\n\t    return promise.catch(function (e) { return 0; }) && promise;\n\t};\n\texports.silentRejection = function (error) {\n\t    return exports.silenceUncaughtInPromise(coreservices_1.services.$q.reject(error));\n\t};\n\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** Predicates @module common_predicates */ /** */\n\tvar hof_1 = __webpack_require__(5);\n\tvar toStr = Object.prototype.toString;\n\tvar tis = function (t) { return function (x) { return typeof (x) === t; }; };\n\texports.isUndefined = tis('undefined');\n\texports.isDefined = hof_1.not(exports.isUndefined);\n\texports.isNull = function (o) { return o === null; };\n\texports.isFunction = tis('function');\n\texports.isNumber = tis('number');\n\texports.isString = tis('string');\n\texports.isObject = function (x) { return x !== null && typeof x === 'object'; };\n\texports.isArray = Array.isArray;\n\texports.isDate = (function (x) { return toStr.call(x) === '[object Date]'; });\n\texports.isRegExp = (function (x) { return toStr.call(x) === '[object RegExp]'; });\n\t/**\n\t * Predicate which checks if a value is injectable\n\t *\n\t * A value is \"injectable\" if it is a function, or if it is an ng1 array-notation-style array\n\t * where all the elements in the array are Strings, except the last one, which is a Function\n\t */\n\tfunction isInjectable(val) {\n\t    if (exports.isArray(val) && val.length) {\n\t        var head = val.slice(0, -1), tail = val.slice(-1);\n\t        return !(head.filter(hof_1.not(exports.isString)).length || tail.filter(hof_1.not(exports.isFunction)).length);\n\t    }\n\t    return exports.isFunction(val);\n\t}\n\texports.isInjectable = isInjectable;\n\t/**\n\t * Predicate which checks if a value looks like a Promise\n\t *\n\t * It is probably a Promise if it's an object, and it has a `then` property which is a Function\n\t */\n\texports.isPromise = hof_1.and(exports.isObject, hof_1.pipe(hof_1.prop('then'), exports.isFunction));\n\n\n/***/ },\n/* 5 */\n/***/ function(module, exports) {\n\n\t/**\n\t * Higher order functions\n\t *\n\t * @module common_hof\n\t */ /** */\n\t\"use strict\";\n\t/**\n\t * Returns a new function for [Partial Application](https://en.wikipedia.org/wiki/Partial_application) of the original function.\n\t *\n\t * Given a function with N parameters, returns a new function that supports partial application.\n\t * The new function accepts anywhere from 1 to N parameters.  When that function is called with M parameters,\n\t * where M is less than N, it returns a new function that accepts the remaining parameters.  It continues to\n\t * accept more parameters until all N parameters have been supplied.\n\t *\n\t *\n\t * This contrived example uses a partially applied function as an predicate, which returns true\n\t * if an object is found in both arrays.\n\t * @example\n\t * ```\n\t * // returns true if an object is in both of the two arrays\n\t * function inBoth(array1, array2, object) {\n\t *   return array1.indexOf(object) !== -1 &&\n\t *          array2.indexOf(object) !== 1;\n\t * }\n\t * let obj1, obj2, obj3, obj4, obj5, obj6, obj7\n\t * let foos = [obj1, obj3]\n\t * let bars = [obj3, obj4, obj5]\n\t *\n\t * // A curried \"copy\" of inBoth\n\t * let curriedInBoth = curry(inBoth);\n\t * // Partially apply both the array1 and array2\n\t * let inFoosAndBars = curriedInBoth(foos, bars);\n\t *\n\t * // Supply the final argument; since all arguments are\n\t * // supplied, the original inBoth function is then called.\n\t * let obj1InBoth = inFoosAndBars(obj1); // false\n\t *\n\t * // Use the inFoosAndBars as a predicate.\n\t * // Filter, on each iteration, supplies the final argument\n\t * let allObjs = [ obj1, obj2, obj3, obj4, obj5, obj6, obj7 ];\n\t * let foundInBoth = allObjs.filter(inFoosAndBars); // [ obj3 ]\n\t *\n\t * ```\n\t *\n\t * Stolen from: http://stackoverflow.com/questions/4394747/javascript-curry-function\n\t *\n\t * @param fn\n\t * @returns {*|function(): (*|any)}\n\t */\n\tfunction curry(fn) {\n\t    var initial_args = [].slice.apply(arguments, [1]);\n\t    var func_args_length = fn.length;\n\t    function curried(args) {\n\t        if (args.length >= func_args_length)\n\t            return fn.apply(null, args);\n\t        return function () {\n\t            return curried(args.concat([].slice.apply(arguments)));\n\t        };\n\t    }\n\t    return curried(initial_args);\n\t}\n\texports.curry = curry;\n\t/**\n\t * Given a varargs list of functions, returns a function that composes the argument functions, right-to-left\n\t * given: f(x), g(x), h(x)\n\t * let composed = compose(f,g,h)\n\t * then, composed is: f(g(h(x)))\n\t */\n\tfunction compose() {\n\t    var args = arguments;\n\t    var start = args.length - 1;\n\t    return function () {\n\t        var i = start, result = args[start].apply(this, arguments);\n\t        while (i--)\n\t            result = args[i].call(this, result);\n\t        return result;\n\t    };\n\t}\n\texports.compose = compose;\n\t/**\n\t * Given a varargs list of functions, returns a function that is composes the argument functions, left-to-right\n\t * given: f(x), g(x), h(x)\n\t * let piped = pipe(f,g,h);\n\t * then, piped is: h(g(f(x)))\n\t */\n\tfunction pipe() {\n\t    var funcs = [];\n\t    for (var _i = 0; _i < arguments.length; _i++) {\n\t        funcs[_i - 0] = arguments[_i];\n\t    }\n\t    return compose.apply(null, [].slice.call(arguments).reverse());\n\t}\n\texports.pipe = pipe;\n\t/**\n\t * Given a property name, returns a function that returns that property from an object\n\t * let obj = { foo: 1, name: \"blarg\" };\n\t * let getName = prop(\"name\");\n\t * getName(obj) === \"blarg\"\n\t */\n\texports.prop = function (name) { return function (obj) { return obj && obj[name]; }; };\n\t/**\n\t * Given a property name and a value, returns a function that returns a boolean based on whether\n\t * the passed object has a property that matches the value\n\t * let obj = { foo: 1, name: \"blarg\" };\n\t * let getName = propEq(\"name\", \"blarg\");\n\t * getName(obj) === true\n\t */\n\texports.propEq = curry(function (name, val, obj) { return obj && obj[name] === val; });\n\t/**\n\t * Given a dotted property name, returns a function that returns a nested property from an object, or undefined\n\t * let obj = { id: 1, nestedObj: { foo: 1, name: \"blarg\" }, };\n\t * let getName = prop(\"nestedObj.name\");\n\t * getName(obj) === \"blarg\"\n\t * let propNotFound = prop(\"this.property.doesnt.exist\");\n\t * propNotFound(obj) === undefined\n\t */\n\texports.parse = function (name) { return pipe.apply(null, name.split(\".\").map(exports.prop)); };\n\t/**\n\t * Given a function that returns a truthy or falsey value, returns a\n\t * function that returns the opposite (falsey or truthy) value given the same inputs\n\t */\n\texports.not = function (fn) { return function () {\n\t    var args = [];\n\t    for (var _i = 0; _i < arguments.length; _i++) {\n\t        args[_i - 0] = arguments[_i];\n\t    }\n\t    return !fn.apply(null, args);\n\t}; };\n\t/**\n\t * Given two functions that return truthy or falsey values, returns a function that returns truthy\n\t * if both functions return truthy for the given arguments\n\t */\n\tfunction and(fn1, fn2) {\n\t    return function () {\n\t        var args = [];\n\t        for (var _i = 0; _i < arguments.length; _i++) {\n\t            args[_i - 0] = arguments[_i];\n\t        }\n\t        return fn1.apply(null, args) && fn2.apply(null, args);\n\t    };\n\t}\n\texports.and = and;\n\t/**\n\t * Given two functions that return truthy or falsey values, returns a function that returns truthy\n\t * if at least one of the functions returns truthy for the given arguments\n\t */\n\tfunction or(fn1, fn2) {\n\t    return function () {\n\t        var args = [];\n\t        for (var _i = 0; _i < arguments.length; _i++) {\n\t            args[_i - 0] = arguments[_i];\n\t        }\n\t        return fn1.apply(null, args) || fn2.apply(null, args);\n\t    };\n\t}\n\texports.or = or;\n\t/**\n\t * Check if all the elements of an array match a predicate function\n\t *\n\t * @param fn1 a predicate function `fn1`\n\t * @returns a function which takes an array and returns true if `fn1` is true for all elements of the array\n\t */\n\texports.all = function (fn1) { return function (arr) { return arr.reduce(function (b, x) { return b && !!fn1(x); }, true); }; };\n\texports.any = function (fn1) { return function (arr) { return arr.reduce(function (b, x) { return b || !!fn1(x); }, false); }; };\n\texports.none = exports.not(exports.any);\n\t/** Given a class, returns a Predicate function that returns true if the object is of that class */\n\texports.is = function (ctor) { return function (obj) { return (obj != null && obj.constructor === ctor || obj instanceof ctor); }; };\n\t/** Given a value, returns a Predicate function that returns true if another value is === equal to the original value */\n\texports.eq = function (val) { return function (other) { return val === other; }; };\n\t/** Given a value, returns a function which returns the value */\n\texports.val = function (v) { return function () { return v; }; };\n\tfunction invoke(fnName, args) {\n\t    return function (obj) { return obj[fnName].apply(obj, args); };\n\t}\n\texports.invoke = invoke;\n\t/**\n\t * Sorta like Pattern Matching (a functional programming conditional construct)\n\t *\n\t * See http://c2.com/cgi/wiki?PatternMatching\n\t *\n\t * This is a conditional construct which allows a series of predicates and output functions\n\t * to be checked and then applied.  Each predicate receives the input.  If the predicate\n\t * returns truthy, then its matching output function (mapping function) is provided with\n\t * the input and, then the result is returned.\n\t *\n\t * Each combination (2-tuple) of predicate + output function should be placed in an array\n\t * of size 2: [ predicate, mapFn ]\n\t *\n\t * These 2-tuples should be put in an outer array.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * // Here's a 2-tuple where the first element is the isString predicate\n\t * // and the second element is a function that returns a description of the input\n\t * let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ];\n\t *\n\t * // Second tuple: predicate \"isNumber\", mapfn returns a description\n\t * let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ];\n\t *\n\t * let third = [ (input) => input === null,  (input) => `Oh, null...` ];\n\t *\n\t * let fourth = [ (input) => input === undefined,  (input) => `notdefined` ];\n\t *\n\t * let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]);\n\t *\n\t * console.log(descriptionOf(undefined)); // 'notdefined'\n\t * console.log(descriptionOf(55)); // '(55) That's a number!'\n\t * console.log(descriptionOf(\"foo\")); // 'Here's your string foo'\n\t * ```\n\t *\n\t * @param struct A 2D array.  Each element of the array should be an array, a 2-tuple,\n\t * with a Predicate and a mapping/output function\n\t * @returns {function(any): *}\n\t */\n\tfunction pattern(struct) {\n\t    return function (x) {\n\t        for (var i = 0; i < struct.length; i++) {\n\t            if (struct[i][0](x))\n\t                return struct[i][1](x);\n\t        }\n\t    };\n\t}\n\texports.pattern = pattern;\n\n\n/***/ },\n/* 6 */\n/***/ function(module, exports) {\n\n\t/**\n\t * This module is a stub for core services such as Dependency Injection or Browser Location.\n\t * Core services may be implemented by a specific framework, such as ng1 or ng2, or be pure javascript.\n\t *\n\t * @module common\n\t */\n\t\"use strict\";\n\t/** for typedoc */\n\t//import {IQService} from \"angular\";\n\t//import {IInjectorService} from \"angular\";\n\tvar notImplemented = function (fnname) { return function () {\n\t    throw new Error(fnname + \"(): No coreservices implementation for UI-Router is loaded. You should include one of: ['angular1.js']\");\n\t}; };\n\tvar services = {\n\t    $q: undefined,\n\t    $injector: undefined,\n\t    location: {},\n\t    locationConfig: {},\n\t    template: {}\n\t};\n\texports.services = services;\n\t[\"replace\", \"url\", \"path\", \"search\", \"hash\", \"onChange\"]\n\t    .forEach(function (key) { return services.location[key] = notImplemented(key); });\n\t[\"port\", \"protocol\", \"host\", \"baseHref\", \"html5Mode\", \"hashPrefix\"]\n\t    .forEach(function (key) { return services.locationConfig[key] = notImplemented(key); });\n\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t/** @module common */\n\t/**\n\t * Matches state names using glob-like patterns.\n\t *\n\t * See: [[StateService.includes]]\n\t */\n\tvar Glob = (function () {\n\t    function Glob(text) {\n\t        this.text = text;\n\t        this.glob = text.split('.');\n\t    }\n\t    Glob.prototype.matches = function (name) {\n\t        var segments = name.split('.');\n\t        // match single stars\n\t        for (var i = 0, l = this.glob.length; i < l; i++) {\n\t            if (this.glob[i] === '*')\n\t                segments[i] = '*';\n\t        }\n\t        // match greedy starts\n\t        if (this.glob[0] === '**') {\n\t            segments = segments.slice(segments.indexOf(this.glob[1]));\n\t            segments.unshift('**');\n\t        }\n\t        // match greedy ends\n\t        if (this.glob[this.glob.length - 1] === '**') {\n\t            segments.splice(segments.indexOf(this.glob[this.glob.length - 2]) + 1, Number.MAX_VALUE);\n\t            segments.push('**');\n\t        }\n\t        if (this.glob.length != segments.length)\n\t            return false;\n\t        return segments.join('') === this.glob.join('');\n\t    };\n\t    Glob.is = function (text) {\n\t        return text.indexOf('*') > -1;\n\t    };\n\t    Glob.fromString = function (text) {\n\t        if (!this.is(text))\n\t            return null;\n\t        return new Glob(text);\n\t    };\n\t    return Glob;\n\t}());\n\texports.Glob = Glob;\n\n\n/***/ },\n/* 8 */\n/***/ function(module, exports) {\n\n\t/** @module common */ /** for typedoc */\n\t\"use strict\";\n\tvar Queue = (function () {\n\t    function Queue(_items, _limit) {\n\t        if (_items === void 0) { _items = []; }\n\t        if (_limit === void 0) { _limit = null; }\n\t        this._items = _items;\n\t        this._limit = _limit;\n\t    }\n\t    Queue.prototype.enqueue = function (item) {\n\t        var items = this._items;\n\t        items.push(item);\n\t        if (this._limit && items.length > this._limit)\n\t            items.shift();\n\t        return item;\n\t    };\n\t    Queue.prototype.dequeue = function () {\n\t        if (this.size())\n\t            return this._items.splice(0, 1)[0];\n\t    };\n\t    Queue.prototype.clear = function () {\n\t        var current = this._items;\n\t        this._items = [];\n\t        return current;\n\t    };\n\t    Queue.prototype.size = function () {\n\t        return this._items.length;\n\t    };\n\t    Queue.prototype.remove = function (item) {\n\t        var idx = this._items.indexOf(item);\n\t        return idx > -1 && this._items.splice(idx, 1)[0];\n\t    };\n\t    Queue.prototype.peekTail = function () {\n\t        return this._items[this._items.length - 1];\n\t    };\n\t    Queue.prototype.peekHead = function () {\n\t        if (this.size())\n\t            return this._items[0];\n\t    };\n\t    return Queue;\n\t}());\n\texports.Queue = Queue;\n\n\n/***/ },\n/* 9 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module common_strings */ /** */\n\t\"use strict\";\n\tvar predicates_1 = __webpack_require__(4);\n\tvar rejectFactory_1 = __webpack_require__(10);\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar transition_1 = __webpack_require__(11);\n\tvar resolvable_1 = __webpack_require__(19);\n\t/**\n\t * Returns a string shortened to a maximum length\n\t *\n\t * If the string is already less than the `max` length, return the string.\n\t * Else return the string, shortened to `max - 3` and append three dots (\"...\").\n\t *\n\t * @param max the maximum length of the string to return\n\t * @param str the input string\n\t */\n\tfunction maxLength(max, str) {\n\t    if (str.length <= max)\n\t        return str;\n\t    return str.substr(0, max - 3) + \"...\";\n\t}\n\texports.maxLength = maxLength;\n\t/**\n\t * Returns a string, with spaces added to the end, up to a desired str length\n\t *\n\t * If the string is already longer than the desired length, return the string.\n\t * Else returns the string, with extra spaces on the end, such that it reaches `length` characters.\n\t *\n\t * @param length the desired length of the string to return\n\t * @param str the input string\n\t */\n\tfunction padString(length, str) {\n\t    while (str.length < length)\n\t        str += \" \";\n\t    return str;\n\t}\n\texports.padString = padString;\n\tfunction kebobString(camelCase) {\n\t    return camelCase\n\t        .replace(/^([A-Z])/, function ($1) { return $1.toLowerCase(); }) // replace first char\n\t        .replace(/([A-Z])/g, function ($1) { return \"-\" + $1.toLowerCase(); }); // replace rest\n\t}\n\texports.kebobString = kebobString;\n\tfunction _toJson(obj) {\n\t    return JSON.stringify(obj);\n\t}\n\tfunction _fromJson(json) {\n\t    return predicates_1.isString(json) ? JSON.parse(json) : json;\n\t}\n\tfunction promiseToString(p) {\n\t    return \"Promise(\" + JSON.stringify(p) + \")\";\n\t}\n\tfunction functionToString(fn) {\n\t    var fnStr = fnToString(fn);\n\t    var namedFunctionMatch = fnStr.match(/^(function [^ ]+\\([^)]*\\))/);\n\t    return namedFunctionMatch ? namedFunctionMatch[1] : fnStr;\n\t}\n\texports.functionToString = functionToString;\n\tfunction fnToString(fn) {\n\t    var _fn = predicates_1.isArray(fn) ? fn.slice(-1)[0] : fn;\n\t    return _fn && _fn.toString() || \"undefined\";\n\t}\n\texports.fnToString = fnToString;\n\tvar stringifyPatternFn = null;\n\tvar stringifyPattern = function (value) {\n\t    var isTransitionRejectionPromise = rejectFactory_1.Rejection.isTransitionRejectionPromise;\n\t    stringifyPatternFn = stringifyPatternFn || hof_1.pattern([\n\t        [hof_1.not(predicates_1.isDefined), hof_1.val(\"undefined\")],\n\t        [predicates_1.isNull, hof_1.val(\"null\")],\n\t        [predicates_1.isPromise, hof_1.val(\"[Promise]\")],\n\t        [isTransitionRejectionPromise, function (x) { return x._transitionRejection.toString(); }],\n\t        [hof_1.is(rejectFactory_1.Rejection), hof_1.invoke(\"toString\")],\n\t        [hof_1.is(transition_1.Transition), hof_1.invoke(\"toString\")],\n\t        [hof_1.is(resolvable_1.Resolvable), hof_1.invoke(\"toString\")],\n\t        [predicates_1.isInjectable, functionToString],\n\t        [hof_1.val(true), common_1.identity]\n\t    ]);\n\t    return stringifyPatternFn(value);\n\t};\n\tfunction stringify(o) {\n\t    var seen = [];\n\t    function format(val) {\n\t        if (predicates_1.isObject(val)) {\n\t            if (seen.indexOf(val) !== -1)\n\t                return '[circular ref]';\n\t            seen.push(val);\n\t        }\n\t        return stringifyPattern(val);\n\t    }\n\t    return JSON.stringify(o, function (key, val) { return format(val); }).replace(/\\\\\"/g, '\"');\n\t}\n\texports.stringify = stringify;\n\t/** Returns a function that splits a string on a character or substring */\n\texports.beforeAfterSubstr = function (char) { return function (str) {\n\t    if (!str)\n\t        return [\"\", \"\"];\n\t    var idx = str.indexOf(char);\n\t    if (idx === -1)\n\t        return [str, \"\"];\n\t    return [str.substr(0, idx), str.substr(idx + 1)];\n\t}; };\n\n\n/***/ },\n/* 10 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module transition */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar strings_1 = __webpack_require__(9);\n\t(function (RejectType) {\n\t    RejectType[RejectType[\"SUPERSEDED\"] = 2] = \"SUPERSEDED\";\n\t    RejectType[RejectType[\"ABORTED\"] = 3] = \"ABORTED\";\n\t    RejectType[RejectType[\"INVALID\"] = 4] = \"INVALID\";\n\t    RejectType[RejectType[\"IGNORED\"] = 5] = \"IGNORED\";\n\t    RejectType[RejectType[\"ERROR\"] = 6] = \"ERROR\";\n\t})(exports.RejectType || (exports.RejectType = {}));\n\tvar RejectType = exports.RejectType;\n\tvar Rejection = (function () {\n\t    function Rejection(type, message, detail) {\n\t        this.type = type;\n\t        this.message = message;\n\t        this.detail = detail;\n\t    }\n\t    Rejection.prototype.toString = function () {\n\t        var detailString = function (d) { return d && d.toString !== Object.prototype.toString ? d.toString() : strings_1.stringify(d); };\n\t        var type = this.type, message = this.message, detail = detailString(this.detail);\n\t        return \"TransitionRejection(type: \" + type + \", message: \" + message + \", detail: \" + detail + \")\";\n\t    };\n\t    Rejection.prototype.toPromise = function () {\n\t        return common_1.extend(common_1.silentRejection(this), { _transitionRejection: this });\n\t    };\n\t    /** Returns true if the obj is a rejected promise created from the `asPromise` factory */\n\t    Rejection.isTransitionRejectionPromise = function (obj) {\n\t        return obj && (typeof obj.then === 'function') && obj._transitionRejection instanceof Rejection;\n\t    };\n\t    /** Returns a TransitionRejection due to transition superseded */\n\t    Rejection.superseded = function (detail, options) {\n\t        var message = \"The transition has been superseded by a different transition (see detail).\";\n\t        var rejection = new Rejection(RejectType.SUPERSEDED, message, detail);\n\t        if (options && options.redirected) {\n\t            rejection.redirected = true;\n\t        }\n\t        return rejection;\n\t    };\n\t    /** Returns a TransitionRejection due to redirected transition */\n\t    Rejection.redirected = function (detail) {\n\t        return Rejection.superseded(detail, { redirected: true });\n\t    };\n\t    /** Returns a TransitionRejection due to invalid transition */\n\t    Rejection.invalid = function (detail) {\n\t        var message = \"This transition is invalid (see detail)\";\n\t        return new Rejection(RejectType.INVALID, message, detail);\n\t    };\n\t    /** Returns a TransitionRejection due to ignored transition */\n\t    Rejection.ignored = function (detail) {\n\t        var message = \"The transition was ignored.\";\n\t        return new Rejection(RejectType.IGNORED, message, detail);\n\t    };\n\t    /** Returns a TransitionRejection due to aborted transition */\n\t    Rejection.aborted = function (detail) {\n\t        // TODO think about how to encapsulate an Error() object\n\t        var message = \"The transition has been aborted.\";\n\t        return new Rejection(RejectType.ABORTED, message, detail);\n\t    };\n\t    /** Returns a TransitionRejection due to aborted transition */\n\t    Rejection.errored = function (detail) {\n\t        // TODO think about how to encapsulate an Error() object\n\t        var message = \"The transition errored.\";\n\t        return new Rejection(RejectType.ERROR, message, detail);\n\t    };\n\t    return Rejection;\n\t}());\n\texports.Rejection = Rejection;\n\n\n/***/ },\n/* 11 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module transition */ /** for typedoc */\n\tvar trace_1 = __webpack_require__(12);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\tvar transitionHook_1 = __webpack_require__(13);\n\tvar hookRegistry_1 = __webpack_require__(15);\n\tvar hookBuilder_1 = __webpack_require__(16);\n\tvar node_1 = __webpack_require__(21);\n\tvar pathFactory_1 = __webpack_require__(20);\n\tvar targetState_1 = __webpack_require__(14);\n\tvar param_1 = __webpack_require__(22);\n\tvar resolvable_1 = __webpack_require__(19);\n\tvar rejectFactory_1 = __webpack_require__(10);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar router_1 = __webpack_require__(26);\n\tvar transitionCount = 0;\n\tvar stateSelf = hof_1.prop(\"self\");\n\t/**\n\t * Represents a transition between two states.\n\t *\n\t * When navigating to a state, we are transitioning **from** the current state **to** the new state.\n\t *\n\t * This object contains all contextual information about the to/from states, parameters, resolves.\n\t * It has information about all states being entered and exited as a result of the transition.\n\t */\n\tvar Transition = (function () {\n\t    /**\n\t     * Creates a new Transition object.\n\t     *\n\t     * If the target state is not valid, an error is thrown.\n\t     *\n\t     * @param fromPath The path of [[PathNode]]s from which the transition is leaving.  The last node in the `fromPath`\n\t     *        encapsulates the \"from state\".\n\t     * @param targetState The target state and parameters being transitioned to (also, the transition options)\n\t     * @param router The [[UIRouter]] instance\n\t     */\n\t    function Transition(fromPath, targetState, router) {\n\t        var _this = this;\n\t        /** @hidden */\n\t        this._deferred = coreservices_1.services.$q.defer();\n\t        /**\n\t         * This promise is resolved or rejected based on the outcome of the Transition.\n\t         *\n\t         * When the transition is successful, the promise is resolved\n\t         * When the transition is unsuccessful, the promise is rejected with the [[TransitionRejection]] or javascript error\n\t         */\n\t        this.promise = this._deferred.promise;\n\t        this.treeChanges = function () { return _this._treeChanges; };\n\t        this.isActive = function () { return _this === _this._options.current(); };\n\t        this.router = router;\n\t        if (!targetState.valid()) {\n\t            throw new Error(targetState.error());\n\t        }\n\t        // Makes the Transition instance a hook registry (onStart, etc)\n\t        hookRegistry_1.HookRegistry.mixin(new hookRegistry_1.HookRegistry(), this);\n\t        // current() is assumed to come from targetState.options, but provide a naive implementation otherwise.\n\t        this._options = common_1.extend({ current: hof_1.val(this) }, targetState.options());\n\t        this.$id = transitionCount++;\n\t        var toPath = pathFactory_1.PathFactory.buildToPath(fromPath, targetState);\n\t        this._treeChanges = pathFactory_1.PathFactory.treeChanges(fromPath, toPath, this._options.reloadState);\n\t        var enteringStates = this._treeChanges.entering.map(function (node) { return node.state; });\n\t        pathFactory_1.PathFactory.applyViewConfigs(router.transitionService.$view, this._treeChanges.to, enteringStates);\n\t        var rootResolvables = [\n\t            new resolvable_1.Resolvable(router_1.UIRouter, function () { return router; }, [], undefined, router),\n\t            new resolvable_1.Resolvable(Transition, function () { return _this; }, [], undefined, this),\n\t            new resolvable_1.Resolvable('$transition$', function () { return _this; }, [], undefined, this),\n\t            new resolvable_1.Resolvable('$stateParams', function () { return _this.params(); }, [], undefined, this.params())\n\t        ];\n\t        var rootNode = this._treeChanges.to[0];\n\t        var context = new resolveContext_1.ResolveContext(this._treeChanges.to);\n\t        context.addResolvables(rootResolvables, rootNode.state);\n\t    }\n\t    /** @inheritdoc */\n\t    Transition.prototype.onBefore = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onStart = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onExit = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onRetain = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onEnter = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onFinish = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onSuccess = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    Transition.prototype.onError = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    Transition.prototype.$from = function () {\n\t        return common_1.tail(this._treeChanges.from).state;\n\t    };\n\t    Transition.prototype.$to = function () {\n\t        return common_1.tail(this._treeChanges.to).state;\n\t    };\n\t    /**\n\t     * Returns the \"from state\"\n\t     *\n\t     * @returns The state object for the Transition's \"from state\".\n\t     */\n\t    Transition.prototype.from = function () {\n\t        return this.$from().self;\n\t    };\n\t    /**\n\t     * Returns the \"to state\"\n\t     *\n\t     * @returns The state object for the Transition's target state (\"to state\").\n\t     */\n\t    Transition.prototype.to = function () {\n\t        return this.$to().self;\n\t    };\n\t    /**\n\t     * Determines whether two transitions are equivalent.\n\t     */\n\t    Transition.prototype.is = function (compare) {\n\t        if (compare instanceof Transition) {\n\t            // TODO: Also compare parameters\n\t            return this.is({ to: compare.$to().name, from: compare.$from().name });\n\t        }\n\t        return !((compare.to && !hookRegistry_1.matchState(this.$to(), compare.to)) ||\n\t            (compare.from && !hookRegistry_1.matchState(this.$from(), compare.from)));\n\t    };\n\t    /**\n\t     * Gets transition parameter values\n\t     *\n\t     * @param pathname Pick which treeChanges path to get parameters for:\n\t     *   (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`)\n\t     * @returns transition parameter values for the desired path.\n\t     */\n\t    Transition.prototype.params = function (pathname) {\n\t        if (pathname === void 0) { pathname = \"to\"; }\n\t        return this._treeChanges[pathname].map(hof_1.prop(\"paramValues\")).reduce(common_1.mergeR, {});\n\t    };\n\t    /**\n\t     * Creates a [[UIInjector]] Dependency Injector\n\t     *\n\t     * Returns a Dependency Injector for the Transition's target state (to state).\n\t     * The injector provides resolve values which the target state has access to.\n\t     *\n\t     * The `UIInjector` can also provide values from the native root/global injector (ng1/ng2).\n\t     *\n\t     * If a `state` is provided, the injector that is returned will be limited to resolve values that the provided state has access to.\n\t     *\n\t     * @param state Limits the resolves provided to only the resolves the provided state has access to.\n\t     * @returns a [[UIInjector]]\n\t     */\n\t    Transition.prototype.injector = function (state) {\n\t        var path = this.treeChanges().to;\n\t        if (state)\n\t            path = pathFactory_1.PathFactory.subPath(path, function (node) { return node.state === state || node.state.name === state; });\n\t        return new resolveContext_1.ResolveContext(path).injector();\n\t    };\n\t    /**\n\t     * Gets all available resolve tokens (keys)\n\t     *\n\t     * This method can be used in conjunction with [[getResolve]] to inspect the resolve values\n\t     * available to the Transition.\n\t     *\n\t     * The returned tokens include those defined on [[StateDeclaration.resolve]] blocks, for the states\n\t     * in the Transition's [[TreeChanges.to]] path.\n\t     *\n\t     * @returns an array of resolve tokens (keys)\n\t     */\n\t    Transition.prototype.getResolveTokens = function () {\n\t        return new resolveContext_1.ResolveContext(this._treeChanges.to).getTokens();\n\t    };\n\t    /**\n\t     * Gets resolved values\n\t     *\n\t     * This method can be used in conjunction with [[getResolveTokens]] to inspect what resolve values\n\t     * are available to the Transition.\n\t     *\n\t     * Given a token, returns the resolved data for that token.\n\t     * Given an array of tokens, returns an array of resolved data for those tokens.\n\t     *\n\t     * If a resolvable hasn't yet been fetched, returns `undefined` for that token\n\t     * If a resolvable doesn't exist for the token, throws an error.\n\t     *\n\t     * @param token the token (or array of tokens)\n\t     *\n\t     * @returns an array of resolve tokens (keys)\n\t     */\n\t    Transition.prototype.getResolveValue = function (token) {\n\t        var resolveContext = new resolveContext_1.ResolveContext(this._treeChanges.to);\n\t        var getData = function (token) {\n\t            var resolvable = resolveContext.getResolvable(token);\n\t            if (resolvable === undefined) {\n\t                throw new Error(\"Dependency Injection token not found: ${stringify(token)}\");\n\t            }\n\t            return resolvable.data;\n\t        };\n\t        if (predicates_1.isArray(token)) {\n\t            return token.map(getData);\n\t        }\n\t        return getData(token);\n\t    };\n\t    /**\n\t     * Dynamically adds a new [[Resolvable]] (`resolve`) to this transition.\n\t     *\n\t     * @param resolvable an [[Resolvable]] object\n\t     * @param state the state in the \"to path\" which should receive the new resolve (otherwise, the root state)\n\t     */\n\t    Transition.prototype.addResolvable = function (resolvable, state) {\n\t        if (state === void 0) { state = \"\"; }\n\t        var stateName = (typeof state === \"string\") ? state : state.name;\n\t        var topath = this._treeChanges.to;\n\t        var targetNode = common_1.find(topath, function (node) { return node.state.name === stateName; });\n\t        var resolveContext = new resolveContext_1.ResolveContext(topath);\n\t        resolveContext.addResolvables([resolvable], targetNode.state);\n\t    };\n\t    /**\n\t     * Gets the previous transition, from which this transition was redirected.\n\t     *\n\t     * @returns The previous Transition, or null if this Transition is not the result of a redirection\n\t     */\n\t    Transition.prototype.previous = function () {\n\t        return this._options.previous || null;\n\t    };\n\t    /**\n\t     * Get the transition options\n\t     *\n\t     * @returns the options for this Transition.\n\t     */\n\t    Transition.prototype.options = function () {\n\t        return this._options;\n\t    };\n\t    /**\n\t     * Gets the states being entered.\n\t     *\n\t     * @returns an array of states that will be entered during this transition.\n\t     */\n\t    Transition.prototype.entering = function () {\n\t        return common_1.map(this._treeChanges.entering, hof_1.prop('state')).map(stateSelf);\n\t    };\n\t    /**\n\t     * Gets the states being exited.\n\t     *\n\t     * @returns an array of states that will be exited during this transition.\n\t     */\n\t    Transition.prototype.exiting = function () {\n\t        return common_1.map(this._treeChanges.exiting, hof_1.prop('state')).map(stateSelf).reverse();\n\t    };\n\t    /**\n\t     * Gets the states being retained.\n\t     *\n\t     * @returns an array of states that are already entered from a previous Transition, that will not be\n\t     *    exited during this Transition\n\t     */\n\t    Transition.prototype.retained = function () {\n\t        return common_1.map(this._treeChanges.retained, hof_1.prop('state')).map(stateSelf);\n\t    };\n\t    /**\n\t     * Get the [[ViewConfig]]s associated with this Transition\n\t     *\n\t     * Each state can define one or more views (template/controller), which are encapsulated as `ViewConfig` objects.\n\t     * This method fetches the `ViewConfigs` for a given path in the Transition (e.g., \"to\" or \"entering\").\n\t     *\n\t     * @param pathname the name of the path to fetch views for:\n\t     *   (`'to'`, `'from'`, `'entering'`, `'exiting'`, `'retained'`)\n\t     * @param state If provided, only returns the `ViewConfig`s for a single state in the path\n\t     *\n\t     * @returns a list of ViewConfig objects for the given path.\n\t     */\n\t    Transition.prototype.views = function (pathname, state) {\n\t        if (pathname === void 0) { pathname = \"entering\"; }\n\t        var path = this._treeChanges[pathname];\n\t        path = !state ? path : path.filter(hof_1.propEq('state', state));\n\t        return path.map(hof_1.prop(\"views\")).filter(common_1.identity).reduce(common_1.unnestR, []);\n\t    };\n\t    /**\n\t     * Creates a new transition that is a redirection of the current one.\n\t     *\n\t     * This transition can be returned from a [[TransitionService]] hook to\n\t     * redirect a transition to a new state and/or set of parameters.\n\t     *\n\t     * @returns Returns a new [[Transition]] instance.\n\t     */\n\t    Transition.prototype.redirect = function (targetState) {\n\t        var newOptions = common_1.extend({}, this.options(), targetState.options(), { previous: this });\n\t        targetState = new targetState_1.TargetState(targetState.identifier(), targetState.$state(), targetState.params(), newOptions);\n\t        var newTransition = this.router.transitionService.create(this._treeChanges.from, targetState);\n\t        var originalEnteringNodes = this.treeChanges().entering;\n\t        var redirectEnteringNodes = newTransition.treeChanges().entering;\n\t        // --- Re-use resolve data from original transition ---\n\t        // When redirecting from a parent state to a child state where the parent parameter values haven't changed\n\t        // (because of the redirect), the resolves fetched by the original transition are still valid in the\n\t        // redirected transition.\n\t        //\n\t        // This allows you to define a redirect on a parent state which depends on an async resolve value.\n\t        // You can wait for the resolve, then redirect to a child state based on the result.\n\t        // The redirected transition does not have to re-fetch the resolve.\n\t        // ---------------------------------------------------------\n\t        var nodeIsReloading = function (reloadState) { return function (node) {\n\t            return reloadState && node.state.includes[reloadState.name];\n\t        }; };\n\t        // Find any \"entering\" nodes in the redirect path that match the original path and aren't being reloaded\n\t        var matchingEnteringNodes = node_1.PathNode.matching(redirectEnteringNodes, originalEnteringNodes)\n\t            .filter(hof_1.not(nodeIsReloading(targetState.options().reloadState)));\n\t        // Use the existing (possibly pre-resolved) resolvables for the matching entering nodes.\n\t        matchingEnteringNodes.forEach(function (node, idx) {\n\t            node.resolvables = originalEnteringNodes[idx].resolvables;\n\t        });\n\t        return newTransition;\n\t    };\n\t    /** @hidden If a transition doesn't exit/enter any states, returns any [[Param]] whose value changed */\n\t    Transition.prototype._changedParams = function () {\n\t        var _a = this._treeChanges, to = _a.to, from = _a.from;\n\t        if (this._options.reload || common_1.tail(to).state !== common_1.tail(from).state)\n\t            return undefined;\n\t        var nodeSchemas = to.map(function (node) { return node.paramSchema; });\n\t        var _b = [to, from].map(function (path) { return path.map(function (x) { return x.paramValues; }); }), toValues = _b[0], fromValues = _b[1];\n\t        var tuples = common_1.arrayTuples(nodeSchemas, toValues, fromValues);\n\t        return tuples.map(function (_a) {\n\t            var schema = _a[0], toVals = _a[1], fromVals = _a[2];\n\t            return param_1.Param.changed(schema, toVals, fromVals);\n\t        }).reduce(common_1.unnestR, []);\n\t    };\n\t    /**\n\t     * Returns true if the transition is dynamic.\n\t     *\n\t     * A transition is dynamic if no states are entered nor exited, but at least one dynamic parameter has changed.\n\t     *\n\t     * @returns true if the Transition is dynamic\n\t     */\n\t    Transition.prototype.dynamic = function () {\n\t        var changes = this._changedParams();\n\t        return !changes ? false : changes.map(function (x) { return x.dynamic; }).reduce(common_1.anyTrueR, false);\n\t    };\n\t    /**\n\t     * Returns true if the transition is ignored.\n\t     *\n\t     * A transition is ignored if no states are entered nor exited, and no parameter values have changed.\n\t     *\n\t     * @returns true if the Transition is ignored.\n\t     */\n\t    Transition.prototype.ignored = function () {\n\t        var changes = this._changedParams();\n\t        return !changes ? false : changes.length === 0;\n\t    };\n\t    /**\n\t     * @hidden\n\t     */\n\t    Transition.prototype.hookBuilder = function () {\n\t        return new hookBuilder_1.HookBuilder(this.router.transitionService, this, {\n\t            transition: this,\n\t            current: this._options.current\n\t        });\n\t    };\n\t    /**\n\t     * Runs the transition\n\t     *\n\t     * This method is generally called from the [[StateService.transitionTo]]\n\t     *\n\t     * @returns a promise for a successful transition.\n\t     */\n\t    Transition.prototype.run = function () {\n\t        var _this = this;\n\t        var runSynchronousHooks = transitionHook_1.TransitionHook.runSynchronousHooks;\n\t        var hookBuilder = this.hookBuilder();\n\t        var globals = this.router.globals;\n\t        globals.transitionHistory.enqueue(this);\n\t        var syncResult = runSynchronousHooks(hookBuilder.getOnBeforeHooks());\n\t        if (rejectFactory_1.Rejection.isTransitionRejectionPromise(syncResult)) {\n\t            syncResult.catch(function () { return 0; }); // issue #2676\n\t            var rejectReason = syncResult._transitionRejection;\n\t            this._deferred.reject(rejectReason);\n\t            return this.promise;\n\t        }\n\t        if (!this.valid()) {\n\t            var error = new Error(this.error());\n\t            this._deferred.reject(error);\n\t            return this.promise;\n\t        }\n\t        if (this.ignored()) {\n\t            trace_1.trace.traceTransitionIgnored(this);\n\t            this._deferred.reject(rejectFactory_1.Rejection.ignored());\n\t            return this.promise;\n\t        }\n\t        // When the chain is complete, then resolve or reject the deferred\n\t        var transitionSuccess = function () {\n\t            trace_1.trace.traceSuccess(_this.$to(), _this);\n\t            _this.success = true;\n\t            _this._deferred.resolve(_this.to());\n\t            runSynchronousHooks(hookBuilder.getOnSuccessHooks(), true);\n\t        };\n\t        var transitionError = function (error) {\n\t            trace_1.trace.traceError(error, _this);\n\t            _this.success = false;\n\t            _this._deferred.reject(error);\n\t            runSynchronousHooks(hookBuilder.getOnErrorHooks(), true);\n\t        };\n\t        trace_1.trace.traceTransitionStart(this);\n\t        // Chain the next hook off the previous\n\t        var appendHookToChain = function (prev, nextHook) {\n\t            return prev.then(function () { return nextHook.invokeHook(); });\n\t        };\n\t        // Run the hooks, then resolve or reject the overall deferred in the .then() handler\n\t        hookBuilder.asyncHooks()\n\t            .reduce(appendHookToChain, syncResult)\n\t            .then(transitionSuccess, transitionError);\n\t        return this.promise;\n\t    };\n\t    /**\n\t     * Checks if the Transition is valid\n\t     *\n\t     * @returns true if the Transition is valid\n\t     */\n\t    Transition.prototype.valid = function () {\n\t        return !this.error();\n\t    };\n\t    /**\n\t     * The reason the Transition is invalid\n\t     *\n\t     * @returns an error message explaining why the transition is invalid\n\t     */\n\t    Transition.prototype.error = function () {\n\t        var state = this.$to();\n\t        if (state.self[common_1.abstractKey])\n\t            return \"Cannot transition to abstract state '\" + state.name + \"'\";\n\t        if (!param_1.Param.validates(state.parameters(), this.params()))\n\t            return \"Param values not valid for state '\" + state.name + \"'\";\n\t    };\n\t    /**\n\t     * A string representation of the Transition\n\t     *\n\t     * @returns A string representation of the Transition\n\t     */\n\t    Transition.prototype.toString = function () {\n\t        var fromStateOrName = this.from();\n\t        var toStateOrName = this.to();\n\t        var avoidEmptyHash = function (params) {\n\t            return (params[\"#\"] !== null && params[\"#\"] !== undefined) ? params : common_1.omit(params, \"#\");\n\t        };\n\t        // (X) means the to state is invalid.\n\t        var id = this.$id, from = predicates_1.isObject(fromStateOrName) ? fromStateOrName.name : fromStateOrName, fromParams = common_1.toJson(avoidEmptyHash(this._treeChanges.from.map(hof_1.prop('paramValues')).reduce(common_1.mergeR, {}))), toValid = this.valid() ? \"\" : \"(X) \", to = predicates_1.isObject(toStateOrName) ? toStateOrName.name : toStateOrName, toParams = common_1.toJson(avoidEmptyHash(this.params()));\n\t        return \"Transition#\" + id + \"( '\" + from + \"'\" + fromParams + \" -> \" + toValid + \"'\" + to + \"'\" + toParams + \" )\";\n\t    };\n\t    Transition.diToken = Transition;\n\t    return Transition;\n\t}());\n\texports.Transition = Transition;\n\n\n/***/ },\n/* 12 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/**\n\t * UI-Router Transition Tracing\n\t *\n\t * Enable transition tracing to print transition information to the console, in order to help debug your application.\n\t * Tracing logs detailed information about each Transition to your console.\n\t *\n\t * To enable tracing, import the [[trace]] singleton and enable one or more categories.\n\t *\n\t * ES6\n\t * ```\n\t *\n\t * import {trace} from \"ui-router-ng2\"; // or \"angular-ui-router\"\n\t * trace.enable(1, 5); // TRANSITION and VIEWCONFIG\n\t * ```\n\t *\n\t * CJS\n\t * ```\n\t *\n\t * let trace = require(\"angular-ui-router\").trace; // or \"ui-router-ng2\"\n\t * trace.enable(\"TRANSITION\", \"VIEWCONFIG\");\n\t * ```\n\t *\n\t * Globals\n\t * ```\n\t *\n\t * let trace = window[\"angular-ui-router\"].trace; // or \"ui-router-ng2\"\n\t * trace.enable(); // Trace everything (very verbose)\n\t * ```\n\t *\n\t * @module trace\n\t */ /** for typedoc */\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar strings_1 = __webpack_require__(9);\n\t/** @hidden */\n\tfunction uiViewString(viewData) {\n\t    if (!viewData)\n\t        return 'ui-view (defunct)';\n\t    return (\"[ui-view#\" + viewData.id + \" tag \") +\n\t        (\"in template from '\" + (viewData.creationContext && viewData.creationContext.name || '(root)') + \"' state]: \") +\n\t        (\"fqn: '\" + viewData.fqn + \"', \") +\n\t        (\"name: '\" + viewData.name + \"@\" + viewData.creationContext + \"')\");\n\t}\n\t/** @hidden */\n\tvar viewConfigString = function (viewConfig) {\n\t    return (\"[ViewConfig#\" + viewConfig.$id + \" from '\" + (viewConfig.viewDecl.$context.name || '(root)') + \"' state]: target ui-view: '\" + viewConfig.viewDecl.$uiViewName + \"@\" + viewConfig.viewDecl.$uiViewContextAnchor + \"'\");\n\t};\n\t/** @hidden */\n\tfunction normalizedCat(input) {\n\t    return predicates_1.isNumber(input) ? Category[input] : Category[Category[input]];\n\t}\n\t/**\n\t * Trace categories\n\t *\n\t * [[Trace.enable]] or [[Trace.disable]] a category\n\t *\n\t * `trace.enable(Category.TRANSITION)`\n\t *\n\t * These can also be provided using a matching string, or position ordinal\n\t *\n\t * `trace.enable(\"TRANSITION\")`\n\t *\n\t * `trace.enable(1)`\n\t */\n\t(function (Category) {\n\t    Category[Category[\"RESOLVE\"] = 0] = \"RESOLVE\";\n\t    Category[Category[\"TRANSITION\"] = 1] = \"TRANSITION\";\n\t    Category[Category[\"HOOK\"] = 2] = \"HOOK\";\n\t    Category[Category[\"INVOKE\"] = 3] = \"INVOKE\";\n\t    Category[Category[\"UIVIEW\"] = 4] = \"UIVIEW\";\n\t    Category[Category[\"VIEWCONFIG\"] = 5] = \"VIEWCONFIG\";\n\t})(exports.Category || (exports.Category = {}));\n\tvar Category = exports.Category;\n\t/**\n\t * Prints UI-Router Transition trace information to the console.\n\t */\n\tvar Trace = (function () {\n\t    function Trace() {\n\t        /** @hidden */\n\t        this._enabled = {};\n\t        this.approximateDigests = 0;\n\t    }\n\t    /** @hidden */\n\t    Trace.prototype._set = function (enabled, categories) {\n\t        var _this = this;\n\t        if (!categories.length) {\n\t            categories = Object.keys(Category)\n\t                .filter(function (k) { return isNaN(parseInt(k, 10)); })\n\t                .map(function (key) { return Category[key]; });\n\t        }\n\t        categories.map(normalizedCat).forEach(function (category) { return _this._enabled[category] = enabled; });\n\t    };\n\t    /**\n\t     * Enables a trace [[Category]]\n\t     *\n\t     * ```\n\t     * trace.enable(\"TRANSITION\");\n\t     * ```\n\t     *\n\t     * @param categories categories to enable. If `categories` is omitted, all categories are enabled.\n\t     *        Also takes strings (category name) or ordinal (category position)\n\t     */\n\t    Trace.prototype.enable = function () {\n\t        var categories = [];\n\t        for (var _i = 0; _i < arguments.length; _i++) {\n\t            categories[_i - 0] = arguments[_i];\n\t        }\n\t        this._set(true, categories);\n\t    };\n\t    /**\n\t     * Disables a trace [[Category]]\n\t     *\n\t     * ```\n\t     * trace.disable(\"VIEWCONFIG\");\n\t     * ```\n\t     *\n\t     * @param categories categories to disable. If `categories` is omitted, all categories are disabled.\n\t     *        Also takes strings (category name) or ordinal (category position)\n\t     */\n\t    Trace.prototype.disable = function () {\n\t        var categories = [];\n\t        for (var _i = 0; _i < arguments.length; _i++) {\n\t            categories[_i - 0] = arguments[_i];\n\t        }\n\t        this._set(false, categories);\n\t    };\n\t    /**\n\t     * Retrieves the enabled stateus of a [[Category]]\n\t     *\n\t     * ```\n\t     * trace.enabled(\"VIEWCONFIG\"); // true or false\n\t     * ```\n\t     *\n\t     * @returns boolean true if the category is enabled\n\t     */\n\t    Trace.prototype.enabled = function (category) {\n\t        return !!this._enabled[normalizedCat(category)];\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceTransitionStart = function (transition) {\n\t        if (!this.enabled(Category.TRANSITION))\n\t            return;\n\t        var tid = transition.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(transition);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \": Started  -> \" + transitionStr);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceTransitionIgnored = function (trans) {\n\t        if (!this.enabled(Category.TRANSITION))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(trans);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \": Ignored  <> \" + transitionStr);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceHookInvocation = function (step, options) {\n\t        if (!this.enabled(Category.HOOK))\n\t            return;\n\t        var tid = hof_1.parse(\"transition.$id\")(options), digest = this.approximateDigests, event = hof_1.parse(\"traceData.hookType\")(options) || \"internal\", context = hof_1.parse(\"traceData.context.state.name\")(options) || hof_1.parse(\"traceData.context\")(options) || \"unknown\", name = strings_1.functionToString(step.fn);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \":   Hook -> \" + event + \" context: \" + context + \", \" + strings_1.maxLength(200, name));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceHookResult = function (hookResult, transitionResult, transitionOptions) {\n\t        if (!this.enabled(Category.HOOK))\n\t            return;\n\t        var tid = hof_1.parse(\"transition.$id\")(transitionOptions), digest = this.approximateDigests, hookResultStr = strings_1.stringify(hookResult), transitionResultStr = strings_1.stringify(transitionResult);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \":   <- Hook returned: \" + strings_1.maxLength(200, hookResultStr) + \", transition result: \" + strings_1.maxLength(200, transitionResultStr));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceResolvePath = function (path, when, trans) {\n\t        if (!this.enabled(Category.RESOLVE))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, pathStr = path && path.toString();\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \":         Resolving \" + pathStr + \" (\" + when + \")\");\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceResolvableResolved = function (resolvable, trans) {\n\t        if (!this.enabled(Category.RESOLVE))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, resolvableStr = resolvable && resolvable.toString(), result = strings_1.stringify(resolvable.data);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \":               <- Resolved  \" + resolvableStr + \" to: \" + strings_1.maxLength(200, result));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceError = function (error, trans) {\n\t        if (!this.enabled(Category.TRANSITION))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, transitionStr = strings_1.stringify(trans);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \": <- Rejected \" + transitionStr + \", reason: \" + error);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceSuccess = function (finalState, trans) {\n\t        if (!this.enabled(Category.TRANSITION))\n\t            return;\n\t        var tid = trans && trans.$id, digest = this.approximateDigests, state = finalState.name, transitionStr = strings_1.stringify(trans);\n\t        console.log(\"Transition #\" + tid + \" Digest #\" + digest + \": <- Success  \" + transitionStr + \", final state: \" + state);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceUIViewEvent = function (event, viewData, extra) {\n\t        if (extra === void 0) { extra = \"\"; }\n\t        if (!this.enabled(Category.UIVIEW))\n\t            return;\n\t        console.log(\"ui-view: \" + strings_1.padString(30, event) + \" \" + uiViewString(viewData) + extra);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceUIViewConfigUpdated = function (viewData, context) {\n\t        if (!this.enabled(Category.UIVIEW))\n\t            return;\n\t        this.traceUIViewEvent(\"Updating\", viewData, \" with ViewConfig from context='\" + context + \"'\");\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceUIViewScopeCreated = function (viewData, newScope) {\n\t        if (!this.enabled(Category.UIVIEW))\n\t            return;\n\t        this.traceUIViewEvent(\"Created scope for\", viewData, \", scope #\" + newScope.$id);\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceUIViewFill = function (viewData, html) {\n\t        if (!this.enabled(Category.UIVIEW))\n\t            return;\n\t        this.traceUIViewEvent(\"Fill\", viewData, \" with: \" + strings_1.maxLength(200, html));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceViewServiceEvent = function (event, viewConfig) {\n\t        if (!this.enabled(Category.VIEWCONFIG))\n\t            return;\n\t        console.log(\"VIEWCONFIG: \" + event + \" \" + viewConfigString(viewConfig));\n\t    };\n\t    /** called by ui-router code */\n\t    Trace.prototype.traceViewServiceUIViewEvent = function (event, viewData) {\n\t        if (!this.enabled(Category.VIEWCONFIG))\n\t            return;\n\t        console.log(\"VIEWCONFIG: \" + event + \" \" + uiViewString(viewData));\n\t    };\n\t    return Trace;\n\t}());\n\texports.Trace = Trace;\n\t/**\n\t * The [[Trace]] singleton\n\t *\n\t * @example\n\t * ```js\n\t *\n\t * import {trace} from \"angular-ui-router\";\n\t * trace.enable(1, 5);\n\t * ```\n\t */\n\tvar trace = new Trace();\n\texports.trace = trace;\n\n\n/***/ },\n/* 13 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar strings_1 = __webpack_require__(9);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\tvar trace_1 = __webpack_require__(12);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar rejectFactory_1 = __webpack_require__(10);\n\tvar targetState_1 = __webpack_require__(14);\n\tvar defaultOptions = {\n\t    async: true,\n\t    rejectIfSuperseded: true,\n\t    current: common_1.noop,\n\t    transition: null,\n\t    traceData: {},\n\t    bind: null\n\t};\n\t/** @hidden */\n\tvar TransitionHook = (function () {\n\t    function TransitionHook(transition, stateContext, hookFn, resolveContext, options) {\n\t        var _this = this;\n\t        this.transition = transition;\n\t        this.stateContext = stateContext;\n\t        this.hookFn = hookFn;\n\t        this.resolveContext = resolveContext;\n\t        this.options = options;\n\t        this.isSuperseded = function () { return _this.options.current() !== _this.options.transition; };\n\t        this.options = common_1.defaults(options, defaultOptions);\n\t    }\n\t    TransitionHook.prototype.invokeHook = function () {\n\t        var _a = this, options = _a.options, hookFn = _a.hookFn, resolveContext = _a.resolveContext;\n\t        trace_1.trace.traceHookInvocation(this, options);\n\t        if (options.rejectIfSuperseded && this.isSuperseded()) {\n\t            return rejectFactory_1.Rejection.superseded(options.current()).toPromise();\n\t        }\n\t        var hookResult = hookFn.call(options.bind, this.transition, this.stateContext);\n\t        return this.handleHookResult(hookResult);\n\t    };\n\t    /**\n\t     * This method handles the return value of a Transition Hook.\n\t     *\n\t     * A hook can return false, a redirect (TargetState), or a promise (which may resolve to false or a redirect)\n\t     */\n\t    TransitionHook.prototype.handleHookResult = function (hookResult) {\n\t        var _this = this;\n\t        if (!predicates_1.isDefined(hookResult))\n\t            return undefined;\n\t        /**\n\t         * Handles transition superseded, transition aborted and transition redirect.\n\t         */\n\t        var mapHookResult = hof_1.pattern([\n\t            // Transition is no longer current\n\t            [this.isSuperseded, function () { return rejectFactory_1.Rejection.superseded(_this.options.current()).toPromise(); }],\n\t            // If the hook returns false, abort the current Transition\n\t            [hof_1.eq(false), function () { return rejectFactory_1.Rejection.aborted(\"Hook aborted transition\").toPromise(); }],\n\t            // If the hook returns a Transition, halt the current Transition and redirect to that Transition.\n\t            [hof_1.is(targetState_1.TargetState), function (target) { return rejectFactory_1.Rejection.redirected(target).toPromise(); }],\n\t            // A promise was returned, wait for the promise and then chain another hookHandler\n\t            [predicates_1.isPromise, function (promise) { return promise.then(_this.handleHookResult.bind(_this)); }]\n\t        ]);\n\t        var transitionResult = mapHookResult(hookResult);\n\t        if (transitionResult)\n\t            trace_1.trace.traceHookResult(hookResult, transitionResult, this.options);\n\t        return transitionResult;\n\t    };\n\t    TransitionHook.prototype.toString = function () {\n\t        var _a = this, options = _a.options, hookFn = _a.hookFn;\n\t        var event = hof_1.parse(\"traceData.hookType\")(options) || \"internal\", context = hof_1.parse(\"traceData.context.state.name\")(options) || hof_1.parse(\"traceData.context\")(options) || \"unknown\", name = strings_1.fnToString(hookFn);\n\t        return event + \" context: \" + context + \", \" + strings_1.maxLength(200, name);\n\t    };\n\t    /**\n\t     * Given an array of TransitionHooks, runs each one synchronously and sequentially.\n\t     *\n\t     * Returns a promise chain composed of any promises returned from each hook.invokeStep() call\n\t     */\n\t    TransitionHook.runSynchronousHooks = function (hooks, swallowExceptions) {\n\t        if (swallowExceptions === void 0) { swallowExceptions = false; }\n\t        var results = [];\n\t        for (var i = 0; i < hooks.length; i++) {\n\t            try {\n\t                results.push(hooks[i].invokeHook());\n\t            }\n\t            catch (exception) {\n\t                if (!swallowExceptions) {\n\t                    return rejectFactory_1.Rejection.errored(exception).toPromise();\n\t                }\n\t                console.error(\"Swallowed exception during synchronous hook handler: \" + exception); // TODO: What to do here?\n\t            }\n\t        }\n\t        var rejections = results.filter(rejectFactory_1.Rejection.isTransitionRejectionPromise);\n\t        if (rejections.length)\n\t            return rejections[0];\n\t        return results\n\t            .filter(predicates_1.isPromise)\n\t            .reduce(function (chain, promise) { return chain.then(hof_1.val(promise)); }, coreservices_1.services.$q.when());\n\t    };\n\t    return TransitionHook;\n\t}());\n\texports.TransitionHook = TransitionHook;\n\n\n/***/ },\n/* 14 */\n/***/ function(module, exports) {\n\n\t/** @module state */ /** for typedoc */\n\t\"use strict\";\n\t/**\n\t * @ngdoc object\n\t * @name ui.router.state.type:TargetState\n\t *\n\t * @description\n\t * Encapsulate the desired target of a transition.\n\t * Wraps an identifier for a state, a set of parameters, and transition options with the definition of the state.\n\t *\n\t * @param {StateOrName} _identifier  An identifier for a state. Either a fully-qualified path, or the object\n\t *            used to define the state.\n\t * @param {IState} _definition The `State` object definition.\n\t * @param {ParamsOrArray} _params Parameters for the target state\n\t * @param {TransitionOptions} _options Transition options.\n\t */\n\tvar TargetState = (function () {\n\t    function TargetState(_identifier, _definition, _params, _options) {\n\t        if (_params === void 0) { _params = {}; }\n\t        if (_options === void 0) { _options = {}; }\n\t        this._identifier = _identifier;\n\t        this._definition = _definition;\n\t        this._options = _options;\n\t        this._params = _params || {};\n\t    }\n\t    TargetState.prototype.name = function () {\n\t        return this._definition && this._definition.name || this._identifier;\n\t    };\n\t    TargetState.prototype.identifier = function () {\n\t        return this._identifier;\n\t    };\n\t    TargetState.prototype.params = function () {\n\t        return this._params;\n\t    };\n\t    TargetState.prototype.$state = function () {\n\t        return this._definition;\n\t    };\n\t    TargetState.prototype.state = function () {\n\t        return this._definition && this._definition.self;\n\t    };\n\t    TargetState.prototype.options = function () {\n\t        return this._options;\n\t    };\n\t    TargetState.prototype.exists = function () {\n\t        return !!(this._definition && this._definition.self);\n\t    };\n\t    TargetState.prototype.valid = function () {\n\t        return !this.error();\n\t    };\n\t    TargetState.prototype.error = function () {\n\t        var base = this.options().relative;\n\t        if (!this._definition && !!base) {\n\t            var stateName = base.name ? base.name : base;\n\t            return \"Could not resolve '\" + this.name() + \"' from state '\" + stateName + \"'\";\n\t        }\n\t        if (!this._definition)\n\t            return \"No such state '\" + this.name() + \"'\";\n\t        if (!this._definition.self)\n\t            return \"State '\" + this.name() + \"' has an invalid definition\";\n\t    };\n\t    return TargetState;\n\t}());\n\texports.TargetState = TargetState;\n\n\n/***/ },\n/* 15 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module transition */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar glob_1 = __webpack_require__(7);\n\t/**\n\t * Determines if the given state matches the matchCriteria\n\t *\n\t * @hidden\n\t *\n\t * @param state a State Object to test against\n\t * @param criterion\n\t * - If a string, matchState uses the string as a glob-matcher against the state name\n\t * - If an array (of strings), matchState uses each string in the array as a glob-matchers against the state name\n\t *   and returns a positive match if any of the globs match.\n\t * - If a function, matchState calls the function with the state and returns true if the function's result is truthy.\n\t * @returns {boolean}\n\t */\n\tfunction matchState(state, criterion) {\n\t    var toMatch = predicates_1.isString(criterion) ? [criterion] : criterion;\n\t    function matchGlobs(_state) {\n\t        var globStrings = toMatch;\n\t        for (var i = 0; i < globStrings.length; i++) {\n\t            var glob = glob_1.Glob.fromString(globStrings[i]);\n\t            if ((glob && glob.matches(_state.name)) || (!glob && globStrings[i] === _state.name)) {\n\t                return true;\n\t            }\n\t        }\n\t        return false;\n\t    }\n\t    var matchFn = (predicates_1.isFunction(toMatch) ? toMatch : matchGlobs);\n\t    return !!matchFn(state);\n\t}\n\texports.matchState = matchState;\n\t/** @hidden */\n\tvar EventHook = (function () {\n\t    function EventHook(matchCriteria, callback, options) {\n\t        if (options === void 0) { options = {}; }\n\t        this.callback = callback;\n\t        this.matchCriteria = common_1.extend({ to: true, from: true, exiting: true, retained: true, entering: true }, matchCriteria);\n\t        this.priority = options.priority || 0;\n\t        this.bind = options.bind || null;\n\t    }\n\t    EventHook._matchingNodes = function (nodes, criterion) {\n\t        if (criterion === true)\n\t            return nodes;\n\t        var matching = nodes.filter(function (node) { return matchState(node.state, criterion); });\n\t        return matching.length ? matching : null;\n\t    };\n\t    /**\n\t     * Determines if this hook's [[matchCriteria]] match the given [[TreeChanges]]\n\t     *\n\t     * @returns an IMatchingNodes object, or null. If an IMatchingNodes object is returned, its values\n\t     * are the matching [[PathNode]]s for each [[HookMatchCriterion]] (to, from, exiting, retained, entering)\n\t     */\n\t    EventHook.prototype.matches = function (treeChanges) {\n\t        var mc = this.matchCriteria, _matchingNodes = EventHook._matchingNodes;\n\t        var matches = {\n\t            to: _matchingNodes([common_1.tail(treeChanges.to)], mc.to),\n\t            from: _matchingNodes([common_1.tail(treeChanges.from)], mc.from),\n\t            exiting: _matchingNodes(treeChanges.exiting, mc.exiting),\n\t            retained: _matchingNodes(treeChanges.retained, mc.retained),\n\t            entering: _matchingNodes(treeChanges.entering, mc.entering),\n\t        };\n\t        // Check if all the criteria matched the TreeChanges object\n\t        var allMatched = [\"to\", \"from\", \"exiting\", \"retained\", \"entering\"]\n\t            .map(function (prop) { return matches[prop]; })\n\t            .reduce(common_1.allTrueR, true);\n\t        return allMatched ? matches : null;\n\t    };\n\t    return EventHook;\n\t}());\n\texports.EventHook = EventHook;\n\t/** @hidden Return a registration function of the requested type. */\n\tfunction makeHookRegistrationFn(hooks, name) {\n\t    return function (matchObject, callback, options) {\n\t        if (options === void 0) { options = {}; }\n\t        var eventHook = new EventHook(matchObject, callback, options);\n\t        hooks[name].push(eventHook);\n\t        return function deregisterEventHook() {\n\t            common_1.removeFrom(hooks[name])(eventHook);\n\t        };\n\t    };\n\t}\n\t/**\n\t * Mixin class acts as a Transition Hook registry.\n\t *\n\t * Holds the registered [[HookFn]] objects.\n\t * Exposes functions to register new hooks.\n\t *\n\t * This is a Mixin class which can be applied to other objects.\n\t *\n\t * The hook registration functions are [[onBefore]], [[onStart]], [[onEnter]], [[onRetain]], [[onExit]], [[onFinish]], [[onSuccess]], [[onError]].\n\t *\n\t * This class is mixed into both the [[TransitionService]] and every [[Transition]] object.\n\t * Global hooks are added to the [[TransitionService]].\n\t * Since each [[Transition]] is itself a `HookRegistry`, hooks can also be added to individual Transitions\n\t * (note: the hook criteria still must match the Transition).\n\t */\n\tvar HookRegistry = (function () {\n\t    function HookRegistry() {\n\t        var _this = this;\n\t        this._transitionEvents = {\n\t            onBefore: [], onStart: [], onEnter: [], onRetain: [], onExit: [], onFinish: [], onSuccess: [], onError: []\n\t        };\n\t        this.getHooks = function (name) { return _this._transitionEvents[name]; };\n\t        /** @inheritdoc */\n\t        this.onBefore = makeHookRegistrationFn(this._transitionEvents, \"onBefore\");\n\t        /** @inheritdoc */\n\t        this.onStart = makeHookRegistrationFn(this._transitionEvents, \"onStart\");\n\t        /** @inheritdoc */\n\t        this.onEnter = makeHookRegistrationFn(this._transitionEvents, \"onEnter\");\n\t        /** @inheritdoc */\n\t        this.onRetain = makeHookRegistrationFn(this._transitionEvents, \"onRetain\");\n\t        /** @inheritdoc */\n\t        this.onExit = makeHookRegistrationFn(this._transitionEvents, \"onExit\");\n\t        /** @inheritdoc */\n\t        this.onFinish = makeHookRegistrationFn(this._transitionEvents, \"onFinish\");\n\t        /** @inheritdoc */\n\t        this.onSuccess = makeHookRegistrationFn(this._transitionEvents, \"onSuccess\");\n\t        /** @inheritdoc */\n\t        this.onError = makeHookRegistrationFn(this._transitionEvents, \"onError\");\n\t    }\n\t    HookRegistry.mixin = function (source, target) {\n\t        Object.keys(source._transitionEvents).concat([\"getHooks\"]).forEach(function (key) { return target[key] = source[key]; });\n\t    };\n\t    return HookRegistry;\n\t}());\n\texports.HookRegistry = HookRegistry;\n\n\n/***/ },\n/* 16 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module transition */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar transitionHook_1 = __webpack_require__(13);\n\tvar resolveContext_1 = __webpack_require__(17);\n\t/**\n\t * This class returns applicable TransitionHooks for a specific Transition instance.\n\t *\n\t * Hooks (IEventHook) may be registered globally, e.g., $transitions.onEnter(...), or locally, e.g.\n\t * myTransition.onEnter(...).  The HookBuilder finds matching IEventHooks (where the match criteria is\n\t * determined by the type of hook)\n\t *\n\t * The HookBuilder also converts IEventHooks objects to TransitionHook objects, which are used to run a Transition.\n\t *\n\t * The HookBuilder constructor is given the $transitions service and a Transition instance.  Thus, a HookBuilder\n\t * instance may only be used for one specific Transition object. (side note: the _treeChanges accessor is private\n\t * in the Transition class, so we must also provide the Transition's _treeChanges)\n\t *\n\t */\n\tvar HookBuilder = (function () {\n\t    function HookBuilder($transitions, transition, baseHookOptions) {\n\t        var _this = this;\n\t        this.$transitions = $transitions;\n\t        this.transition = transition;\n\t        this.baseHookOptions = baseHookOptions;\n\t        this.getOnBeforeHooks = function () { return _this._buildNodeHooks(\"onBefore\", \"to\", tupleSort(), { async: false }); };\n\t        this.getOnStartHooks = function () { return _this._buildNodeHooks(\"onStart\", \"to\", tupleSort()); };\n\t        this.getOnExitHooks = function () { return _this._buildNodeHooks(\"onExit\", \"exiting\", tupleSort(true), { stateHook: true }); };\n\t        this.getOnRetainHooks = function () { return _this._buildNodeHooks(\"onRetain\", \"retained\", tupleSort(false), { stateHook: true }); };\n\t        this.getOnEnterHooks = function () { return _this._buildNodeHooks(\"onEnter\", \"entering\", tupleSort(false), { stateHook: true }); };\n\t        this.getOnFinishHooks = function () { return _this._buildNodeHooks(\"onFinish\", \"to\", tupleSort()); };\n\t        this.getOnSuccessHooks = function () { return _this._buildNodeHooks(\"onSuccess\", \"to\", tupleSort(), { async: false, rejectIfSuperseded: false }); };\n\t        this.getOnErrorHooks = function () { return _this._buildNodeHooks(\"onError\", \"to\", tupleSort(), { async: false, rejectIfSuperseded: false }); };\n\t        this.treeChanges = transition.treeChanges();\n\t        this.toState = common_1.tail(this.treeChanges.to).state;\n\t        this.fromState = common_1.tail(this.treeChanges.from).state;\n\t        this.transitionOptions = transition.options();\n\t    }\n\t    HookBuilder.prototype.asyncHooks = function () {\n\t        var onStartHooks = this.getOnStartHooks();\n\t        var onExitHooks = this.getOnExitHooks();\n\t        var onRetainHooks = this.getOnRetainHooks();\n\t        var onEnterHooks = this.getOnEnterHooks();\n\t        var onFinishHooks = this.getOnFinishHooks();\n\t        var asyncHooks = [onStartHooks, onExitHooks, onRetainHooks, onEnterHooks, onFinishHooks];\n\t        return asyncHooks.reduce(common_1.unnestR, []).filter(common_1.identity);\n\t    };\n\t    /**\n\t     * Returns an array of newly built TransitionHook objects.\n\t     *\n\t     * - Finds all IEventHooks registered for the given `hookType` which matched the transition's [[TreeChanges]].\n\t     * - Finds [[PathNode]] (or `PathNode[]`) to use as the TransitionHook context(s)\n\t     * - For each of the [[PathNode]]s, creates a TransitionHook\n\t     *\n\t     * @param hookType the name of the hook registration function, e.g., 'onEnter', 'onFinish'.\n\t     * @param matchingNodesProp selects which [[PathNode]]s from the [[IMatchingNodes]] object to create hooks for.\n\t     * @param getLocals a function which accepts a [[PathNode]] and returns additional locals to provide to the hook as injectables\n\t     * @param sortHooksFn a function which compares two HookTuple and returns <1, 0, or >1\n\t     * @param options any specific Transition Hook Options\n\t     */\n\t    HookBuilder.prototype._buildNodeHooks = function (hookType, matchingNodesProp, sortHooksFn, options) {\n\t        var _this = this;\n\t        // Find all the matching registered hooks for a given hook type\n\t        var matchingHooks = this._matchingHooks(hookType, this.treeChanges);\n\t        if (!matchingHooks)\n\t            return [];\n\t        var makeTransitionHooks = function (hook) {\n\t            // Fetch the Nodes that caused this hook to match.\n\t            var matches = hook.matches(_this.treeChanges);\n\t            // Select the PathNode[] that will be used as TransitionHook context objects\n\t            var matchingNodes = matches[matchingNodesProp];\n\t            // When invoking 'exiting' hooks, give them the \"from path\" for resolve data.\n\t            // Everything else gets the \"to path\"\n\t            var resolvePath = matchingNodesProp === 'exiting' ? _this.treeChanges.from : _this.treeChanges.to;\n\t            var resolveContext = new resolveContext_1.ResolveContext(resolvePath);\n\t            // Return an array of HookTuples\n\t            return matchingNodes.map(function (node) {\n\t                var _options = common_1.extend({ bind: hook.bind, traceData: { hookType: hookType, context: node } }, _this.baseHookOptions, options);\n\t                var state = _options.stateHook ? node.state : null;\n\t                var context = resolveContext.subContext(node.state);\n\t                var transitionHook = new transitionHook_1.TransitionHook(_this.transition, state, hook.callback, context, _options);\n\t                return { hook: hook, node: node, transitionHook: transitionHook };\n\t            });\n\t        };\n\t        return matchingHooks.map(makeTransitionHooks)\n\t            .reduce(common_1.unnestR, [])\n\t            .sort(sortHooksFn)\n\t            .map(function (tuple) { return tuple.transitionHook; });\n\t    };\n\t    /**\n\t     * Finds all IEventHooks from:\n\t     * - The Transition object instance hook registry\n\t     * - The TransitionService ($transitions) global hook registry\n\t     *\n\t     * which matched:\n\t     * - the eventType\n\t     * - the matchCriteria (to, from, exiting, retained, entering)\n\t     *\n\t     * @returns an array of matched [[IEventHook]]s\n\t     */\n\t    HookBuilder.prototype._matchingHooks = function (hookName, treeChanges) {\n\t        return [this.transition, this.$transitions] // Instance and Global hook registries\n\t            .map(function (reg) { return reg.getHooks(hookName); }) // Get named hooks from registries\n\t            .filter(common_1.assertPredicate(predicates_1.isArray, \"broken event named: \" + hookName)) // Sanity check\n\t            .reduce(common_1.unnestR, []) // Un-nest IEventHook[][] to IEventHook[] array\n\t            .filter(function (hook) { return hook.matches(treeChanges); }); // Only those satisfying matchCriteria\n\t    };\n\t    return HookBuilder;\n\t}());\n\texports.HookBuilder = HookBuilder;\n\t/**\n\t * A factory for a sort function for HookTuples.\n\t *\n\t * The sort function first compares the PathNode depth (how deep in the state tree a node is), then compares\n\t * the EventHook priority.\n\t *\n\t * @param reverseDepthSort a boolean, when true, reverses the sort order for the node depth\n\t * @returns a tuple sort function\n\t */\n\tfunction tupleSort(reverseDepthSort) {\n\t    if (reverseDepthSort === void 0) { reverseDepthSort = false; }\n\t    return function nodeDepthThenPriority(l, r) {\n\t        var factor = reverseDepthSort ? -1 : 1;\n\t        var depthDelta = (l.node.state.path.length - r.node.state.path.length) * factor;\n\t        return depthDelta !== 0 ? depthDelta : r.hook.priority - l.hook.priority;\n\t    };\n\t}\n\n\n/***/ },\n/* 17 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module resolve */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar trace_1 = __webpack_require__(12);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar interface_1 = __webpack_require__(18);\n\tvar resolvable_1 = __webpack_require__(19);\n\tvar pathFactory_1 = __webpack_require__(20);\n\tvar strings_1 = __webpack_require__(9);\n\tvar when = interface_1.resolvePolicies.when;\n\tvar ALL_WHENS = [when.EAGER, when.LAZY];\n\tvar EAGER_WHENS = [when.EAGER];\n\t/**\n\t * Encapsulates Depenency Injection for a path of nodes\n\t *\n\t * UI-Router states are organized as a tree.\n\t * A nested state has a path of ancestors to the root of the tree.\n\t * When a state is being activated, each element in the path is wrapped as a [[PathNode]].\n\t * A `PathNode` is a stateful object that holds things like parameters and resolvables for the state being activated.\n\t *\n\t * The ResolveContext closes over the [[PathNode]]s, and provides DI for the last node in the path.\n\t */\n\tvar ResolveContext = (function () {\n\t    function ResolveContext(_path) {\n\t        this._path = _path;\n\t    }\n\t    /** Gets all the tokens found in the resolve context, de-duplicated */\n\t    ResolveContext.prototype.getTokens = function () {\n\t        return this._path.reduce(function (acc, node) { return acc.concat(node.resolvables.map(function (r) { return r.token; })); }, []).reduce(common_1.uniqR, []);\n\t    };\n\t    /**\n\t     * Gets the Resolvable that matches the token\n\t     *\n\t     * Gets the last Resolvable that matches the token in this context, or undefined.\n\t     * Throws an error if it doesn't exist in the ResolveContext\n\t     */\n\t    ResolveContext.prototype.getResolvable = function (token) {\n\t        var matching = this._path.map(function (node) { return node.resolvables; })\n\t            .reduce(common_1.unnestR, [])\n\t            .filter(function (r) { return r.token === token; });\n\t        return common_1.tail(matching);\n\t    };\n\t    /**\n\t     * Returns a ResolveContext that includes a portion of this one\n\t     *\n\t     * Given a state, this method creates a new ResolveContext from this one.\n\t     * The new context starts at the first node (root) and stops at the node for the `state` parameter.\n\t     *\n\t     * #### Why\n\t     *\n\t     * When a transition is created, the nodes in the \"To Path\" are injected from a ResolveContext.\n\t     * A ResolveContext closes over a path of [[PathNode]]s and processes the resolvables.\n\t     * The \"To State\" can inject values from its own resolvables, as well as those from all its ancestor state's (node's).\n\t     * This method is used to create a narrower context when injecting ancestor nodes.\n\t     *\n\t     * @example\n\t     * `let ABCD = new ResolveContext([A, B, C, D]);`\n\t     *\n\t     * Given a path `[A, B, C, D]`, where `A`, `B`, `C` and `D` are nodes for states `a`, `b`, `c`, `d`:\n\t     * When injecting `D`, `D` should have access to all resolvables from `A`, `B`, `C`, `D`.\n\t     * However, `B` should only be able to access resolvables from `A`, `B`.\n\t     *\n\t     * When resolving for the `B` node, first take the full \"To Path\" Context `[A,B,C,D]` and limit to the subpath `[A,B]`.\n\t     * `let AB = ABCD.subcontext(a)`\n\t     */\n\t    ResolveContext.prototype.subContext = function (state) {\n\t        return new ResolveContext(pathFactory_1.PathFactory.subPath(this._path, function (node) { return node.state === state; }));\n\t    };\n\t    /**\n\t     * Adds Resolvables to the node that matches the state\n\t     *\n\t     * This adds a [[Resolvable]] (generally one created on the fly; not declared on a [[StateDeclaration.resolve]] block).\n\t     * The resolvable is added to the node matching the `state` parameter.\n\t     *\n\t     * These new resolvables are not automatically fetched.\n\t     * The calling code should either fetch them, fetch something that depends on them,\n\t     * or rely on [[resolvePath]] being called when some state is being entered.\n\t     *\n\t     * Note: each resolvable's [[ResolvePolicy]] is merged with the state's policy, and the global default.\n\t     *\n\t     * @param newResolvables the new Resolvables\n\t     * @param state Used to find the node to put the resolvable on\n\t     */\n\t    ResolveContext.prototype.addResolvables = function (newResolvables, state) {\n\t        var node = common_1.find(this._path, hof_1.propEq('state', state));\n\t        var keys = newResolvables.map(function (r) { return r.token; });\n\t        node.resolvables = node.resolvables.filter(function (r) { return keys.indexOf(r.token) === -1; }).concat(newResolvables);\n\t    };\n\t    /**\n\t     * Returns a promise for an array of resolved path Element promises\n\t     *\n\t     * @param when\n\t     * @param trans\n\t     * @returns {Promise<any>|any}\n\t     */\n\t    ResolveContext.prototype.resolvePath = function (when, trans) {\n\t        var _this = this;\n\t        if (when === void 0) { when = \"LAZY\"; }\n\t        // This option determines which 'when' policy Resolvables we are about to fetch.\n\t        var whenOption = common_1.inArray(ALL_WHENS, when) ? when : \"LAZY\";\n\t        // If the caller specified EAGER, only the EAGER Resolvables are fetched.\n\t        // if the caller specified LAZY, both EAGER and LAZY Resolvables are fetched.`\n\t        var matchedWhens = whenOption === interface_1.resolvePolicies.when.EAGER ? EAGER_WHENS : ALL_WHENS;\n\t        // get the subpath to the state argument, if provided\n\t        trace_1.trace.traceResolvePath(this._path, when, trans);\n\t        var promises = this._path.reduce(function (acc, node) {\n\t            var matchesRequestedPolicy = function (resolvable) {\n\t                return common_1.inArray(matchedWhens, resolvable.getPolicy(node.state).when);\n\t            };\n\t            var nodeResolvables = node.resolvables.filter(matchesRequestedPolicy);\n\t            var subContext = _this.subContext(node.state);\n\t            // For the matching Resolvables, start their async fetch process.\n\t            var getResult = function (r) { return r.get(subContext, trans)\n\t                .then(function (value) { return ({ token: r.token, value: value }); }); };\n\t            return acc.concat(nodeResolvables.map(getResult));\n\t        }, []);\n\t        return coreservices_1.services.$q.all(promises);\n\t    };\n\t    ResolveContext.prototype.injector = function () {\n\t        return new UIInjectorImpl(this);\n\t    };\n\t    ResolveContext.prototype.findNode = function (resolvable) {\n\t        return common_1.find(this._path, function (node) { return common_1.inArray(node.resolvables, resolvable); });\n\t    };\n\t    /**\n\t     * Gets the async dependencies of a Resolvable\n\t     *\n\t     * Given a Resolvable, returns its dependencies as a Resolvable[]\n\t     */\n\t    ResolveContext.prototype.getDependencies = function (resolvable) {\n\t        var node = this.findNode(resolvable);\n\t        // Find which other resolvables are \"visible\" to the `resolvable` argument\n\t        // subpath stopping at resolvable's node, or the whole path (if the resolvable isn't in the path)\n\t        var subPath = pathFactory_1.PathFactory.subPath(this._path, function (x) { return x === node; }) || this._path;\n\t        var availableResolvables = subPath\n\t            .reduce(function (acc, node) { return acc.concat(node.resolvables); }, []) //all of subpath's resolvables\n\t            .filter(function (res) { return res !== resolvable; }); // filter out the `resolvable` argument\n\t        var getDependency = function (token) {\n\t            var matching = availableResolvables.filter(function (r) { return r.token === token; });\n\t            if (matching.length)\n\t                return common_1.tail(matching);\n\t            var fromInjector = coreservices_1.services.$injector.get(token);\n\t            if (!fromInjector) {\n\t                throw new Error(\"Could not find Dependency Injection token: \" + strings_1.stringify(token));\n\t            }\n\t            return new resolvable_1.Resolvable(token, function () { return fromInjector; }, [], fromInjector);\n\t        };\n\t        return resolvable.deps.map(getDependency);\n\t    };\n\t    return ResolveContext;\n\t}());\n\texports.ResolveContext = ResolveContext;\n\tvar UIInjectorImpl = (function () {\n\t    function UIInjectorImpl(context) {\n\t        this.context = context;\n\t        /** The native injector ($injector on ng1, Root Injector on ng2, justjs injector for everything else) */\n\t        this.native = coreservices_1.services.$injector;\n\t    }\n\t    UIInjectorImpl.prototype.get = function (token) {\n\t        var resolvable = this.context.getResolvable(token);\n\t        if (resolvable) {\n\t            if (!resolvable.resolved) {\n\t                throw new Error(\"Resolvable async .get() not complete:\" + strings_1.stringify(resolvable.token));\n\t            }\n\t            return resolvable.data;\n\t        }\n\t        return coreservices_1.services.$injector.get(token);\n\t    };\n\t    UIInjectorImpl.prototype.getAsync = function (token) {\n\t        var resolvable = this.context.getResolvable(token);\n\t        if (resolvable)\n\t            return resolvable.get(this.context);\n\t        return coreservices_1.services.$q.when(coreservices_1.services.$injector.get(token));\n\t    };\n\t    return UIInjectorImpl;\n\t}());\n\n\n/***/ },\n/* 18 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\texports.resolvePolicies = {\n\t    when: {\n\t        LAZY: \"LAZY\",\n\t        EAGER: \"EAGER\"\n\t    },\n\t    async: {\n\t        WAIT: \"WAIT\",\n\t        NOWAIT: \"NOWAIT\",\n\t        RXWAIT: \"RXWAIT\"\n\t    }\n\t};\n\n\n/***/ },\n/* 19 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module resolve */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar trace_1 = __webpack_require__(12);\n\tvar strings_1 = __webpack_require__(9);\n\tvar predicates_1 = __webpack_require__(4);\n\t// TODO: explicitly make this user configurable\n\texports.defaultResolvePolicy = {\n\t    when: \"LAZY\",\n\t    async: \"WAIT\"\n\t};\n\t/**\n\t * The basic building block for the resolve system.\n\t *\n\t * Resolvables encapsulate a state's resolve's resolveFn, the resolveFn's declared dependencies, the wrapped (.promise),\n\t * and the unwrapped-when-complete (.data) result of the resolveFn.\n\t *\n\t * Resolvable.get() either retrieves the Resolvable's existing promise, or else invokes resolve() (which invokes the\n\t * resolveFn) and returns the resulting promise.\n\t *\n\t * Resolvable.get() and Resolvable.resolve() both execute within a context path, which is passed as the first\n\t * parameter to those fns.\n\t */\n\tvar Resolvable = (function () {\n\t    function Resolvable(arg1, resolveFn, deps, policy, data) {\n\t        this.resolved = false;\n\t        this.promise = undefined;\n\t        if (arg1 instanceof Resolvable) {\n\t            common_1.extend(this, arg1);\n\t        }\n\t        else if (predicates_1.isFunction(resolveFn)) {\n\t            if (arg1 == null || arg1 == undefined)\n\t                throw new Error(\"new Resolvable(): token argument is required\");\n\t            if (!predicates_1.isFunction(resolveFn))\n\t                throw new Error(\"new Resolvable(): resolveFn argument must be a function\");\n\t            this.token = arg1;\n\t            this.policy = policy;\n\t            this.resolveFn = resolveFn;\n\t            this.deps = deps || [];\n\t            this.data = data;\n\t            this.resolved = data !== undefined;\n\t            this.promise = this.resolved ? coreservices_1.services.$q.when(this.data) : undefined;\n\t        }\n\t        else if (predicates_1.isObject(arg1) && arg1.token && predicates_1.isFunction(arg1.resolveFn)) {\n\t            var literal = arg1;\n\t            return new Resolvable(literal.token, literal.resolveFn, literal.deps, literal.policy, literal.data);\n\t        }\n\t    }\n\t    Resolvable.prototype.getPolicy = function (state) {\n\t        var thisPolicy = this.policy || {};\n\t        var statePolicy = state && state.resolvePolicy || {};\n\t        return {\n\t            when: thisPolicy.when || statePolicy.when || exports.defaultResolvePolicy.when,\n\t            async: thisPolicy.async || statePolicy.async || exports.defaultResolvePolicy.async,\n\t        };\n\t    };\n\t    /**\n\t     * Asynchronously resolve this Resolvable's data\n\t     *\n\t     * Given a ResolveContext that this Resolvable is found in:\n\t     * Wait for this Resolvable's dependencies, then invoke this Resolvable's function\n\t     * and update the Resolvable's state\n\t     */\n\t    Resolvable.prototype.resolve = function (resolveContext, trans) {\n\t        var _this = this;\n\t        var $q = coreservices_1.services.$q;\n\t        // Gets all dependencies from ResolveContext and wait for them to be resolved\n\t        var getResolvableDependencies = function () {\n\t            return $q.all(resolveContext.getDependencies(_this).map(function (r) {\n\t                return r.get(resolveContext, trans);\n\t            }));\n\t        };\n\t        // Invokes the resolve function passing the resolved dependencies as arguments\n\t        var invokeResolveFn = function (resolvedDeps) {\n\t            return _this.resolveFn.apply(null, resolvedDeps);\n\t        };\n\t        /**\n\t         * For RXWAIT policy:\n\t         *\n\t         * Given an observable returned from a resolve function:\n\t         * - enables .cache() mode (this allows multicast subscribers)\n\t         * - then calls toPromise() (this triggers subscribe() and thus fetches)\n\t         * - Waits for the promise, then return the cached observable (not the first emitted value).\n\t         */\n\t        var waitForRx = function (observable$) {\n\t            var cached = observable$.cache();\n\t            return cached.toPromise().then(function () { return cached; });\n\t        };\n\t        // If the resolve policy is RXWAIT, wait for the observable to emit something. otherwise pass through.\n\t        var node = resolveContext.findNode(this);\n\t        var state = node && node.state;\n\t        var maybeWaitForRx = this.getPolicy(state).async === \"RXWAIT\" ? waitForRx : function (x) { return x; };\n\t        // After the final value has been resolved, update the state of the Resolvable\n\t        var applyResolvedValue = function (resolvedValue) {\n\t            _this.data = resolvedValue;\n\t            _this.resolved = true;\n\t            trace_1.trace.traceResolvableResolved(_this, trans);\n\t            return _this.data;\n\t        };\n\t        // Sets the promise property first, then getsResolvableDependencies in the context of the promise chain. Always waits one tick.\n\t        return this.promise = $q.when()\n\t            .then(getResolvableDependencies)\n\t            .then(invokeResolveFn)\n\t            .then(maybeWaitForRx)\n\t            .then(applyResolvedValue);\n\t    };\n\t    /**\n\t     * Gets a promise for this Resolvable's data.\n\t     *\n\t     * Fetches the data and returns a promise.\n\t     * Returns the existing promise if it has already been fetched once.\n\t     */\n\t    Resolvable.prototype.get = function (resolveContext, trans) {\n\t        return this.promise || this.resolve(resolveContext, trans);\n\t    };\n\t    Resolvable.prototype.toString = function () {\n\t        return \"Resolvable(token: \" + strings_1.stringify(this.token) + \", requires: [\" + this.deps.map(strings_1.stringify) + \"])\";\n\t    };\n\t    Resolvable.prototype.clone = function () {\n\t        return new Resolvable(this);\n\t    };\n\t    return Resolvable;\n\t}());\n\texports.Resolvable = Resolvable;\n\n\n/***/ },\n/* 20 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module path */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar targetState_1 = __webpack_require__(14);\n\tvar node_1 = __webpack_require__(21);\n\t/**\n\t * This class contains functions which convert TargetStates, Nodes and paths from one type to another.\n\t */\n\tvar PathFactory = (function () {\n\t    function PathFactory() {\n\t    }\n\t    /** Given a PathNode[], create an TargetState */\n\t    PathFactory.makeTargetState = function (path) {\n\t        var state = common_1.tail(path).state;\n\t        return new targetState_1.TargetState(state, state, path.map(hof_1.prop(\"paramValues\")).reduce(common_1.mergeR, {}));\n\t    };\n\t    PathFactory.buildPath = function (targetState) {\n\t        var toParams = targetState.params();\n\t        return targetState.$state().path.map(function (state) { return new node_1.PathNode(state).applyRawParams(toParams); });\n\t    };\n\t    /** Given a fromPath: PathNode[] and a TargetState, builds a toPath: PathNode[] */\n\t    PathFactory.buildToPath = function (fromPath, targetState) {\n\t        var toPath = PathFactory.buildPath(targetState);\n\t        if (targetState.options().inherit) {\n\t            return PathFactory.inheritParams(fromPath, toPath, Object.keys(targetState.params()));\n\t        }\n\t        return toPath;\n\t    };\n\t    /**\n\t     * Creates ViewConfig objects and adds to nodes.\n\t     *\n\t     * On each [[PathNode]], creates ViewConfig objects from the views: property of the node's state\n\t     */\n\t    PathFactory.applyViewConfigs = function ($view, path, states) {\n\t        // Only apply the viewConfigs to the nodes for the given states\n\t        path.filter(function (node) { return common_1.inArray(states, node.state); }).forEach(function (node) {\n\t            var viewDecls = common_1.values(node.state.views || {});\n\t            var subPath = PathFactory.subPath(path, function (n) { return n === node; });\n\t            var viewConfigs = viewDecls.map(function (view) { return $view.createViewConfig(subPath, view); });\n\t            node.views = viewConfigs.reduce(common_1.unnestR, []);\n\t        });\n\t    };\n\t    /**\n\t     * Given a fromPath and a toPath, returns a new to path which inherits parameters from the fromPath\n\t     *\n\t     * For a parameter in a node to be inherited from the from path:\n\t     * - The toPath's node must have a matching node in the fromPath (by state).\n\t     * - The parameter name must not be found in the toKeys parameter array.\n\t     *\n\t     * Note: the keys provided in toKeys are intended to be those param keys explicitly specified by some\n\t     * caller, for instance, $state.transitionTo(..., toParams).  If a key was found in toParams,\n\t     * it is not inherited from the fromPath.\n\t     */\n\t    PathFactory.inheritParams = function (fromPath, toPath, toKeys) {\n\t        if (toKeys === void 0) { toKeys = []; }\n\t        function nodeParamVals(path, state) {\n\t            var node = common_1.find(path, hof_1.propEq('state', state));\n\t            return common_1.extend({}, node && node.paramValues);\n\t        }\n\t        /**\n\t         * Given an [[PathNode]] \"toNode\", return a new [[PathNode]] with param values inherited from the\n\t         * matching node in fromPath.  Only inherit keys that aren't found in \"toKeys\" from the node in \"fromPath\"\"\n\t         */\n\t        function makeInheritedParamsNode(toNode) {\n\t            // All param values for the node (may include default key/vals, when key was not found in toParams)\n\t            var toParamVals = common_1.extend({}, toNode && toNode.paramValues);\n\t            // limited to only those keys found in toParams\n\t            var incomingParamVals = common_1.pick(toParamVals, toKeys);\n\t            toParamVals = common_1.omit(toParamVals, toKeys);\n\t            var fromParamVals = nodeParamVals(fromPath, toNode.state) || {};\n\t            // extend toParamVals with any fromParamVals, then override any of those those with incomingParamVals\n\t            var ownParamVals = common_1.extend(toParamVals, fromParamVals, incomingParamVals);\n\t            return new node_1.PathNode(toNode.state).applyRawParams(ownParamVals);\n\t        }\n\t        // The param keys specified by the incoming toParams\n\t        return toPath.map(makeInheritedParamsNode);\n\t    };\n\t    /**\n\t     * Computes the tree changes (entering, exiting) between a fromPath and toPath.\n\t     */\n\t    PathFactory.treeChanges = function (fromPath, toPath, reloadState) {\n\t        var keep = 0, max = Math.min(fromPath.length, toPath.length);\n\t        var staticParams = function (state) { return state.parameters({ inherit: false }).filter(hof_1.not(hof_1.prop('dynamic'))).map(hof_1.prop('id')); };\n\t        var nodesMatch = function (node1, node2) { return node1.equals(node2, staticParams(node1.state)); };\n\t        while (keep < max && fromPath[keep].state !== reloadState && nodesMatch(fromPath[keep], toPath[keep])) {\n\t            keep++;\n\t        }\n\t        /** Given a retained node, return a new node which uses the to node's param values */\n\t        function applyToParams(retainedNode, idx) {\n\t            var cloned = node_1.PathNode.clone(retainedNode);\n\t            cloned.paramValues = toPath[idx].paramValues;\n\t            return cloned;\n\t        }\n\t        var from, retained, exiting, entering, to;\n\t        from = fromPath;\n\t        retained = from.slice(0, keep);\n\t        exiting = from.slice(keep);\n\t        // Create a new retained path (with shallow copies of nodes) which have the params of the toPath mapped\n\t        var retainedWithToParams = retained.map(applyToParams);\n\t        entering = toPath.slice(keep);\n\t        to = (retainedWithToParams).concat(entering);\n\t        return { from: from, to: to, retained: retained, exiting: exiting, entering: entering };\n\t    };\n\t    /**\n\t     * Return a subpath of a path, which stops at the first matching node\n\t     *\n\t     * Given an array of nodes, returns a subset of the array starting from the first node,\n\t     * stopping when the first node matches the predicate.\n\t     *\n\t     * @param path a path of [[PathNode]]s\n\t     * @param predicate a [[Predicate]] fn that matches [[PathNode]]s\n\t     * @returns a subpath up to the matching node, or undefined if no match is found\n\t     */\n\t    PathFactory.subPath = function (path, predicate) {\n\t        var node = common_1.find(path, predicate);\n\t        var elementIdx = path.indexOf(node);\n\t        return elementIdx === -1 ? undefined : path.slice(0, elementIdx + 1);\n\t    };\n\t    /** Gets the raw parameter values from a path */\n\t    PathFactory.paramValues = function (path) { return path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {}); };\n\t    return PathFactory;\n\t}());\n\texports.PathFactory = PathFactory;\n\n\n/***/ },\n/* 21 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module path */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar param_1 = __webpack_require__(22);\n\t/**\n\t * A node in a [[TreeChanges]] path\n\t *\n\t * For a [[TreeChanges]] path, this class holds the stateful information for a single node in the path.\n\t * Each PathNode corresponds to a state being entered, exited, or retained.\n\t * The stateful information includes parameter values and resolve data.\n\t */\n\tvar PathNode = (function () {\n\t    function PathNode(state) {\n\t        if (state instanceof PathNode) {\n\t            var node = state;\n\t            this.state = node.state;\n\t            this.paramSchema = node.paramSchema.slice();\n\t            this.paramValues = common_1.extend({}, node.paramValues);\n\t            this.resolvables = node.resolvables.slice();\n\t            this.views = node.views && node.views.slice();\n\t        }\n\t        else {\n\t            this.state = state;\n\t            this.paramSchema = state.parameters({ inherit: false });\n\t            this.paramValues = {};\n\t            this.resolvables = state.resolvables.map(function (res) { return res.clone(); });\n\t        }\n\t    }\n\t    /** Sets [[paramValues]] for the node, from the values of an object hash */\n\t    PathNode.prototype.applyRawParams = function (params) {\n\t        var getParamVal = function (paramDef) { return [paramDef.id, paramDef.value(params[paramDef.id])]; };\n\t        this.paramValues = this.paramSchema.reduce(function (memo, pDef) { return common_1.applyPairs(memo, getParamVal(pDef)); }, {});\n\t        return this;\n\t    };\n\t    /** Gets a specific [[Param]] metadata that belongs to the node */\n\t    PathNode.prototype.parameter = function (name) {\n\t        return common_1.find(this.paramSchema, hof_1.propEq(\"id\", name));\n\t    };\n\t    /**\n\t     * @returns true if the state and parameter values for another PathNode are\n\t     * equal to the state and param values for this PathNode\n\t     */\n\t    PathNode.prototype.equals = function (node, keys) {\n\t        var _this = this;\n\t        if (keys === void 0) { keys = this.paramSchema.map(hof_1.prop('id')); }\n\t        var paramValsEq = function (key) { return _this.parameter(key).type.equals(_this.paramValues[key], node.paramValues[key]); };\n\t        return this.state === node.state && keys.map(paramValsEq).reduce(common_1.allTrueR, true);\n\t    };\n\t    /** Returns a clone of the PathNode */\n\t    PathNode.clone = function (node) {\n\t        return new PathNode(node);\n\t    };\n\t    /**\n\t     * Returns a new path which is a subpath of the first path which matched the second path.\n\t     *\n\t     * The new path starts from root and contains any nodes that match the nodes in the second path.\n\t     * Nodes are compared using their state property and parameter values.\n\t     */\n\t    PathNode.matching = function (pathA, pathB) {\n\t        var matching = [];\n\t        for (var i = 0; i < pathA.length && i < pathB.length; i++) {\n\t            var a = pathA[i], b = pathB[i];\n\t            if (a.state !== b.state)\n\t                break;\n\t            if (!param_1.Param.equals(a.paramSchema, a.paramValues, b.paramValues))\n\t                break;\n\t            matching.push(a);\n\t        }\n\t        return matching;\n\t    };\n\t    return PathNode;\n\t}());\n\texports.PathNode = PathNode;\n\n\n/***/ },\n/* 22 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module params */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar urlMatcherConfig_1 = __webpack_require__(23);\n\tvar type_1 = __webpack_require__(24);\n\tvar paramTypes_1 = __webpack_require__(25);\n\tvar hasOwn = Object.prototype.hasOwnProperty;\n\tvar isShorthand = function (cfg) { return [\"value\", \"type\", \"squash\", \"array\", \"dynamic\"].filter(hasOwn.bind(cfg || {})).length === 0; };\n\t(function (DefType) {\n\t    DefType[DefType[\"PATH\"] = 0] = \"PATH\";\n\t    DefType[DefType[\"SEARCH\"] = 1] = \"SEARCH\";\n\t    DefType[DefType[\"CONFIG\"] = 2] = \"CONFIG\";\n\t})(exports.DefType || (exports.DefType = {}));\n\tvar DefType = exports.DefType;\n\tfunction unwrapShorthand(cfg) {\n\t    cfg = isShorthand(cfg) && { value: cfg } || cfg;\n\t    return common_1.extend(cfg, {\n\t        $$fn: predicates_1.isInjectable(cfg.value) ? cfg.value : function () { return cfg.value; }\n\t    });\n\t}\n\tfunction getType(cfg, urlType, location, id) {\n\t    if (cfg.type && urlType && urlType.name !== 'string')\n\t        throw new Error(\"Param '\" + id + \"' has two type configurations.\");\n\t    if (cfg.type && urlType && urlType.name === 'string' && paramTypes_1.paramTypes.type(cfg.type))\n\t        return paramTypes_1.paramTypes.type(cfg.type);\n\t    if (urlType)\n\t        return urlType;\n\t    if (!cfg.type)\n\t        return (location === DefType.CONFIG ? paramTypes_1.paramTypes.type(\"any\") : paramTypes_1.paramTypes.type(\"string\"));\n\t    return cfg.type instanceof type_1.ParamType ? cfg.type : paramTypes_1.paramTypes.type(cfg.type);\n\t}\n\t/**\n\t * returns false, true, or the squash value to indicate the \"default parameter url squash policy\".\n\t */\n\tfunction getSquashPolicy(config, isOptional) {\n\t    var squash = config.squash;\n\t    if (!isOptional || squash === false)\n\t        return false;\n\t    if (!predicates_1.isDefined(squash) || squash == null)\n\t        return urlMatcherConfig_1.matcherConfig.defaultSquashPolicy();\n\t    if (squash === true || predicates_1.isString(squash))\n\t        return squash;\n\t    throw new Error(\"Invalid squash policy: '\" + squash + \"'. Valid policies: false, true, or arbitrary string\");\n\t}\n\tfunction getReplace(config, arrayMode, isOptional, squash) {\n\t    var replace, configuredKeys, defaultPolicy = [\n\t        { from: \"\", to: (isOptional || arrayMode ? undefined : \"\") },\n\t        { from: null, to: (isOptional || arrayMode ? undefined : \"\") }\n\t    ];\n\t    replace = predicates_1.isArray(config.replace) ? config.replace : [];\n\t    if (predicates_1.isString(squash))\n\t        replace.push({ from: squash, to: undefined });\n\t    configuredKeys = common_1.map(replace, hof_1.prop(\"from\"));\n\t    return common_1.filter(defaultPolicy, function (item) { return configuredKeys.indexOf(item.from) === -1; }).concat(replace);\n\t}\n\tvar Param = (function () {\n\t    function Param(id, type, config, location) {\n\t        config = unwrapShorthand(config);\n\t        type = getType(config, type, location, id);\n\t        var arrayMode = getArrayMode();\n\t        type = arrayMode ? type.$asArray(arrayMode, location === DefType.SEARCH) : type;\n\t        var isOptional = config.value !== undefined;\n\t        var dynamic = predicates_1.isDefined(config.dynamic) ? !!config.dynamic : !!type.dynamic;\n\t        var squash = getSquashPolicy(config, isOptional);\n\t        var replace = getReplace(config, arrayMode, isOptional, squash);\n\t        // array config: param name (param[]) overrides default settings.  explicit config overrides param name.\n\t        function getArrayMode() {\n\t            var arrayDefaults = { array: (location === DefType.SEARCH ? \"auto\" : false) };\n\t            var arrayParamNomenclature = id.match(/\\[\\]$/) ? { array: true } : {};\n\t            return common_1.extend(arrayDefaults, arrayParamNomenclature, config).array;\n\t        }\n\t        common_1.extend(this, { id: id, type: type, location: location, squash: squash, replace: replace, isOptional: isOptional, dynamic: dynamic, config: config, array: arrayMode });\n\t    }\n\t    Param.prototype.isDefaultValue = function (value) {\n\t        return this.isOptional && this.type.equals(this.value(), value);\n\t    };\n\t    /**\n\t     * [Internal] Gets the decoded representation of a value if the value is defined, otherwise, returns the\n\t     * default value, which may be the result of an injectable function.\n\t     */\n\t    Param.prototype.value = function (value) {\n\t        var _this = this;\n\t        /**\n\t         * [Internal] Get the default value of a parameter, which may be an injectable function.\n\t         */\n\t        var $$getDefaultValue = function () {\n\t            if (!coreservices_1.services.$injector)\n\t                throw new Error(\"Injectable functions cannot be called at configuration time\");\n\t            var defaultValue = coreservices_1.services.$injector.invoke(_this.config.$$fn);\n\t            if (defaultValue !== null && defaultValue !== undefined && !_this.type.is(defaultValue))\n\t                throw new Error(\"Default value (\" + defaultValue + \") for parameter '\" + _this.id + \"' is not an instance of ParamType (\" + _this.type.name + \")\");\n\t            return defaultValue;\n\t        };\n\t        var $replace = function (val) {\n\t            var replacement = common_1.map(common_1.filter(_this.replace, hof_1.propEq('from', val)), hof_1.prop(\"to\"));\n\t            return replacement.length ? replacement[0] : val;\n\t        };\n\t        value = $replace(value);\n\t        return !predicates_1.isDefined(value) ? $$getDefaultValue() : this.type.$normalize(value);\n\t    };\n\t    Param.prototype.isSearch = function () {\n\t        return this.location === DefType.SEARCH;\n\t    };\n\t    Param.prototype.validates = function (value) {\n\t        // There was no parameter value, but the param is optional\n\t        if ((!predicates_1.isDefined(value) || value === null) && this.isOptional)\n\t            return true;\n\t        // The value was not of the correct ParamType, and could not be decoded to the correct ParamType\n\t        var normalized = this.type.$normalize(value);\n\t        if (!this.type.is(normalized))\n\t            return false;\n\t        // The value was of the correct type, but when encoded, did not match the ParamType's regexp\n\t        var encoded = this.type.encode(normalized);\n\t        return !(predicates_1.isString(encoded) && !this.type.pattern.exec(encoded));\n\t    };\n\t    Param.prototype.toString = function () {\n\t        return \"{Param:\" + this.id + \" \" + this.type + \" squash: '\" + this.squash + \"' optional: \" + this.isOptional + \"}\";\n\t    };\n\t    /** Creates a new [[Param]] from a CONFIG block */\n\t    Param.fromConfig = function (id, type, config) {\n\t        return new Param(id, type, config, DefType.CONFIG);\n\t    };\n\t    /** Creates a new [[Param]] from a url PATH */\n\t    Param.fromPath = function (id, type, config) {\n\t        return new Param(id, type, config, DefType.PATH);\n\t    };\n\t    /** Creates a new [[Param]] from a url SEARCH */\n\t    Param.fromSearch = function (id, type, config) {\n\t        return new Param(id, type, config, DefType.SEARCH);\n\t    };\n\t    Param.values = function (params, values) {\n\t        if (values === void 0) { values = {}; }\n\t        return params.map(function (param) { return [param.id, param.value(values[param.id])]; }).reduce(common_1.applyPairs, {});\n\t    };\n\t    /**\n\t     * Finds [[Param]] objects which have different param values\n\t     *\n\t     * Filters a list of [[Param]] objects to only those whose parameter values differ in two param value objects\n\t     *\n\t     * @param params: The list of Param objects to filter\n\t     * @param values1: The first set of parameter values\n\t     * @param values2: the second set of parameter values\n\t     *\n\t     * @returns any Param objects whose values were different between values1 and values2\n\t     */\n\t    Param.changed = function (params, values1, values2) {\n\t        if (values1 === void 0) { values1 = {}; }\n\t        if (values2 === void 0) { values2 = {}; }\n\t        return params.filter(function (param) { return !param.type.equals(values1[param.id], values2[param.id]); });\n\t    };\n\t    /**\n\t     * Checks if two param value objects are equal (for a set of [[Param]] objects)\n\t     *\n\t     * @param params The list of [[Param]] objects to check\n\t     * @param values1 The first set of param values\n\t     * @param values2 The second set of param values\n\t     *\n\t     * @returns true if the param values in values1 and values2 are equal\n\t     */\n\t    Param.equals = function (params, values1, values2) {\n\t        if (values1 === void 0) { values1 = {}; }\n\t        if (values2 === void 0) { values2 = {}; }\n\t        return Param.changed(params, values1, values2).length === 0;\n\t    };\n\t    /** Returns true if a the parameter values are valid, according to the Param definitions */\n\t    Param.validates = function (params, values) {\n\t        if (values === void 0) { values = {}; }\n\t        return params.map(function (param) { return param.validates(values[param.id]); }).reduce(common_1.allTrueR, true);\n\t    };\n\t    return Param;\n\t}());\n\texports.Param = Param;\n\n\n/***/ },\n/* 23 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module url */ /** for typedoc */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar MatcherConfig = (function () {\n\t    function MatcherConfig() {\n\t        this._isCaseInsensitive = false;\n\t        this._isStrictMode = true;\n\t        this._defaultSquashPolicy = false;\n\t    }\n\t    MatcherConfig.prototype.caseInsensitive = function (value) {\n\t        return this._isCaseInsensitive = predicates_1.isDefined(value) ? value : this._isCaseInsensitive;\n\t    };\n\t    MatcherConfig.prototype.strictMode = function (value) {\n\t        return this._isStrictMode = predicates_1.isDefined(value) ? value : this._isStrictMode;\n\t    };\n\t    MatcherConfig.prototype.defaultSquashPolicy = function (value) {\n\t        if (predicates_1.isDefined(value) && value !== true && value !== false && !predicates_1.isString(value))\n\t            throw new Error(\"Invalid squash policy: \" + value + \". Valid policies: false, true, arbitrary-string\");\n\t        return this._defaultSquashPolicy = predicates_1.isDefined(value) ? value : this._defaultSquashPolicy;\n\t    };\n\t    return MatcherConfig;\n\t}());\n\texports.MatcherConfig = MatcherConfig;\n\t// TODO: Do not export global instance; create one in UIRouter() constructor\n\texports.matcherConfig = new MatcherConfig();\n\n\n/***/ },\n/* 24 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module params */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\t/**\n\t * Wraps up a `ParamType` object to handle array values.\n\t */\n\tfunction ArrayType(type, mode) {\n\t    var _this = this;\n\t    // Wrap non-array value as array\n\t    function arrayWrap(val) { return predicates_1.isArray(val) ? val : (predicates_1.isDefined(val) ? [val] : []); }\n\t    // Unwrap array value for \"auto\" mode. Return undefined for empty array.\n\t    function arrayUnwrap(val) {\n\t        switch (val.length) {\n\t            case 0: return undefined;\n\t            case 1: return mode === \"auto\" ? val[0] : val;\n\t            default: return val;\n\t        }\n\t    }\n\t    // Wraps type (.is/.encode/.decode) functions to operate on each value of an array\n\t    function arrayHandler(callback, allTruthyMode) {\n\t        return function handleArray(val) {\n\t            if (predicates_1.isArray(val) && val.length === 0)\n\t                return val;\n\t            var arr = arrayWrap(val);\n\t            var result = common_1.map(arr, callback);\n\t            return (allTruthyMode === true) ? common_1.filter(result, function (x) { return !x; }).length === 0 : arrayUnwrap(result);\n\t        };\n\t    }\n\t    // Wraps type (.equals) functions to operate on each value of an array\n\t    function arrayEqualsHandler(callback) {\n\t        return function handleArray(val1, val2) {\n\t            var left = arrayWrap(val1), right = arrayWrap(val2);\n\t            if (left.length !== right.length)\n\t                return false;\n\t            for (var i = 0; i < left.length; i++) {\n\t                if (!callback(left[i], right[i]))\n\t                    return false;\n\t            }\n\t            return true;\n\t        };\n\t    }\n\t    ['encode', 'decode', 'equals', '$normalize'].map(function (name) {\n\t        _this[name] = (name === 'equals' ? arrayEqualsHandler : arrayHandler)(type[name].bind(type));\n\t    });\n\t    common_1.extend(this, {\n\t        dynamic: type.dynamic,\n\t        name: type.name,\n\t        pattern: type.pattern,\n\t        is: arrayHandler(type.is.bind(type), true),\n\t        $arrayMode: mode\n\t    });\n\t}\n\t/**\n\t * A class that implements Custom Parameter Type functionality.\n\t *\n\t * This class has naive implementations for all the [[ParamTypeDefinition]] methods.\n\t *\n\t * An instance of this class is created when a custom [[ParamTypeDefinition]] object is registered with the [[UrlMatcherFactory.type]].\n\t *\n\t * Used by [[UrlMatcher]] when matching or formatting URLs, or comparing and validating parameter values.\n\t *\n\t * @example\n\t * ```\n\t *\n\t * {\n\t *   decode: function(val) { return parseInt(val, 10); },\n\t *   encode: function(val) { return val && val.toString(); },\n\t *   equals: function(a, b) { return this.is(a) && a === b; },\n\t *   is: function(val) { return angular.isNumber(val) && isFinite(val) && val % 1 === 0; },\n\t *   pattern: /\\d+/\n\t * }\n\t * ```\n\t */\n\tvar ParamType = (function () {\n\t    /**\n\t     * @param def  A configuration object which contains the custom type definition.  The object's\n\t     *        properties will override the default methods and/or pattern in `ParamType`'s public interface.\n\t     * @returns a new ParamType object\n\t     */\n\t    function ParamType(def) {\n\t        this.pattern = /.*/;\n\t        common_1.extend(this, def);\n\t    }\n\t    // consider these four methods to be \"abstract methods\" that should be overridden\n\t    /** @inheritdoc */\n\t    ParamType.prototype.is = function (val, key) { return true; };\n\t    /** @inheritdoc */\n\t    ParamType.prototype.encode = function (val, key) { return val; };\n\t    /** @inheritdoc */\n\t    ParamType.prototype.decode = function (val, key) { return val; };\n\t    /** @inheritdoc */\n\t    ParamType.prototype.equals = function (a, b) { return a == b; };\n\t    ParamType.prototype.$subPattern = function () {\n\t        var sub = this.pattern.toString();\n\t        return sub.substr(1, sub.length - 2);\n\t    };\n\t    ParamType.prototype.toString = function () {\n\t        return \"{ParamType:\" + this.name + \"}\";\n\t    };\n\t    /** Given an encoded string, or a decoded object, returns a decoded object */\n\t    ParamType.prototype.$normalize = function (val) {\n\t        return this.is(val) ? val : this.decode(val);\n\t    };\n\t    /**\n\t     * Wraps an existing custom ParamType as an array of ParamType, depending on 'mode'.\n\t     * e.g.:\n\t     * - urlmatcher pattern \"/path?{queryParam[]:int}\"\n\t     * - url: \"/path?queryParam=1&queryParam=2\n\t     * - $stateParams.queryParam will be [1, 2]\n\t     * if `mode` is \"auto\", then\n\t     * - url: \"/path?queryParam=1 will create $stateParams.queryParam: 1\n\t     * - url: \"/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2]\n\t     */\n\t    ParamType.prototype.$asArray = function (mode, isSearch) {\n\t        if (!mode)\n\t            return this;\n\t        if (mode === \"auto\" && !isSearch)\n\t            throw new Error(\"'auto' array mode is for query parameters only\");\n\t        return new ArrayType(this, mode);\n\t    };\n\t    return ParamType;\n\t}());\n\texports.ParamType = ParamType;\n\n\n/***/ },\n/* 25 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module params */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar type_1 = __webpack_require__(24);\n\t// Use tildes to pre-encode slashes.\n\t// If the slashes are simply URLEncoded, the browser can choose to pre-decode them,\n\t// and bidirectional encoding/decoding fails.\n\t// Tilde was chosen because it's not a RFC 3986 section 2.2 Reserved Character\n\tfunction valToString(val) { return val != null ? val.toString().replace(/~/g, \"~~\").replace(/\\//g, \"~2F\") : val; }\n\tfunction valFromString(val) { return val != null ? val.toString().replace(/~2F/g, \"/\").replace(/~~/g, \"~\") : val; }\n\tvar ParamTypes = (function () {\n\t    function ParamTypes() {\n\t        this.enqueue = true;\n\t        this.typeQueue = [];\n\t        this.defaultTypes = {\n\t            \"hash\": {\n\t                encode: valToString,\n\t                decode: valFromString,\n\t                is: hof_1.is(String),\n\t                pattern: /.*/,\n\t                equals: function (a, b) { return a == b; } // allow coersion for null/undefined/\"\"\n\t            },\n\t            \"string\": {\n\t                encode: valToString,\n\t                decode: valFromString,\n\t                is: hof_1.is(String),\n\t                pattern: /[^/]*/\n\t            },\n\t            \"int\": {\n\t                encode: valToString,\n\t                decode: function (val) { return parseInt(val, 10); },\n\t                is: function (val) { return predicates_1.isDefined(val) && this.decode(val.toString()) === val; },\n\t                pattern: /-?\\d+/\n\t            },\n\t            \"bool\": {\n\t                encode: function (val) { return val && 1 || 0; },\n\t                decode: function (val) { return parseInt(val, 10) !== 0; },\n\t                is: hof_1.is(Boolean),\n\t                pattern: /0|1/\n\t            },\n\t            \"date\": {\n\t                encode: function (val) {\n\t                    return !this.is(val) ? undefined : [\n\t                        val.getFullYear(),\n\t                        ('0' + (val.getMonth() + 1)).slice(-2),\n\t                        ('0' + val.getDate()).slice(-2)\n\t                    ].join(\"-\");\n\t                },\n\t                decode: function (val) {\n\t                    if (this.is(val))\n\t                        return val;\n\t                    var match = this.capture.exec(val);\n\t                    return match ? new Date(match[1], match[2] - 1, match[3]) : undefined;\n\t                },\n\t                is: function (val) { return val instanceof Date && !isNaN(val.valueOf()); },\n\t                equals: function (l, r) {\n\t                    return ['getFullYear', 'getMonth', 'getDate']\n\t                        .reduce(function (acc, fn) { return acc && l[fn]() === r[fn](); }, true);\n\t                },\n\t                pattern: /[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,\n\t                capture: /([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/\n\t            },\n\t            \"json\": {\n\t                encode: common_1.toJson,\n\t                decode: common_1.fromJson,\n\t                is: hof_1.is(Object),\n\t                equals: common_1.equals,\n\t                pattern: /[^/]*/\n\t            },\n\t            \"any\": {\n\t                encode: common_1.identity,\n\t                decode: common_1.identity,\n\t                equals: common_1.equals,\n\t                pattern: /.*/\n\t            }\n\t        };\n\t        // Register default types. Store them in the prototype of this.types.\n\t        var makeType = function (definition, name) { return new type_1.ParamType(common_1.extend({ name: name }, definition)); };\n\t        this.types = common_1.inherit(common_1.map(this.defaultTypes, makeType), {});\n\t    }\n\t    ParamTypes.prototype.type = function (name, definition, definitionFn) {\n\t        if (!predicates_1.isDefined(definition))\n\t            return this.types[name];\n\t        if (this.types.hasOwnProperty(name))\n\t            throw new Error(\"A type named '\" + name + \"' has already been defined.\");\n\t        this.types[name] = new type_1.ParamType(common_1.extend({ name: name }, definition));\n\t        if (definitionFn) {\n\t            this.typeQueue.push({ name: name, def: definitionFn });\n\t            if (!this.enqueue)\n\t                this._flushTypeQueue();\n\t        }\n\t        return this;\n\t    };\n\t    ParamTypes.prototype._flushTypeQueue = function () {\n\t        while (this.typeQueue.length) {\n\t            var type = this.typeQueue.shift();\n\t            if (type.pattern)\n\t                throw new Error(\"You cannot override a type's .pattern at runtime.\");\n\t            common_1.extend(this.types[type.name], coreservices_1.services.$injector.invoke(type.def));\n\t        }\n\t    };\n\t    return ParamTypes;\n\t}());\n\texports.ParamTypes = ParamTypes;\n\texports.paramTypes = new ParamTypes();\n\n\n/***/ },\n/* 26 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module core */ /** */\n\tvar urlMatcherFactory_1 = __webpack_require__(27);\n\tvar urlRouter_1 = __webpack_require__(29);\n\tvar state_1 = __webpack_require__(30);\n\tvar urlRouter_2 = __webpack_require__(29);\n\tvar transitionService_1 = __webpack_require__(31);\n\tvar view_1 = __webpack_require__(37);\n\tvar stateRegistry_1 = __webpack_require__(38);\n\tvar stateService_1 = __webpack_require__(43);\n\tvar globals_1 = __webpack_require__(44);\n\t/**\n\t * The master class used to instantiate an instance of UI-Router.\n\t *\n\t * This class instantiates and wires the global UI-Router services.\n\t *\n\t * After instantiating a new instance of the Router class, configure it for your app.  For instance, register\n\t * your app states with the [[stateRegistry]] (and set url options using ...).  Then, tell UI-Router to monitor\n\t * the URL by calling `urlRouter.listen()` ([[URLRouter.listen]])\n\t */\n\tvar UIRouter = (function () {\n\t    function UIRouter() {\n\t        this.viewService = new view_1.ViewService();\n\t        this.transitionService = new transitionService_1.TransitionService(this);\n\t        this.globals = new globals_1.Globals(this.transitionService);\n\t        this.urlMatcherFactory = new urlMatcherFactory_1.UrlMatcherFactory();\n\t        this.urlRouterProvider = new urlRouter_1.UrlRouterProvider(this.urlMatcherFactory, this.globals.params);\n\t        this.urlRouter = new urlRouter_2.UrlRouter(this.urlRouterProvider);\n\t        this.stateRegistry = new stateRegistry_1.StateRegistry(this.urlMatcherFactory, this.urlRouterProvider);\n\t        /** @hidden TODO: move this to ng1.ts */\n\t        this.stateProvider = new state_1.StateProvider(this.stateRegistry);\n\t        this.stateService = new stateService_1.StateService(this);\n\t        this.viewService.rootContext(this.stateRegistry.root());\n\t        this.globals.$current = this.stateRegistry.root();\n\t        this.globals.current = this.globals.$current.self;\n\t    }\n\t    return UIRouter;\n\t}());\n\texports.UIRouter = UIRouter;\n\n\n/***/ },\n/* 27 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module url */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar urlMatcher_1 = __webpack_require__(28);\n\tvar urlMatcherConfig_1 = __webpack_require__(23);\n\tvar param_1 = __webpack_require__(22);\n\tvar paramTypes_1 = __webpack_require__(25);\n\t/** @hidden */\n\tfunction getDefaultConfig() {\n\t    return {\n\t        strict: urlMatcherConfig_1.matcherConfig.strictMode(),\n\t        caseInsensitive: urlMatcherConfig_1.matcherConfig.caseInsensitive()\n\t    };\n\t}\n\t/**\n\t * Factory for [[UrlMatcher]] instances.\n\t *\n\t * The factory is available to ng1 services as\n\t * `$urlMatcherFactor` or ng1 providers as `$urlMatcherFactoryProvider`.\n\t */\n\tvar UrlMatcherFactory = (function () {\n\t    function UrlMatcherFactory() {\n\t        common_1.extend(this, { UrlMatcher: urlMatcher_1.UrlMatcher, Param: param_1.Param });\n\t    }\n\t    /**\n\t     * Defines whether URL matching should be case sensitive (the default behavior), or not.\n\t     *\n\t     * @param value `false` to match URL in a case sensitive manner; otherwise `true`;\n\t     * @returns the current value of caseInsensitive\n\t     */\n\t    UrlMatcherFactory.prototype.caseInsensitive = function (value) {\n\t        return urlMatcherConfig_1.matcherConfig.caseInsensitive(value);\n\t    };\n\t    /**\n\t     * Defines whether URLs should match trailing slashes, or not (the default behavior).\n\t     *\n\t     * @param value `false` to match trailing slashes in URLs, otherwise `true`.\n\t     * @returns the current value of strictMode\n\t     */\n\t    UrlMatcherFactory.prototype.strictMode = function (value) {\n\t        return urlMatcherConfig_1.matcherConfig.strictMode(value);\n\t    };\n\t    /**\n\t     * Sets the default behavior when generating or matching URLs with default parameter values.\n\t     *\n\t     * @param value A string that defines the default parameter URL squashing behavior.\n\t     *    - `nosquash`: When generating an href with a default parameter value, do not squash the parameter value from the URL\n\t     *    - `slash`: When generating an href with a default parameter value, squash (remove) the parameter value, and, if the\n\t     *             parameter is surrounded by slashes, squash (remove) one slash from the URL\n\t     *    - any other string, e.g. \"~\": When generating an href with a default parameter value, squash (remove)\n\t     *             the parameter value from the URL and replace it with this string.\n\t     * @returns the current value of defaultSquashPolicy\n\t     */\n\t    UrlMatcherFactory.prototype.defaultSquashPolicy = function (value) {\n\t        return urlMatcherConfig_1.matcherConfig.defaultSquashPolicy(value);\n\t    };\n\t    /**\n\t     * Creates a [[UrlMatcher]] for the specified pattern.\n\t     *\n\t     * @param pattern  The URL pattern.\n\t     * @param config  The config object hash.\n\t     * @returns The UrlMatcher.\n\t     */\n\t    UrlMatcherFactory.prototype.compile = function (pattern, config) {\n\t        return new urlMatcher_1.UrlMatcher(pattern, common_1.extend(getDefaultConfig(), config));\n\t    };\n\t    /**\n\t     * Returns true if the specified object is a [[UrlMatcher]], or false otherwise.\n\t     *\n\t     * @param object  The object to perform the type check against.\n\t     * @returns `true` if the object matches the `UrlMatcher` interface, by\n\t     *          implementing all the same methods.\n\t     */\n\t    UrlMatcherFactory.prototype.isMatcher = function (object) {\n\t        // TODO: typeof?\n\t        if (!predicates_1.isObject(object))\n\t            return false;\n\t        var result = true;\n\t        common_1.forEach(urlMatcher_1.UrlMatcher.prototype, function (val, name) {\n\t            if (predicates_1.isFunction(val))\n\t                result = result && (predicates_1.isDefined(object[name]) && predicates_1.isFunction(object[name]));\n\t        });\n\t        return result;\n\t    };\n\t    ;\n\t    /**\n\t     * Creates and registers a custom [[ParamType]] object that can be used to generate URLs with typed parameters.\n\t     *\n\t     * @param name  The type name.\n\t     * @param definition The type definition. See [[ParamTypeDefinition]] for information on the values accepted.\n\t     * @param definitionFn A function that is injected before the app\n\t     *        runtime starts.  The result of this function is merged into the existing `definition`.\n\t     *        See [[ParamType]] for information on the values accepted.\n\t     *\n\t     * @returns - if a type was registered: the [[UrlMatcherFactory]]\n\t     *   - if only the `name` parameter was specified: the currently registered [[ParamType]] object, or undefined\n\t     *\n\t     * This is a simple example of a custom type that encodes and decodes items from an\n\t     * array, using the array index as the URL-encoded value:\n\t     */\n\t    UrlMatcherFactory.prototype.type = function (name, definition, definitionFn) {\n\t        var type = paramTypes_1.paramTypes.type(name, definition, definitionFn);\n\t        return !predicates_1.isDefined(definition) ? type : this;\n\t    };\n\t    ;\n\t    /** @hidden */\n\t    UrlMatcherFactory.prototype.$get = function () {\n\t        paramTypes_1.paramTypes.enqueue = false;\n\t        paramTypes_1.paramTypes._flushTypeQueue();\n\t        return this;\n\t    };\n\t    ;\n\t    return UrlMatcherFactory;\n\t}());\n\texports.UrlMatcherFactory = UrlMatcherFactory;\n\n\n/***/ },\n/* 28 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module url */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar param_1 = __webpack_require__(22);\n\tvar paramTypes_1 = __webpack_require__(25);\n\tvar predicates_2 = __webpack_require__(4);\n\tvar param_2 = __webpack_require__(22);\n\tvar common_2 = __webpack_require__(3);\n\tvar common_3 = __webpack_require__(3);\n\t/** @hidden */\n\tfunction quoteRegExp(string, param) {\n\t    var surroundPattern = ['', ''], result = string.replace(/[\\\\\\[\\]\\^$*+?.()|{}]/g, \"\\\\$&\");\n\t    if (!param)\n\t        return result;\n\t    switch (param.squash) {\n\t        case false:\n\t            surroundPattern = ['(', ')' + (param.isOptional ? '?' : '')];\n\t            break;\n\t        case true:\n\t            result = result.replace(/\\/$/, '');\n\t            surroundPattern = ['(?:\\/(', ')|\\/)?'];\n\t            break;\n\t        default:\n\t            surroundPattern = [(\"(\" + param.squash + \"|\"), ')?'];\n\t            break;\n\t    }\n\t    return result + surroundPattern[0] + param.type.pattern.source + surroundPattern[1];\n\t}\n\t/** @hidden */\n\tvar memoizeTo = function (obj, prop, fn) { return obj[prop] = obj[prop] || fn(); };\n\t/**\n\t * Matches URLs against patterns.\n\t *\n\t * Matches URLs against patterns and extracts named parameters from the path or the search\n\t * part of the URL.\n\t *\n\t * A URL pattern consists of a path pattern, optionally followed by '?' and a list of search (query)\n\t * parameters. Multiple search parameter names are separated by '&'. Search parameters\n\t * do not influence whether or not a URL is matched, but their values are passed through into\n\t * the matched parameters returned by [[UrlMatcher.exec]].\n\t *\n\t * - *Path parameters* are defined using curly brace placeholders (`/somepath/{param}`)\n\t * or colon placeholders (`/somePath/:param`).\n\t *\n\t * - *A parameter RegExp* may be defined for a param after a colon\n\t * (`/somePath/{param:[a-zA-Z0-9]+}`) in a curly brace placeholder.\n\t * The regexp must match for the url to be matched.\n\t * Should the regexp itself contain curly braces, they must be in matched pairs or escaped with a backslash.\n\t *\n\t * - *Custom parameter types* may also be specified after a colon (`/somePath/{param:int}`)\n\t * in curly brace parameters.  See [[UrlMatcherFactory.type]] for more information.\n\t *\n\t * - *Catch-all parameters* are defined using an asterisk placeholder (`/somepath/*catchallparam`).  A catch-all\n\t * parameter value will contain the remainder of the URL.\n\t *\n\t * ---\n\t *\n\t * Parameter names may contain only word characters (latin letters, digits, and underscore) and\n\t * must be unique within the pattern (across both path and search parameters).\n\t * A path parameter matches any number of characters other than '/'. For catch-all\n\t * placeholders the path parameter matches any number of characters.\n\t *\n\t * Examples:\n\t *\n\t * * `'/hello/'` - Matches only if the path is exactly '/hello/'. There is no special treatment for\n\t *   trailing slashes, and patterns have to match the entire path, not just a prefix.\n\t * * `'/user/:id'` - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or\n\t *   '/user/bob/details'. The second path segment will be captured as the parameter 'id'.\n\t * * `'/user/{id}'` - Same as the previous example, but using curly brace syntax.\n\t * * `'/user/{id:[^/]*}'` - Same as the previous example.\n\t * * `'/user/{id:[0-9a-fA-F]{1,8}}'` - Similar to the previous example, but only matches if the id\n\t *   parameter consists of 1 to 8 hex digits.\n\t * * `'/files/{path:.*}'` - Matches any URL starting with '/files/' and captures the rest of the\n\t *   path into the parameter 'path'.\n\t * * `'/files/*path'` - ditto.\n\t * * `'/calendar/{start:date}'` - Matches \"/calendar/2014-11-12\" (because the pattern defined\n\t *   in the built-in  `date` ParamType matches `2014-11-12`) and provides a Date object in $stateParams.start\n\t *\n\t */\n\tvar UrlMatcher = (function () {\n\t    /**\n\t     * @param pattern The pattern to compile into a matcher.\n\t     * @param config  A configuration object hash\n\t     * * `caseInsensitive` - `true` if URL matching should be case insensitive, otherwise `false`, the default value (for backward compatibility) is `false`.\n\t     * * `strict` - `false` if matching against a URL with a trailing slash should be treated as equivalent to a URL without a trailing slash, the default value is `true`.\n\t     *\n\t     * @property {string} pattern  The pattern that was passed into the constructor\n\t     */\n\t    function UrlMatcher(pattern, config) {\n\t        var _this = this;\n\t        this.config = config;\n\t        /** @hidden */\n\t        this._cache = { path: [], pattern: null };\n\t        /** @hidden */\n\t        this._children = [];\n\t        /** @hidden */\n\t        this._params = [];\n\t        /** @hidden */\n\t        this._segments = [];\n\t        /** @hidden */\n\t        this._compiled = [];\n\t        this.pattern = pattern;\n\t        this.config = common_1.defaults(this.config, {\n\t            params: {},\n\t            strict: true,\n\t            caseInsensitive: false,\n\t            paramMap: common_1.identity\n\t        });\n\t        // Find all placeholders and create a compiled pattern, using either classic or curly syntax:\n\t        //   '*' name\n\t        //   ':' name\n\t        //   '{' name '}'\n\t        //   '{' name ':' regexp '}'\n\t        // The regular expression is somewhat complicated due to the need to allow curly braces\n\t        // inside the regular expression. The placeholder regexp breaks down as follows:\n\t        //    ([:*])([\\w\\[\\]]+)              - classic placeholder ($1 / $2) (search version has - for snake-case)\n\t        //    \\{([\\w\\[\\]]+)(?:\\:\\s*( ... ))?\\}  - curly brace placeholder ($3) with optional regexp/type ... ($4) (search version has - for snake-case\n\t        //    (?: ... | ... | ... )+         - the regexp consists of any number of atoms, an atom being either\n\t        //    [^{}\\\\]+                       - anything other than curly braces or backslash\n\t        //    \\\\.                            - a backslash escape\n\t        //    \\{(?:[^{}\\\\]+|\\\\.)*\\}          - a matched set of curly braces containing other atoms\n\t        var placeholder = /([:*])([\\w\\[\\]]+)|\\{([\\w\\[\\]]+)(?:\\:\\s*((?:[^{}\\\\]+|\\\\.|\\{(?:[^{}\\\\]+|\\\\.)*\\})+))?\\}/g, searchPlaceholder = /([:]?)([\\w\\[\\].-]+)|\\{([\\w\\[\\].-]+)(?:\\:\\s*((?:[^{}\\\\]+|\\\\.|\\{(?:[^{}\\\\]+|\\\\.)*\\})+))?\\}/g, last = 0, m, patterns = [];\n\t        var checkParamErrors = function (id) {\n\t            if (!UrlMatcher.nameValidator.test(id))\n\t                throw new Error(\"Invalid parameter name '\" + id + \"' in pattern '\" + pattern + \"'\");\n\t            if (common_1.find(_this._params, hof_1.propEq('id', id)))\n\t                throw new Error(\"Duplicate parameter name '\" + id + \"' in pattern '\" + pattern + \"'\");\n\t        };\n\t        // Split into static segments separated by path parameter placeholders.\n\t        // The number of segments is always 1 more than the number of parameters.\n\t        var matchDetails = function (m, isSearch) {\n\t            // IE[78] returns '' for unmatched groups instead of null\n\t            var id = m[2] || m[3], regexp = isSearch ? m[4] : m[4] || (m[1] === '*' ? '.*' : null);\n\t            return {\n\t                id: id,\n\t                regexp: regexp,\n\t                cfg: _this.config.params[id],\n\t                segment: pattern.substring(last, m.index),\n\t                type: !regexp ? null : paramTypes_1.paramTypes.type(regexp || \"string\") || common_1.inherit(paramTypes_1.paramTypes.type(\"string\"), {\n\t                    pattern: new RegExp(regexp, _this.config.caseInsensitive ? 'i' : undefined)\n\t                })\n\t            };\n\t        };\n\t        var p, segment;\n\t        while ((m = placeholder.exec(pattern))) {\n\t            p = matchDetails(m, false);\n\t            if (p.segment.indexOf('?') >= 0)\n\t                break; // we're into the search part\n\t            checkParamErrors(p.id);\n\t            this._params.push(param_1.Param.fromPath(p.id, p.type, this.config.paramMap(p.cfg, false)));\n\t            this._segments.push(p.segment);\n\t            patterns.push([p.segment, common_1.tail(this._params)]);\n\t            last = placeholder.lastIndex;\n\t        }\n\t        segment = pattern.substring(last);\n\t        // Find any search parameter names and remove them from the last segment\n\t        var i = segment.indexOf('?');\n\t        if (i >= 0) {\n\t            var search = segment.substring(i);\n\t            segment = segment.substring(0, i);\n\t            if (search.length > 0) {\n\t                last = 0;\n\t                while ((m = searchPlaceholder.exec(search))) {\n\t                    p = matchDetails(m, true);\n\t                    checkParamErrors(p.id);\n\t                    this._params.push(param_1.Param.fromSearch(p.id, p.type, this.config.paramMap(p.cfg, true)));\n\t                    last = placeholder.lastIndex;\n\t                }\n\t            }\n\t        }\n\t        this._segments.push(segment);\n\t        common_1.extend(this, {\n\t            _compiled: patterns.map(function (pattern) { return quoteRegExp.apply(null, pattern); }).concat(quoteRegExp(segment)),\n\t            prefix: this._segments[0]\n\t        });\n\t        Object.freeze(this);\n\t    }\n\t    /**\n\t     * Creates a new concatenated UrlMatcher\n\t     *\n\t     * Builds a new UrlMatcher by appending another UrlMatcher to this one.\n\t     *\n\t     * @param url A `UrlMatcher` instance to append as a child of the current `UrlMatcher`.\n\t     */\n\t    UrlMatcher.prototype.append = function (url) {\n\t        this._children.push(url);\n\t        common_1.forEach(url._cache, function (val, key) { return url._cache[key] = predicates_1.isArray(val) ? [] : null; });\n\t        url._cache.path = this._cache.path.concat(this);\n\t        return url;\n\t    };\n\t    /** @hidden */\n\t    UrlMatcher.prototype.isRoot = function () {\n\t        return this._cache.path.length === 0;\n\t    };\n\t    /** Returns the input pattern string */\n\t    UrlMatcher.prototype.toString = function () {\n\t        return this.pattern;\n\t    };\n\t    /**\n\t     * Tests the specified url/path against this matcher.\n\t     *\n\t     * Tests if the given url matches this matcher's pattern, and returns an object containing the captured\n\t     * parameter values.  Returns null if the path does not match.\n\t     *\n\t     * The returned object contains the values\n\t     * of any search parameters that are mentioned in the pattern, but their value may be null if\n\t     * they are not present in `search`. This means that search parameters are always treated\n\t     * as optional.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * new UrlMatcher('/user/{id}?q&r').exec('/user/bob', {\n\t     *   x: '1', q: 'hello'\n\t     * });\n\t     * // returns { id: 'bob', q: 'hello', r: null }\n\t     * ```\n\t     *\n\t     * @param path    The URL path to match, e.g. `$location.path()`.\n\t     * @param search  URL search parameters, e.g. `$location.search()`.\n\t     * @param hash    URL hash e.g. `$location.hash()`.\n\t     * @param options\n\t     *\n\t     * @returns The captured parameter values.\n\t     */\n\t    UrlMatcher.prototype.exec = function (path, search, hash, options) {\n\t        var _this = this;\n\t        if (search === void 0) { search = {}; }\n\t        if (options === void 0) { options = {}; }\n\t        var match = memoizeTo(this._cache, 'pattern', function () {\n\t            return new RegExp([\n\t                '^',\n\t                common_1.unnest(_this._cache.path.concat(_this).map(hof_1.prop('_compiled'))).join(''),\n\t                _this.config.strict === false ? '\\/?' : '',\n\t                '$'\n\t            ].join(''), _this.config.caseInsensitive ? 'i' : undefined);\n\t        }).exec(path);\n\t        if (!match)\n\t            return null;\n\t        //options = defaults(options, { isolate: false });\n\t        var allParams = this.parameters(), pathParams = allParams.filter(function (param) { return !param.isSearch(); }), searchParams = allParams.filter(function (param) { return param.isSearch(); }), nPathSegments = this._cache.path.concat(this).map(function (urlm) { return urlm._segments.length - 1; }).reduce(function (a, x) { return a + x; }), values = {};\n\t        if (nPathSegments !== match.length - 1)\n\t            throw new Error(\"Unbalanced capture group in route '\" + this.pattern + \"'\");\n\t        function decodePathArray(string) {\n\t            var reverseString = function (str) { return str.split(\"\").reverse().join(\"\"); };\n\t            var unquoteDashes = function (str) { return str.replace(/\\\\-/g, \"-\"); };\n\t            var split = reverseString(string).split(/-(?!\\\\)/);\n\t            var allReversed = common_1.map(split, reverseString);\n\t            return common_1.map(allReversed, unquoteDashes).reverse();\n\t        }\n\t        for (var i = 0; i < nPathSegments; i++) {\n\t            var param = pathParams[i];\n\t            var value = match[i + 1];\n\t            // if the param value matches a pre-replace pair, replace the value before decoding.\n\t            for (var j = 0; j < param.replace.length; j++) {\n\t                if (param.replace[j].from === value)\n\t                    value = param.replace[j].to;\n\t            }\n\t            if (value && param.array === true)\n\t                value = decodePathArray(value);\n\t            if (predicates_2.isDefined(value))\n\t                value = param.type.decode(value);\n\t            values[param.id] = param.value(value);\n\t        }\n\t        common_1.forEach(searchParams, function (param) {\n\t            var value = search[param.id];\n\t            for (var j = 0; j < param.replace.length; j++) {\n\t                if (param.replace[j].from === value)\n\t                    value = param.replace[j].to;\n\t            }\n\t            if (predicates_2.isDefined(value))\n\t                value = param.type.decode(value);\n\t            values[param.id] = param.value(value);\n\t        });\n\t        if (hash)\n\t            values[\"#\"] = hash;\n\t        return values;\n\t    };\n\t    /**\n\t     * @hidden\n\t     * Returns all the [[Param]] objects of all path and search parameters of this pattern in order of appearance.\n\t     *\n\t     * @returns {Array.<Param>}  An array of [[Param]] objects. Must be treated as read-only. If the\n\t     *    pattern has no parameters, an empty array is returned.\n\t     */\n\t    UrlMatcher.prototype.parameters = function (opts) {\n\t        if (opts === void 0) { opts = {}; }\n\t        if (opts.inherit === false)\n\t            return this._params;\n\t        return common_1.unnest(this._cache.path.concat(this).map(hof_1.prop('_params')));\n\t    };\n\t    /**\n\t     * @hidden\n\t     * Returns a single parameter from this UrlMatcher by id\n\t     *\n\t     * @param id\n\t     * @param opts\n\t     * @returns {T|Param|any|boolean|UrlMatcher|null}\n\t     */\n\t    UrlMatcher.prototype.parameter = function (id, opts) {\n\t        if (opts === void 0) { opts = {}; }\n\t        var parent = common_1.tail(this._cache.path);\n\t        return (common_1.find(this._params, hof_1.propEq('id', id)) ||\n\t            (opts.inherit !== false && parent && parent.parameter(id)) ||\n\t            null);\n\t    };\n\t    /**\n\t     * Validates the input parameter values against this UrlMatcher\n\t     *\n\t     * Checks an object hash of parameters to validate their correctness according to the parameter\n\t     * types of this `UrlMatcher`.\n\t     *\n\t     * @param params The object hash of parameters to validate.\n\t     * @returns Returns `true` if `params` validates, otherwise `false`.\n\t     */\n\t    UrlMatcher.prototype.validates = function (params) {\n\t        var _this = this;\n\t        var validParamVal = function (param, val) { return !param || param.validates(val); };\n\t        return common_1.pairs(params || {}).map(function (_a) {\n\t            var key = _a[0], val = _a[1];\n\t            return validParamVal(_this.parameter(key), val);\n\t        }).reduce(common_1.allTrueR, true);\n\t    };\n\t    /**\n\t     * Given a set of parameter values, creates a URL from this UrlMatcher.\n\t     *\n\t     * Creates a URL that matches this pattern by substituting the specified values\n\t     * for the path and search parameters.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });\n\t     * // returns '/user/bob?q=yes'\n\t     * ```\n\t     *\n\t     * @param values  the values to substitute for the parameters in this pattern.\n\t     * @returns the formatted URL (path and optionally search part).\n\t     */\n\t    UrlMatcher.prototype.format = function (values) {\n\t        if (values === void 0) { values = {}; }\n\t        if (!this.validates(values))\n\t            return null;\n\t        // Build the full path of UrlMatchers (including all parent UrlMatchers)\n\t        var urlMatchers = this._cache.path.slice().concat(this);\n\t        // Extract all the static segments and Params into an ordered array\n\t        var pathSegmentsAndParams = urlMatchers.map(UrlMatcher.pathSegmentsAndParams).reduce(common_2.unnestR, []);\n\t        // Extract the query params into a separate array\n\t        var queryParams = urlMatchers.map(UrlMatcher.queryParams).reduce(common_2.unnestR, []);\n\t        /**\n\t         * Given a Param,\n\t         * Applies the parameter value, then returns details about it\n\t         */\n\t        function getDetails(param) {\n\t            // Normalize to typed value\n\t            var value = param.value(values[param.id]);\n\t            var isDefaultValue = param.isDefaultValue(value);\n\t            // Check if we're in squash mode for the parameter\n\t            var squash = isDefaultValue ? param.squash : false;\n\t            // Allow the Parameter's Type to encode the value\n\t            var encoded = param.type.encode(value);\n\t            return { param: param, value: value, isDefaultValue: isDefaultValue, squash: squash, encoded: encoded };\n\t        }\n\t        // Build up the path-portion from the list of static segments and parameters\n\t        var pathString = pathSegmentsAndParams.reduce(function (acc, x) {\n\t            // The element is a static segment (a raw string); just append it\n\t            if (predicates_1.isString(x))\n\t                return acc + x;\n\t            // Otherwise, it's a Param.  Fetch details about the parameter value\n\t            var _a = getDetails(x), squash = _a.squash, encoded = _a.encoded, param = _a.param;\n\t            // If squash is === true, try to remove a slash from the path\n\t            if (squash === true)\n\t                return (acc.match(/\\/$/)) ? acc.slice(0, -1) : acc;\n\t            // If squash is a string, use the string for the param value\n\t            if (predicates_1.isString(squash))\n\t                return acc + squash;\n\t            if (squash !== false)\n\t                return acc; // ?\n\t            if (encoded == null)\n\t                return acc;\n\t            // If this parameter value is an array, encode the value using encodeDashes\n\t            if (predicates_1.isArray(encoded))\n\t                return acc + common_1.map(encoded, UrlMatcher.encodeDashes).join(\"-\");\n\t            // If the parameter type is \"raw\", then do not encodeURIComponent\n\t            if (param.type.raw)\n\t                return acc + encoded;\n\t            // Encode the value\n\t            return acc + encodeURIComponent(encoded);\n\t        }, \"\");\n\t        // Build the query string by applying parameter values (array or regular)\n\t        // then mapping to key=value, then flattening and joining using \"&\"\n\t        var queryString = queryParams.map(function (param) {\n\t            var _a = getDetails(param), squash = _a.squash, encoded = _a.encoded, isDefaultValue = _a.isDefaultValue;\n\t            if (encoded == null || (isDefaultValue && squash !== false))\n\t                return;\n\t            if (!predicates_1.isArray(encoded))\n\t                encoded = [encoded];\n\t            if (encoded.length === 0)\n\t                return;\n\t            if (!param.type.raw)\n\t                encoded = common_1.map(encoded, encodeURIComponent);\n\t            return encoded.map(function (val) { return (param.id + \"=\" + val); });\n\t        }).filter(common_1.identity).reduce(common_2.unnestR, []).join(\"&\");\n\t        // Concat the pathstring with the queryString (if exists) and the hashString (if exists)\n\t        return pathString + (queryString ? \"?\" + queryString : \"\") + (values[\"#\"] ? \"#\" + values[\"#\"] : \"\");\n\t    };\n\t    /** @hidden */\n\t    UrlMatcher.encodeDashes = function (str) {\n\t        return encodeURIComponent(str).replace(/-/g, function (c) { return (\"%5C%\" + c.charCodeAt(0).toString(16).toUpperCase()); });\n\t    };\n\t    /** @hidden Given a matcher, return an array with the matcher's path segments and path params, in order */\n\t    UrlMatcher.pathSegmentsAndParams = function (matcher) {\n\t        var staticSegments = matcher._segments;\n\t        var pathParams = matcher._params.filter(function (p) { return p.location === param_2.DefType.PATH; });\n\t        return common_3.arrayTuples(staticSegments, pathParams.concat(undefined)).reduce(common_2.unnestR, []).filter(function (x) { return x !== \"\" && predicates_2.isDefined(x); });\n\t    };\n\t    /** @hidden Given a matcher, return an array with the matcher's query params */\n\t    UrlMatcher.queryParams = function (matcher) {\n\t        return matcher._params.filter(function (p) { return p.location === param_2.DefType.SEARCH; });\n\t    };\n\t    /** @hidden */\n\t    UrlMatcher.nameValidator = /^\\w+([-.]+\\w+)*(?:\\[\\])?$/;\n\t    return UrlMatcher;\n\t}());\n\texports.UrlMatcher = UrlMatcher;\n\n\n/***/ },\n/* 29 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module url */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\t/** @hidden */\n\tvar $location = coreservices_1.services.location;\n\t/** @hidden Returns a string that is a prefix of all strings matching the RegExp */\n\tfunction regExpPrefix(re) {\n\t    var prefix = /^\\^((?:\\\\[^a-zA-Z0-9]|[^\\\\\\[\\]\\^$*+?.()|{}]+)*)/.exec(re.source);\n\t    return (prefix != null) ? prefix[1].replace(/\\\\(.)/g, \"$1\") : '';\n\t}\n\t/** @hidden Interpolates matched values into a String.replace()-style pattern */\n\tfunction interpolate(pattern, match) {\n\t    return pattern.replace(/\\$(\\$|\\d{1,2})/, function (m, what) {\n\t        return match[what === '$' ? 0 : Number(what)];\n\t    });\n\t}\n\t/** @hidden */\n\tfunction handleIfMatch($injector, $stateParams, handler, match) {\n\t    if (!match)\n\t        return false;\n\t    var result = $injector.invoke(handler, handler, { $match: match, $stateParams: $stateParams });\n\t    return predicates_1.isDefined(result) ? result : true;\n\t}\n\t/** @hidden */\n\tfunction appendBasePath(url, isHtml5, absolute) {\n\t    var baseHref = coreservices_1.services.locationConfig.baseHref();\n\t    if (baseHref === '/')\n\t        return url;\n\t    if (isHtml5)\n\t        return baseHref.slice(0, -1) + url;\n\t    if (absolute)\n\t        return baseHref.slice(1) + url;\n\t    return url;\n\t}\n\t// TODO: Optimize groups of rules with non-empty prefix into some sort of decision tree\n\t/** @hidden */\n\tfunction update(rules, otherwiseFn, evt) {\n\t    if (evt && evt.defaultPrevented)\n\t        return;\n\t    function check(rule) {\n\t        var handled = rule(coreservices_1.services.$injector, $location);\n\t        if (!handled)\n\t            return false;\n\t        if (predicates_1.isString(handled)) {\n\t            $location.replace();\n\t            $location.url(handled);\n\t        }\n\t        return true;\n\t    }\n\t    var n = rules.length, i;\n\t    for (i = 0; i < n; i++) {\n\t        if (check(rules[i]))\n\t            return;\n\t    }\n\t    // always check otherwise last to allow dynamic updates to the set of rules\n\t    if (otherwiseFn)\n\t        check(otherwiseFn);\n\t}\n\t/**\n\t * Manages rules for client-side URL\n\t *\n\t * This class manages the router rules for what to do when the URL changes.\n\t */\n\tvar UrlRouterProvider = (function () {\n\t    function UrlRouterProvider($urlMatcherFactory, $stateParams) {\n\t        /** @hidden */\n\t        this.rules = [];\n\t        /** @hidden */\n\t        this.interceptDeferred = false;\n\t        this.$urlMatcherFactory = $urlMatcherFactory;\n\t        this.$stateParams = $stateParams;\n\t    }\n\t    /**\n\t     * Registers a url handler function.\n\t     *\n\t     * Registers a low level url handler (a `rule`). A rule detects specific URL patterns and returns\n\t     * a redirect, or performs some action.\n\t     *\n\t     * If a rule returns a string, the URL is replaced with the string, and all rules are fired again.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * var app = angular.module('app', ['ui.router.router']);\n\t     *\n\t     * app.config(function ($urlRouterProvider) {\n\t     *   // Here's an example of how you might allow case insensitive urls\n\t     *   $urlRouterProvider.rule(function ($injector, $location) {\n\t     *     var path = $location.path(),\n\t     *         normalized = path.toLowerCase();\n\t     *\n\t     *     if (path !== normalized) {\n\t     *       return normalized;\n\t     *     }\n\t     *   });\n\t     * });\n\t     * ```\n\t     *\n\t     * @param rule\n\t     * Handler function that takes `$injector` and `$location` services as arguments.\n\t     * You can use them to detect a url and return a different url as a string.\n\t     *\n\t     * @return [[$urlRouterProvider]] (`this`)\n\t     */\n\t    UrlRouterProvider.prototype.rule = function (rule) {\n\t        if (!predicates_1.isFunction(rule))\n\t            throw new Error(\"'rule' must be a function\");\n\t        this.rules.push(rule);\n\t        return this;\n\t    };\n\t    ;\n\t    /**\n\t     * Defines the path or behavior to use when no url can be matched.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * var app = angular.module('app', ['ui.router.router']);\n\t     *\n\t     * app.config(function ($urlRouterProvider) {\n\t     *   // if the path doesn't match any of the urls you configured\n\t     *   // otherwise will take care of routing the user to the\n\t     *   // specified url\n\t     *   $urlRouterProvider.otherwise('/index');\n\t     *\n\t     *   // Example of using function rule as param\n\t     *   $urlRouterProvider.otherwise(function ($injector, $location) {\n\t     *     return '/a/valid/url';\n\t     *   });\n\t     * });\n\t     * ```\n\t     *\n\t     * @param rule\n\t     * The url path you want to redirect to or a function rule that returns the url path or performs a `$state.go()`.\n\t     * The function version is passed two params: `$injector` and `$location` services, and should return a url string.\n\t     *\n\t     * @return {object} `$urlRouterProvider` - `$urlRouterProvider` instance\n\t     */\n\t    UrlRouterProvider.prototype.otherwise = function (rule) {\n\t        if (!predicates_1.isFunction(rule) && !predicates_1.isString(rule))\n\t            throw new Error(\"'rule' must be a string or function\");\n\t        this.otherwiseFn = predicates_1.isString(rule) ? function () { return rule; } : rule;\n\t        return this;\n\t    };\n\t    ;\n\t    /**\n\t     * Registers a handler for a given url matching.\n\t     *\n\t     * If the handler is a string, it is\n\t     * treated as a redirect, and is interpolated according to the syntax of match\n\t     * (i.e. like `String.replace()` for `RegExp`, or like a `UrlMatcher` pattern otherwise).\n\t     *\n\t     * If the handler is a function, it is injectable.\n\t     * It gets invoked if `$location` matches.\n\t     * You have the option of inject the match object as `$match`.\n\t     *\n\t     * The handler can return\n\t     *\n\t     * - **falsy** to indicate that the rule didn't match after all, then `$urlRouter`\n\t     *   will continue trying to find another one that matches.\n\t     * - **string** which is treated as a redirect and passed to `$location.url()`\n\t     * - **void** or any **truthy** value tells `$urlRouter` that the url was handled.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * var app = angular.module('app', ['ui.router.router']);\n\t     *\n\t     * app.config(function ($urlRouterProvider) {\n\t     *   $urlRouterProvider.when($state.url, function ($match, $stateParams) {\n\t     *     if ($state.$current.navigable !== state ||\n\t     *         !equalForKeys($match, $stateParams) {\n\t     *      $state.transitionTo(state, $match, false);\n\t     *     }\n\t     *   });\n\t     * });\n\t     * ```\n\t     *\n\t     * @param what A pattern string to match, compiled as a [[UrlMatcher]].\n\t     * @param handler The path (or function that returns a path) that you want to redirect your user to.\n\t     *\n\t     * Note: the handler may also invoke arbitrary code, such as `$state.go()`\n\t     */\n\t    UrlRouterProvider.prototype.when = function (what, handler) {\n\t        var _a = this, $urlMatcherFactory = _a.$urlMatcherFactory, $stateParams = _a.$stateParams;\n\t        var redirect, handlerIsString = predicates_1.isString(handler);\n\t        // @todo Queue this\n\t        if (predicates_1.isString(what))\n\t            what = $urlMatcherFactory.compile(what);\n\t        if (!handlerIsString && !predicates_1.isFunction(handler) && !predicates_1.isArray(handler))\n\t            throw new Error(\"invalid 'handler' in when()\");\n\t        var strategies = {\n\t            matcher: function (_what, _handler) {\n\t                if (handlerIsString) {\n\t                    redirect = $urlMatcherFactory.compile(_handler);\n\t                    _handler = ['$match', redirect.format.bind(redirect)];\n\t                }\n\t                return common_1.extend(function () {\n\t                    return handleIfMatch(coreservices_1.services.$injector, $stateParams, _handler, _what.exec($location.path(), $location.search(), $location.hash()));\n\t                }, {\n\t                    prefix: predicates_1.isString(_what.prefix) ? _what.prefix : ''\n\t                });\n\t            },\n\t            regex: function (_what, _handler) {\n\t                if (_what.global || _what.sticky)\n\t                    throw new Error(\"when() RegExp must not be global or sticky\");\n\t                if (handlerIsString) {\n\t                    redirect = _handler;\n\t                    _handler = ['$match', function ($match) { return interpolate(redirect, $match); }];\n\t                }\n\t                return common_1.extend(function () {\n\t                    return handleIfMatch(coreservices_1.services.$injector, $stateParams, _handler, _what.exec($location.path()));\n\t                }, {\n\t                    prefix: regExpPrefix(_what)\n\t                });\n\t            }\n\t        };\n\t        var check = {\n\t            matcher: $urlMatcherFactory.isMatcher(what),\n\t            regex: what instanceof RegExp\n\t        };\n\t        for (var n in check) {\n\t            if (check[n])\n\t                return this.rule(strategies[n](what, handler));\n\t        }\n\t        throw new Error(\"invalid 'what' in when()\");\n\t    };\n\t    ;\n\t    /**\n\t     * Disables monitoring of the URL.\n\t     *\n\t     * Call this method before UI-Router has bootstrapped.\n\t     * It will stop UI-Router from performing the initial url sync.\n\t     *\n\t     * This can be useful to perform some asynchronous initialization before the router starts.\n\t     * Once the initialization is complete, call [[listen]] to tell UI-Router to start watching and synchronizing the URL.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * var app = angular.module('app', ['ui.router']);\n\t     *\n\t     * app.config(function ($urlRouterProvider) {\n\t     *   // Prevent $urlRouter from automatically intercepting URL changes;\n\t     *   $urlRouterProvider.deferIntercept();\n\t     * })\n\t     *\n\t     * app.run(function (MyService, $urlRouter, $http) {\n\t     *   $http.get(\"/stuff\").then(function(resp) {\n\t     *     MyService.doStuff(resp.data);\n\t     *     $urlRouter.listen();\n\t     *     $urlRouter.sync();\n\t     *   });\n\t     * });\n\t     * ```\n\t     *\n\t     * @param defer Indicates whether to defer location change interception. Passing\n\t     *        no parameter is equivalent to `true`.\n\t     */\n\t    UrlRouterProvider.prototype.deferIntercept = function (defer) {\n\t        if (defer === undefined)\n\t            defer = true;\n\t        this.interceptDeferred = defer;\n\t    };\n\t    ;\n\t    return UrlRouterProvider;\n\t}());\n\texports.UrlRouterProvider = UrlRouterProvider;\n\tvar UrlRouter = (function () {\n\t    /** @hidden */\n\t    function UrlRouter(urlRouterProvider) {\n\t        this.urlRouterProvider = urlRouterProvider;\n\t        common_1.bindFunctions(UrlRouter.prototype, this, this);\n\t    }\n\t    /**\n\t     * Checks the current URL for a matching rule\n\t     *\n\t     * Triggers an update; the same update that happens when the address bar url changes, aka `$locationChangeSuccess`.\n\t     * This method is useful when you need to use `preventDefault()` on the `$locationChangeSuccess` event,\n\t     * perform some custom logic (route protection, auth, config, redirection, etc) and then finally proceed\n\t     * with the transition by calling `$urlRouter.sync()`.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * angular.module('app', ['ui.router'])\n\t     *   .run(function($rootScope, $urlRouter) {\n\t     *     $rootScope.$on('$locationChangeSuccess', function(evt) {\n\t     *       // Halt state change from even starting\n\t     *       evt.preventDefault();\n\t     *       // Perform custom logic\n\t     *       var meetsRequirement = ...\n\t     *       // Continue with the update and state transition if logic allows\n\t     *       if (meetsRequirement) $urlRouter.sync();\n\t     *     });\n\t     * });\n\t     * ```\n\t     */\n\t    UrlRouter.prototype.sync = function () {\n\t        update(this.urlRouterProvider.rules, this.urlRouterProvider.otherwiseFn);\n\t    };\n\t    /**\n\t     * Starts listening for URL changes\n\t     *\n\t     * Call this sometime after calling [[deferIntercept]] to start monitoring the url.\n\t     * This causes [[UrlRouter]] to start listening for changes to the URL, if it wasn't already listening.\n\t     */\n\t    UrlRouter.prototype.listen = function () {\n\t        var _this = this;\n\t        return this.listener = this.listener || $location.onChange(function (evt) { return update(_this.urlRouterProvider.rules, _this.urlRouterProvider.otherwiseFn, evt); });\n\t    };\n\t    /**\n\t     * Internal API.\n\t     */\n\t    UrlRouter.prototype.update = function (read) {\n\t        if (read) {\n\t            this.location = $location.url();\n\t            return;\n\t        }\n\t        if ($location.url() === this.location)\n\t            return;\n\t        $location.url(this.location);\n\t        $location.replace();\n\t    };\n\t    /**\n\t     * Internal API.\n\t     *\n\t     * Pushes a new location to the browser history.\n\t     *\n\t     * @param urlMatcher\n\t     * @param params\n\t     * @param options\n\t     */\n\t    UrlRouter.prototype.push = function (urlMatcher, params, options) {\n\t        $location.url(urlMatcher.format(params || {}));\n\t        if (options && options.replace)\n\t            $location.replace();\n\t    };\n\t    /**\n\t     * Builds and returns a URL with interpolated parameters\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * $bob = $urlRouter.href(new UrlMatcher(\"/about/:person\"), {\n\t     *   person: \"bob\"\n\t     * });\n\t     * // $bob == \"/about/bob\";\n\t     * ```\n\t     *\n\t     * @param urlMatcher The [[UrlMatcher]] object which is used as the template of the URL to generate.\n\t     * @param params An object of parameter values to fill the matcher's required parameters.\n\t     * @param options Options object. The options are:\n\t     *\n\t     * - **`absolute`** - {boolean=false},  If true will generate an absolute url, e.g. \"http://www.example.com/fullurl\".\n\t     *\n\t     * @returns Returns the fully compiled URL, or `null` if `params` fail validation against `urlMatcher`\n\t     */\n\t    UrlRouter.prototype.href = function (urlMatcher, params, options) {\n\t        if (!urlMatcher.validates(params))\n\t            return null;\n\t        var url = urlMatcher.format(params);\n\t        options = options || { absolute: false };\n\t        var cfg = coreservices_1.services.locationConfig;\n\t        var isHtml5 = cfg.html5Mode();\n\t        if (!isHtml5 && url !== null) {\n\t            url = \"#\" + cfg.hashPrefix() + url;\n\t        }\n\t        url = appendBasePath(url, isHtml5, options.absolute);\n\t        if (!options.absolute || !url) {\n\t            return url;\n\t        }\n\t        var slash = (!isHtml5 && url ? '/' : ''), port = cfg.port();\n\t        port = (port === 80 || port === 443 ? '' : ':' + port);\n\t        return [cfg.protocol(), '://', cfg.host(), port, slash, url].join('');\n\t    };\n\t    return UrlRouter;\n\t}());\n\texports.UrlRouter = UrlRouter;\n\n\n/***/ },\n/* 30 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** for typedoc */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar common_1 = __webpack_require__(3);\n\t/**\n\t * @ngdoc object\n\t * @name ui.router.state.$stateProvider\n\t *\n\t * @requires ui.router.router.$urlRouterProvider\n\t * @requires ui.router.util.$urlMatcherFactoryProvider\n\t *\n\t * @description\n\t * The new `$stateProvider` works similar to Angular's v1 router, but it focuses purely\n\t * on state.\n\t *\n\t * A state corresponds to a \"place\" in the application in terms of the overall UI and\n\t * navigation. A state describes (via the controller / template / view properties) what\n\t * the UI looks like and does at that place.\n\t *\n\t * States often have things in common, and the primary way of factoring out these\n\t * commonalities in this model is via the state hierarchy, i.e. parent/child states aka\n\t * nested states.\n\t *\n\t * The `$stateProvider` provides interfaces to declare these states for your app.\n\t */\n\tvar StateProvider = (function () {\n\t    function StateProvider(stateRegistry) {\n\t        this.stateRegistry = stateRegistry;\n\t        this.invalidCallbacks = [];\n\t        common_1.bindFunctions(StateProvider.prototype, this, this);\n\t    }\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$stateProvider#decorator\n\t     * @methodOf ui.router.state.$stateProvider\n\t     *\n\t     * @description\n\t     * Allows you to extend (carefully) or override (at your own peril) the\n\t     * `stateBuilder` object used internally by `$stateProvider`. This can be used\n\t     * to add custom functionality to ui-router, for example inferring templateUrl\n\t     * based on the state name.\n\t     *\n\t     * When passing only a name, it returns the current (original or decorated) builder\n\t     * function that matches `name`.\n\t     *\n\t     * The builder functions that can be decorated are listed below. Though not all\n\t     * necessarily have a good use case for decoration, that is up to you to decide.\n\t     *\n\t     * In addition, users can attach custom decorators, which will generate new\n\t     * properties within the state's internal definition. There is currently no clear\n\t     * use-case for this beyond accessing internal states (i.e. $state.$current),\n\t     * however, expect this to become increasingly relevant as we introduce additional\n\t     * meta-programming features.\n\t     *\n\t     * **Warning**: Decorators should not be interdependent because the order of\n\t     * execution of the builder functions in non-deterministic. Builder functions\n\t     * should only be dependent on the state definition object and super function.\n\t     *\n\t     *\n\t     * Existing builder functions and current return values:\n\t     *\n\t     * - **parent** `{object}` - returns the parent state object.\n\t     * - **data** `{object}` - returns state data, including any inherited data that is not\n\t     *   overridden by own values (if any).\n\t     * - **url** `{object}` - returns a {@link ui.router.util.type:UrlMatcher UrlMatcher}\n\t     *   or `null`.\n\t     * - **navigable** `{object}` - returns closest ancestor state that has a URL (aka is\n\t     *   navigable).\n\t     * - **params** `{object}` - returns an array of state params that are ensured to\n\t     *   be a super-set of parent's params.\n\t     * - **views** `{object}` - returns a views object where each key is an absolute view\n\t     *   name (i.e. \"viewName@stateName\") and each value is the config object\n\t     *   (template, controller) for the view. Even when you don't use the views object\n\t     *   explicitly on a state config, one is still created for you internally.\n\t     *   So by decorating this builder function you have access to decorating template\n\t     *   and controller properties.\n\t     * - **ownParams** `{object}` - returns an array of params that belong to the state,\n\t     *   not including any params defined by ancestor states.\n\t     * - **path** `{string}` - returns the full path from the root down to this state.\n\t     *   Needed for state activation.\n\t     * - **includes** `{object}` - returns an object that includes every state that\n\t     *   would pass a `$state.includes()` test.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * // Override the internal 'views' builder with a function that takes the state\n\t     * // definition, and a reference to the internal function being overridden:\n\t     * $stateProvider.decorator('views', function (state, parent) {\n\t     *   let result = {},\n\t     *       views = parent(state);\n\t     *\n\t     *   angular.forEach(views, function (config, name) {\n\t     *     let autoName = (state.name + '.' + name).replace('.', '/');\n\t     *     config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html';\n\t     *     result[name] = config;\n\t     *   });\n\t     *   return result;\n\t     * });\n\t     *\n\t     * $stateProvider.state('home', {\n\t     *   views: {\n\t     *     'contact.list': { controller: 'ListController' },\n\t     *     'contact.item': { controller: 'ItemController' }\n\t     *   }\n\t     * });\n\t     *\n\t     * // ...\n\t     *\n\t     * $state.go('home');\n\t     * // Auto-populates list and item views with /partials/home/contact/list.html,\n\t     * // and /partials/home/contact/item.html, respectively.\n\t     * </pre>\n\t     *\n\t     * @param {string} name The name of the builder function to decorate.\n\t     * @param {object} func A function that is responsible for decorating the original\n\t     * builder function. The function receives two parameters:\n\t     *\n\t     *   - `{object}` - state - The state config object.\n\t     *   - `{object}` - super - The original builder function.\n\t     *\n\t     * @return {object} $stateProvider - $stateProvider instance\n\t     */\n\t    StateProvider.prototype.decorator = function (name, func) {\n\t        return this.stateRegistry.decorator(name, func) || this;\n\t    };\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$stateProvider#state\n\t     * @methodOf ui.router.state.$stateProvider\n\t     *\n\t     * @description\n\t     * Registers a state configuration under a given state name. The stateConfig object\n\t     * has the following acceptable properties.\n\t     *\n\t     * <a id='template'></a>\n\t     *\n\t     * - **`template`** - {string|function=} - html template as a string or a function that returns\n\t     *   an html template as a string which should be used by the uiView directives. This property\n\t     *   takes precedence over templateUrl.\n\t     *\n\t     *   If `template` is a function, it will be called with the following parameters:\n\t     *\n\t     *   - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by\n\t     *     applying the current state\n\t     *\n\t     * <a id='templateUrl'></a>\n\t     *\n\t     * - **`templateUrl`** - {string|function=} - path or function that returns a path to an html\n\t     *   template that should be used by uiView.\n\t     *\n\t     *   If `templateUrl` is a function, it will be called with the following parameters:\n\t     *\n\t     *   - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by\n\t     *     applying the current state\n\t     *\n\t     * <a id='templateProvider'></a>\n\t     *\n\t     * - **`templateProvider`** - {function=} - Provider function that returns HTML content\n\t     *   string.\n\t     *\n\t     * <a id='controller'></a>\n\t     *\n\t     * - **`controller`** - {string|function=} -  Controller fn that should be associated with newly\n\t     *   related scope or the name of a registered controller if passed as a string.\n\t     *\n\t     * <a id='controllerProvider'></a>\n\t     *\n\t     * - **`controllerProvider`** - {function=} - Injectable provider function that returns\n\t     *   the actual controller or string.\n\t     *\n\t     * <a id='controllerAs'></a>\n\t     *\n\t     * - **`controllerAs`** – {string=} – A controller alias name. If present the controller will be\n\t     *   published to scope under the controllerAs name.\n\t     *\n\t     * <a id='resolve'></a>\n\t     *\n\t     * - **`resolve`** - {object.&lt;string, function&gt;=} - An optional map of dependencies which\n\t     *   should be injected into the controller. If any of these dependencies are promises,\n\t     *   the router will wait for them all to be resolved or one to be rejected before the\n\t     *   controller is instantiated. If all the promises are resolved successfully, the values\n\t     *   of the resolved promises are injected and $stateChangeSuccess event is fired. If any\n\t     *   of the promises are rejected the $stateChangeError event is fired. The map object is:\n\t     *\n\t     *   - key - {string}: name of dependency to be injected into controller\n\t     *   - factory - {string|function}: If string then it is alias for service. Otherwise if function,\n\t     *     it is injected and return value it treated as dependency. If result is a promise, it is\n\t     *     resolved before its value is injected into controller.\n\t     *\n\t     * <a id='url'></a>\n\t     *\n\t     * - **`url`** - {string=} - A url with optional parameters. When a state is navigated or\n\t     *   transitioned to, the `$stateParams` service will be populated with any\n\t     *   parameters that were passed.\n\t     *\n\t     * <a id='params'></a>\n\t     *\n\t     * - **`params`** - {object=} - An array of parameter names or regular expressions. Only\n\t     *   use this within a state if you are not using url. Otherwise you can specify your\n\t     *   parameters within the url. When a state is navigated or transitioned to, the\n\t     *   $stateParams service will be populated with any parameters that were passed.\n\t     *\n\t     * <a id='views'></a>\n\t     *\n\t     * - **`views`** - {object=} - Use the views property to set up multiple views or to target views\n\t     *   manually/explicitly.\n\t     *\n\t     * <a id='abstract'></a>\n\t     *\n\t     * - **`abstract`** - {boolean=} - An abstract state will never be directly activated,\n\t     *   but can provide inherited properties to its common children states.\n\t     *\n\t     * <a id='onEnter'></a>\n\t     *\n\t     * - **`onEnter`** - {object=} - Callback function for when a state is entered. Good way\n\t     *   to trigger an action or dispatch an event, such as opening a dialog.\n\t     * If minifying your scripts, make sure to use the `['injection1', 'injection2', function(injection1, injection2){}]` syntax.\n\t     *\n\t     * <a id='onExit'></a>\n\t     *\n\t     * - **`onExit`** - {object=} - Callback function for when a state is exited. Good way to\n\t     *   trigger an action or dispatch an event, such as opening a dialog.\n\t     * If minifying your scripts, make sure to use the `['injection1', 'injection2', function(injection1, injection2){}]` syntax.\n\t     *\n\t     * <a id='reloadOnSearch'></a>\n\t     *\n\t     * - **`reloadOnSearch = true`** - {boolean=} - If `false`, will not retrigger the same state\n\t     *   just because a search/query parameter has changed (via $location.search() or $location.hash()).\n\t     *   Useful for when you'd like to modify $location.search() without triggering a reload.\n\t     *\n\t     * <a id='data'></a>\n\t     *\n\t     * - **`data`** - {object=} - Arbitrary data object, useful for custom configuration.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * // Some state name examples\n\t     *\n\t     * // stateName can be a single top-level name (must be unique).\n\t     * $stateProvider.state(\"home\", {});\n\t     *\n\t     * // Or it can be a nested state name. This state is a child of the\n\t     * // above \"home\" state.\n\t     * $stateProvider.state(\"home.newest\", {});\n\t     *\n\t     * // Nest states as deeply as needed.\n\t     * $stateProvider.state(\"home.newest.abc.xyz.inception\", {});\n\t     *\n\t     * // state() returns $stateProvider, so you can chain state declarations.\n\t     * $stateProvider\n\t     *   .state(\"home\", {})\n\t     *   .state(\"about\", {})\n\t     *   .state(\"contacts\", {});\n\t     * </pre>\n\t     *\n\t     * @param {string} name A unique state name, e.g. \"home\", \"about\", \"contacts\".\n\t     * To create a parent/child state use a dot, e.g. \"about.sales\", \"home.newest\".\n\t     * @param {object} definition State configuration object.\n\t     */\n\t    StateProvider.prototype.state = function (name, definition) {\n\t        if (predicates_1.isObject(name)) {\n\t            definition = name;\n\t        }\n\t        else {\n\t            definition.name = name;\n\t        }\n\t        this.stateRegistry.register(definition);\n\t        return this;\n\t    };\n\t    /**\n\t     * Registers an invalid state handler\n\t     *\n\t     * Registers a function to be injected and invoked when [[StateService.transitionTo]] has been called with an invalid\n\t     * state reference parameter\n\t     *\n\t     * This function can be injected with one some special values:\n\t     * - **`$to$`**: TargetState\n\t     * - **`$from$`**: TargetState\n\t     *\n\t     * Note: This API is subject to change.\n\t     * Replacement of dependency injection support with some alternative is likely.\n\t     *\n\t     * @param {function} callback\n\t     *   The function which will be injected and invoked, when a matching transition is started.\n\t     *   The function may optionally return a {TargetState} or a Promise for a TargetState.  If one\n\t     *   is returned, it is treated as a redirect.\n\t     */\n\t    StateProvider.prototype.onInvalid = function (callback) {\n\t        this.invalidCallbacks.push(callback);\n\t    };\n\t    return StateProvider;\n\t}());\n\texports.StateProvider = StateProvider;\n\n\n/***/ },\n/* 31 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tvar transition_1 = __webpack_require__(11);\n\tvar hookRegistry_1 = __webpack_require__(15);\n\tvar resolve_1 = __webpack_require__(32);\n\tvar views_1 = __webpack_require__(33);\n\tvar url_1 = __webpack_require__(34);\n\tvar redirectTo_1 = __webpack_require__(35);\n\tvar onEnterExitRetain_1 = __webpack_require__(36);\n\tvar hof_1 = __webpack_require__(5);\n\t/**\n\t * The default [[Transition]] options.\n\t *\n\t * Include this object when applying custom defaults:\n\t * let reloadOpts = { reload: true, notify: true }\n\t * let options = defaults(theirOpts, customDefaults, defaultOptions);\n\t */\n\texports.defaultTransOpts = {\n\t    location: true,\n\t    relative: null,\n\t    inherit: false,\n\t    notify: true,\n\t    reload: false,\n\t    custom: {},\n\t    current: function () { return null; }\n\t};\n\t/**\n\t * This class provides services related to Transitions.\n\t *\n\t * - Most importantly, it allows global Transition Hooks to be registered.\n\t * - It allows the default transition error handler to be set.\n\t * - It also has a factory function for creating new [[Transition]] objects, (used internally by the [[StateService]]).\n\t *\n\t * At bootstrap, [[UIRouter]] creates a single instance (singleton) of this class.\n\t */\n\tvar TransitionService = (function () {\n\t    function TransitionService(_router) {\n\t        this._router = _router;\n\t        this.$view = _router.viewService;\n\t        hookRegistry_1.HookRegistry.mixin(new hookRegistry_1.HookRegistry(), this);\n\t        this._deregisterHookFns = {};\n\t        this.registerTransitionHooks();\n\t    }\n\t    /** @hidden */\n\t    TransitionService.prototype.registerTransitionHooks = function () {\n\t        var fns = this._deregisterHookFns;\n\t        // Wire up redirectTo hook\n\t        fns.redirectTo = this.onStart({ to: function (state) { return !!state.redirectTo; } }, redirectTo_1.redirectToHook);\n\t        // Wire up onExit/Retain/Enter state hooks\n\t        fns.onExit = this.onExit({ exiting: function (state) { return !!state.onExit; } }, onEnterExitRetain_1.onExitHook);\n\t        fns.onRetain = this.onRetain({ retained: function (state) { return !!state.onRetain; } }, onEnterExitRetain_1.onRetainHook);\n\t        fns.onEnter = this.onEnter({ entering: function (state) { return !!state.onEnter; } }, onEnterExitRetain_1.onEnterHook);\n\t        // Wire up Resolve hooks\n\t        fns.eagerResolve = this.onStart({}, resolve_1.eagerResolvePath, { priority: 1000 });\n\t        fns.lazyResolve = this.onEnter({ entering: hof_1.val(true) }, resolve_1.lazyResolveState, { priority: 1000 });\n\t        // Wire up the View management hooks\n\t        fns.loadViews = this.onStart({}, views_1.loadEnteringViews);\n\t        fns.activateViews = this.onSuccess({}, views_1.activateViews);\n\t        // After globals.current is updated at priority: 10000\n\t        fns.updateUrl = this.onSuccess({}, url_1.updateUrl, { priority: 9999 });\n\t    };\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onBefore = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onStart = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onExit = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onRetain = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onEnter = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onFinish = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onSuccess = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /** @inheritdoc */\n\t    TransitionService.prototype.onError = function (matchCriteria, callback, options) { throw \"\"; };\n\t    ;\n\t    /**\n\t     * Creates a new [[Transition]] object\n\t     *\n\t     * This is a factory function for creating new Transition objects.\n\t     * It is used internally by the [[StateService]] and should generally not be called by application code.\n\t     *\n\t     * @param fromPath the path to the current state (the from state)\n\t     * @param targetState the target state (destination)\n\t     * @returns a Transition\n\t     */\n\t    TransitionService.prototype.create = function (fromPath, targetState) {\n\t        return new transition_1.Transition(fromPath, targetState, this._router);\n\t    };\n\t    return TransitionService;\n\t}());\n\texports.TransitionService = TransitionService;\n\n\n/***/ },\n/* 32 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module hooks */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar resolveContext_1 = __webpack_require__(17);\n\t/**\n\t * A [[TransitionHookFn]] which resolves all EAGER Resolvables in the To Path\n\t *\n\t * Registered using `transitionService.onStart({}, eagerResolvePath);`\n\t *\n\t * When a Transition starts, this hook resolves all the EAGER Resolvables, which the transition then waits for.\n\t *\n\t * See [[StateDeclaration.resolve]]\n\t */\n\texports.eagerResolvePath = function (trans) {\n\t    return new resolveContext_1.ResolveContext(trans.treeChanges().to)\n\t        .resolvePath(\"EAGER\", trans)\n\t        .then(common_1.noop);\n\t};\n\t/**\n\t * A [[TransitionHookFn]] which resolves all LAZY Resolvables for the state (and all its ancestors) in the To Path\n\t *\n\t * Registered using `transitionService.onEnter({ entering: () => true }, lazyResolveState);`\n\t *\n\t * When a State is being entered, this hook resolves all the Resolvables for this state, which the transition then waits for.\n\t *\n\t * See [[StateDeclaration.resolve]]\n\t */\n\texports.lazyResolveState = function (trans, state) {\n\t    return new resolveContext_1.ResolveContext(trans.treeChanges().to)\n\t        .subContext(state)\n\t        .resolvePath(\"LAZY\", trans)\n\t        .then(common_1.noop);\n\t};\n\n\n/***/ },\n/* 33 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module hooks */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar coreservices_1 = __webpack_require__(6);\n\t/**\n\t * A [[TransitionHookFn]] which waits for the views to load\n\t *\n\t * Registered using `transitionService.onStart({}, loadEnteringViews);`\n\t *\n\t * Allows the views to do async work in [[ViewConfig.load]] before the transition continues.\n\t * In angular 1, this includes loading the templates.\n\t */\n\tfunction loadEnteringViews(transition) {\n\t    var enteringViews = transition.views(\"entering\");\n\t    if (!enteringViews.length)\n\t        return;\n\t    return coreservices_1.services.$q.all(enteringViews.map(function (view) { return view.load(); })).then(common_1.noop);\n\t}\n\texports.loadEnteringViews = loadEnteringViews;\n\t/**\n\t * A [[TransitionHookFn]] which activates the new views when a transition is successful.\n\t *\n\t * Registered using `transitionService.onSuccess({}, activateViews);`\n\t *\n\t * After a transition is complete, this hook deactivates the old views from the previous state,\n\t * and activates the new views from the destination state.\n\t *\n\t * See [[ViewService]]\n\t */\n\tfunction activateViews(transition) {\n\t    var enteringViews = transition.views(\"entering\");\n\t    var exitingViews = transition.views(\"exiting\");\n\t    if (!enteringViews.length && !exitingViews.length)\n\t        return;\n\t    var $view = transition.router.viewService;\n\t    exitingViews.forEach(function (vc) { return $view.deactivateViewConfig(vc); });\n\t    enteringViews.forEach(function (vc) { return $view.activateViewConfig(vc); });\n\t    $view.sync();\n\t}\n\texports.activateViews = activateViews;\n\n\n/***/ },\n/* 34 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t/**\n\t * A [[TransitionHookFn]] which updates the URL after a successful transition\n\t *\n\t * Registered using `transitionService.onSuccess({}, updateUrl);`\n\t */\n\tfunction updateUrl(transition) {\n\t    var options = transition.options();\n\t    var $state = transition.router.stateService;\n\t    var $urlRouter = transition.router.urlRouter;\n\t    if (options.location && $state.$current.navigable) {\n\t        var urlOptions = { replace: options.location === 'replace' };\n\t        $urlRouter.push($state.$current.navigable.url, $state.params, urlOptions);\n\t    }\n\t    $urlRouter.update(true);\n\t}\n\texports.updateUrl = updateUrl;\n\n\n/***/ },\n/* 35 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module hooks */ /** */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar targetState_1 = __webpack_require__(14);\n\t/**\n\t * A [[TransitionHookFn]] that redirects to a different state or params\n\t *\n\t * Registered using `transitionService.onStart({ to: (state) => !!state.redirectTo }, redirectHook);`\n\t *\n\t * See [[StateDeclaration.redirectTo]]\n\t */\n\texports.redirectToHook = function (trans) {\n\t    var redirect = trans.to().redirectTo;\n\t    if (!redirect)\n\t        return;\n\t    function handleResult(result) {\n\t        var $state = trans.router.stateService;\n\t        if (result instanceof targetState_1.TargetState)\n\t            return result;\n\t        if (predicates_1.isString(result))\n\t            return $state.target(result, trans.params(), trans.options());\n\t        if (result['state'] || result['params'])\n\t            return $state.target(result['state'] || trans.to(), result['params'] || trans.params(), trans.options());\n\t    }\n\t    if (predicates_1.isFunction(redirect)) {\n\t        return coreservices_1.services.$q.when(redirect(trans)).then(handleResult);\n\t    }\n\t    return handleResult(redirect);\n\t};\n\n\n/***/ },\n/* 36 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t/**\n\t * A factory which creates an onEnter, onExit or onRetain transition hook function\n\t *\n\t * The returned function invokes the (for instance) state.onEnter hook when the\n\t * state is being entered.\n\t *\n\t * @hidden\n\t */\n\tfunction makeEnterExitRetainHook(hookName) {\n\t    return function (transition, state) {\n\t        return state[hookName](transition, state);\n\t    };\n\t}\n\t/**\n\t * The [[TransitionStateHookFn]] for onExit\n\t *\n\t * When the state is being exited, the state's .onExit function is invoked.\n\t *\n\t * Registered using `transitionService.onExit({ exiting: (state) => !!state.onExit }, onExitHook);`\n\t */\n\texports.onExitHook = makeEnterExitRetainHook('onExit');\n\t/**\n\t * The [[TransitionStateHookFn]] for onRetain\n\t *\n\t * When the state is being exited, the state's .onRetain function is invoked.\n\t *\n\t * Registered using `transitionService.onRetain({ retained: (state) => !!state.onRetain }, onRetainHook);`\n\t */\n\texports.onRetainHook = makeEnterExitRetainHook('onRetain');\n\t/**\n\t * The [[TransitionStateHookFn]] for onEnter\n\t *\n\t * When the state is being exited, the state's .onEnter function is invoked.\n\t *\n\t * Registered using `transitionService.onEnter({ entering: (state) => !!state.onEnter }, onEnterHook);`\n\t */\n\texports.onEnterHook = makeEnterExitRetainHook('onEnter');\n\n\n/***/ },\n/* 37 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module view */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar trace_1 = __webpack_require__(12);\n\tvar match = function (obj1) {\n\t    var keys = [];\n\t    for (var _i = 1; _i < arguments.length; _i++) {\n\t        keys[_i - 1] = arguments[_i];\n\t    }\n\t    return function (obj2) { return keys.reduce(function (memo, key) { return memo && obj1[key] === obj2[key]; }, true); };\n\t};\n\t/**\n\t * The View service\n\t */\n\tvar ViewService = (function () {\n\t    function ViewService() {\n\t        var _this = this;\n\t        this.uiViews = [];\n\t        this.viewConfigs = [];\n\t        this._viewConfigFactories = {};\n\t        this.sync = function () {\n\t            var uiViewsByFqn = _this.uiViews.map(function (uiv) { return [uiv.fqn, uiv]; }).reduce(common_1.applyPairs, {});\n\t            /**\n\t             * Given a ui-view and a ViewConfig, determines if they \"match\".\n\t             *\n\t             * A ui-view has a fully qualified name (fqn) and a context object.  The fqn is built from its overall location in\n\t             * the DOM, describing its nesting relationship to any parent ui-view tags it is nested inside of.\n\t             *\n\t             * A ViewConfig has a target ui-view name and a context anchor.  The ui-view name can be a simple name, or\n\t             * can be a segmented ui-view path, describing a portion of a ui-view fqn.\n\t             *\n\t             * In order for a ui-view to match ViewConfig, ui-view's $type must match the ViewConfig's $type\n\t             *\n\t             * If the ViewConfig's target ui-view name is a simple name (no dots), then a ui-view matches if:\n\t             * - the ui-view's name matches the ViewConfig's target name\n\t             * - the ui-view's context matches the ViewConfig's anchor\n\t             *\n\t             * If the ViewConfig's target ui-view name is a segmented name (with dots), then a ui-view matches if:\n\t             * - There exists a parent ui-view where:\n\t             *    - the parent ui-view's name matches the first segment (index 0) of the ViewConfig's target name\n\t             *    - the parent ui-view's context matches the ViewConfig's anchor\n\t             * - And the remaining segments (index 1..n) of the ViewConfig's target name match the tail of the ui-view's fqn\n\t             *\n\t             * Example:\n\t             *\n\t             * DOM:\n\t             * <div ui-view>                        <!-- created in the root context (name: \"\") -->\n\t             *   <div ui-view=\"foo\">                <!-- created in the context named: \"A\"      -->\n\t             *     <div ui-view>                    <!-- created in the context named: \"A.B\"    -->\n\t             *       <div ui-view=\"bar\">            <!-- created in the context named: \"A.B.C\"  -->\n\t             *       </div>\n\t             *     </div>\n\t             *   </div>\n\t             * </div>\n\t             *\n\t             * uiViews: [\n\t             *  { fqn: \"$default\",                  creationContext: { name: \"\" } },\n\t             *  { fqn: \"$default.foo\",              creationContext: { name: \"A\" } },\n\t             *  { fqn: \"$default.foo.$default\",     creationContext: { name: \"A.B\" } }\n\t             *  { fqn: \"$default.foo.$default.bar\", creationContext: { name: \"A.B.C\" } }\n\t             * ]\n\t             *\n\t             * These four view configs all match the ui-view with the fqn: \"$default.foo.$default.bar\":\n\t             *\n\t             * - ViewConfig1: { uiViewName: \"bar\",                       uiViewContextAnchor: \"A.B.C\" }\n\t             * - ViewConfig2: { uiViewName: \"$default.bar\",              uiViewContextAnchor: \"A.B\" }\n\t             * - ViewConfig3: { uiViewName: \"foo.$default.bar\",          uiViewContextAnchor: \"A\" }\n\t             * - ViewConfig4: { uiViewName: \"$default.foo.$default.bar\", uiViewContextAnchor: \"\" }\n\t             *\n\t             * Using ViewConfig3 as an example, it matches the ui-view with fqn \"$default.foo.$default.bar\" because:\n\t             * - The ViewConfig's segmented target name is: [ \"foo\", \"$default\", \"bar\" ]\n\t             * - There exists a parent ui-view (which has fqn: \"$default.foo\") where:\n\t             *    - the parent ui-view's name \"foo\" matches the first segment \"foo\" of the ViewConfig's target name\n\t             *    - the parent ui-view's context \"A\" matches the ViewConfig's anchor context \"A\"\n\t             * - And the remaining segments [ \"$default\", \"bar\" ].join(\".\"_ of the ViewConfig's target name match\n\t             *   the tail of the ui-view's fqn \"default.bar\"\n\t             */\n\t            var matches = function (uiView) { return function (viewConfig) {\n\t                // Don't supply an ng1 ui-view with an ng2 ViewConfig, etc\n\t                if (uiView.$type !== viewConfig.viewDecl.$type)\n\t                    return false;\n\t                // Split names apart from both viewConfig and uiView into segments\n\t                var vc = viewConfig.viewDecl;\n\t                var vcSegments = vc.$uiViewName.split(\".\");\n\t                var uivSegments = uiView.fqn.split(\".\");\n\t                // Check if the tails of the segment arrays match. ex, these arrays' tails match:\n\t                // vc: [\"foo\", \"bar\"], uiv fqn: [\"$default\", \"foo\", \"bar\"]\n\t                if (!common_1.equals(vcSegments, uivSegments.slice(0 - vcSegments.length)))\n\t                    return false;\n\t                // Now check if the fqn ending at the first segment of the viewConfig matches the context:\n\t                // [\"$default\", \"foo\"].join(\".\") == \"$default.foo\", does the ui-view $default.foo context match?\n\t                var negOffset = (1 - vcSegments.length) || undefined;\n\t                var fqnToFirstSegment = uivSegments.slice(0, negOffset).join(\".\");\n\t                var uiViewContext = uiViewsByFqn[fqnToFirstSegment].creationContext;\n\t                return vc.$uiViewContextAnchor === (uiViewContext && uiViewContext.name);\n\t            }; };\n\t            // Return the number of dots in the fully qualified name\n\t            function uiViewDepth(uiView) {\n\t                return uiView.fqn.split(\".\").length;\n\t            }\n\t            // Return the ViewConfig's context's depth in the context tree.\n\t            function viewConfigDepth(config) {\n\t                var context = config.viewDecl.$context, count = 0;\n\t                while (++count && context.parent)\n\t                    context = context.parent;\n\t                return count;\n\t            }\n\t            // Given a depth function, returns a compare function which can return either ascending or descending order\n\t            var depthCompare = hof_1.curry(function (depthFn, posNeg, left, right) { return posNeg * (depthFn(left) - depthFn(right)); });\n\t            var matchingConfigPair = function (uiView) {\n\t                var matchingConfigs = _this.viewConfigs.filter(matches(uiView));\n\t                if (matchingConfigs.length > 1)\n\t                    matchingConfigs.sort(depthCompare(viewConfigDepth, -1)); // descending\n\t                return [uiView, matchingConfigs[0]];\n\t            };\n\t            var configureUIView = function (_a) {\n\t                var uiView = _a[0], viewConfig = _a[1];\n\t                // If a parent ui-view is reconfigured, it could destroy child ui-views.\n\t                // Before configuring a child ui-view, make sure it's still in the active uiViews array.\n\t                if (_this.uiViews.indexOf(uiView) !== -1)\n\t                    uiView.configUpdated(viewConfig);\n\t            };\n\t            _this.uiViews.sort(depthCompare(uiViewDepth, 1)).map(matchingConfigPair).forEach(configureUIView);\n\t        };\n\t    }\n\t    ViewService.prototype.rootContext = function (context) {\n\t        return this._rootContext = context || this._rootContext;\n\t    };\n\t    ;\n\t    ViewService.prototype.viewConfigFactory = function (viewType, factory) {\n\t        this._viewConfigFactories[viewType] = factory;\n\t    };\n\t    ViewService.prototype.createViewConfig = function (path, decl) {\n\t        var cfgFactory = this._viewConfigFactories[decl.$type];\n\t        if (!cfgFactory)\n\t            throw new Error(\"ViewService: No view config factory registered for type \" + decl.$type);\n\t        var cfgs = cfgFactory(path, decl);\n\t        return predicates_1.isArray(cfgs) ? cfgs : [cfgs];\n\t    };\n\t    /**\n\t     * De-registers a ViewConfig.\n\t     *\n\t     * @param viewConfig The ViewConfig view to deregister.\n\t     */\n\t    ViewService.prototype.deactivateViewConfig = function (viewConfig) {\n\t        trace_1.trace.traceViewServiceEvent(\"<- Removing\", viewConfig);\n\t        common_1.removeFrom(this.viewConfigs, viewConfig);\n\t    };\n\t    ;\n\t    ViewService.prototype.activateViewConfig = function (viewConfig) {\n\t        trace_1.trace.traceViewServiceEvent(\"-> Registering\", viewConfig);\n\t        this.viewConfigs.push(viewConfig);\n\t    };\n\t    ;\n\t    /**\n\t     * Allows a `ui-view` element to register its canonical name with a callback that allows it to\n\t     * be updated with a template, controller, and local variables.\n\t     *\n\t     * @param {String} name The fully-qualified name of the `ui-view` object being registered.\n\t     * @param {Function} configUpdatedCallback A callback that receives updates to the content & configuration\n\t     *                   of the view.\n\t     * @return {Function} Returns a de-registration function used when the view is destroyed.\n\t     */\n\t    ViewService.prototype.registerUIView = function (uiView) {\n\t        trace_1.trace.traceViewServiceUIViewEvent(\"-> Registering\", uiView);\n\t        var uiViews = this.uiViews;\n\t        var fqnMatches = function (uiv) { return uiv.fqn === uiView.fqn; };\n\t        if (uiViews.filter(fqnMatches).length)\n\t            trace_1.trace.traceViewServiceUIViewEvent(\"!!!! duplicate uiView named:\", uiView);\n\t        uiViews.push(uiView);\n\t        this.sync();\n\t        return function () {\n\t            var idx = uiViews.indexOf(uiView);\n\t            if (idx <= 0) {\n\t                trace_1.trace.traceViewServiceUIViewEvent(\"Tried removing non-registered uiView\", uiView);\n\t                return;\n\t            }\n\t            trace_1.trace.traceViewServiceUIViewEvent(\"<- Deregistering\", uiView);\n\t            common_1.removeFrom(uiViews)(uiView);\n\t        };\n\t    };\n\t    ;\n\t    /**\n\t     * Returns the list of views currently available on the page, by fully-qualified name.\n\t     *\n\t     * @return {Array} Returns an array of fully-qualified view names.\n\t     */\n\t    ViewService.prototype.available = function () {\n\t        return this.uiViews.map(hof_1.prop(\"fqn\"));\n\t    };\n\t    /**\n\t     * Returns the list of views on the page containing loaded content.\n\t     *\n\t     * @return {Array} Returns an array of fully-qualified view names.\n\t     */\n\t    ViewService.prototype.active = function () {\n\t        return this.uiViews.filter(hof_1.prop(\"$config\")).map(hof_1.prop(\"name\"));\n\t    };\n\t    /**\n\t     * Normalizes a view's name from a state.views configuration block.\n\t     *\n\t     * @param context the context object (state declaration) that the view belongs to\n\t     * @param rawViewName the name of the view, as declared in the [[StateDeclaration.views]]\n\t     *\n\t     * @returns the normalized uiViewName and uiViewContextAnchor that the view targets\n\t     */\n\t    ViewService.normalizeUIViewTarget = function (context, rawViewName) {\n\t        if (rawViewName === void 0) { rawViewName = \"\"; }\n\t        // TODO: Validate incoming view name with a regexp to allow:\n\t        // ex: \"view.name@foo.bar\" , \"^.^.view.name\" , \"view.name@^.^\" , \"\" ,\n\t        // \"@\" , \"$default@^\" , \"!$default.$default\" , \"!foo.bar\"\n\t        var viewAtContext = rawViewName.split(\"@\");\n\t        var uiViewName = viewAtContext[0] || \"$default\"; // default to unnamed view\n\t        var uiViewContextAnchor = predicates_1.isString(viewAtContext[1]) ? viewAtContext[1] : \"^\"; // default to parent context\n\t        // Handle relative view-name sugar syntax.\n\t        // Matches rawViewName \"^.^.^.foo.bar\" into array: [\"^.^.^.foo.bar\", \"^.^.^\", \"foo.bar\"],\n\t        var relativeViewNameSugar = /^(\\^(?:\\.\\^)*)\\.(.*$)/.exec(uiViewName);\n\t        if (relativeViewNameSugar) {\n\t            // Clobbers existing contextAnchor (rawViewName validation will fix this)\n\t            uiViewContextAnchor = relativeViewNameSugar[1]; // set anchor to \"^.^.^\"\n\t            uiViewName = relativeViewNameSugar[2]; // set view-name to \"foo.bar\"\n\t        }\n\t        if (uiViewName.charAt(0) === '!') {\n\t            uiViewName = uiViewName.substr(1);\n\t            uiViewContextAnchor = \"\"; // target absolutely from root\n\t        }\n\t        // handle parent relative targeting \"^.^.^\"\n\t        var relativeMatch = /^(\\^(?:\\.\\^)*)$/;\n\t        if (relativeMatch.exec(uiViewContextAnchor)) {\n\t            var anchor = uiViewContextAnchor.split(\".\").reduce((function (anchor, x) { return anchor.parent; }), context);\n\t            uiViewContextAnchor = anchor.name;\n\t        }\n\t        return { uiViewName: uiViewName, uiViewContextAnchor: uiViewContextAnchor };\n\t    };\n\t    return ViewService;\n\t}());\n\texports.ViewService = ViewService;\n\n\n/***/ },\n/* 38 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module state */ /** for typedoc */\n\t\"use strict\";\n\tvar stateMatcher_1 = __webpack_require__(39);\n\tvar stateBuilder_1 = __webpack_require__(40);\n\tvar stateQueueManager_1 = __webpack_require__(41);\n\tvar StateRegistry = (function () {\n\t    function StateRegistry(urlMatcherFactory, urlRouterProvider) {\n\t        this.states = {};\n\t        this.matcher = new stateMatcher_1.StateMatcher(this.states);\n\t        this.builder = new stateBuilder_1.StateBuilder(this.matcher, urlMatcherFactory);\n\t        this.stateQueue = new stateQueueManager_1.StateQueueManager(this.states, this.builder, urlRouterProvider);\n\t        var rootStateDef = {\n\t            name: '',\n\t            url: '^',\n\t            views: null,\n\t            params: {\n\t                '#': { value: null, type: 'hash', dynamic: true }\n\t            },\n\t            abstract: true\n\t        };\n\t        var _root = this._root = this.stateQueue.register(rootStateDef);\n\t        _root.navigable = null;\n\t    }\n\t    StateRegistry.prototype.root = function () {\n\t        return this._root;\n\t    };\n\t    StateRegistry.prototype.register = function (stateDefinition) {\n\t        return this.stateQueue.register(stateDefinition);\n\t    };\n\t    StateRegistry.prototype.get = function (stateOrName, base) {\n\t        var _this = this;\n\t        if (arguments.length === 0)\n\t            return Object.keys(this.states).map(function (name) { return _this.states[name].self; });\n\t        var found = this.matcher.find(stateOrName, base);\n\t        return found && found.self || null;\n\t    };\n\t    StateRegistry.prototype.decorator = function (name, func) {\n\t        return this.builder.builder(name, func);\n\t    };\n\t    return StateRegistry;\n\t}());\n\texports.StateRegistry = StateRegistry;\n\n\n/***/ },\n/* 39 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** for typedoc */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar StateMatcher = (function () {\n\t    function StateMatcher(_states) {\n\t        this._states = _states;\n\t    }\n\t    StateMatcher.prototype.isRelative = function (stateName) {\n\t        stateName = stateName || \"\";\n\t        return stateName.indexOf(\".\") === 0 || stateName.indexOf(\"^\") === 0;\n\t    };\n\t    StateMatcher.prototype.find = function (stateOrName, base) {\n\t        if (!stateOrName && stateOrName !== \"\")\n\t            return undefined;\n\t        var isStr = predicates_1.isString(stateOrName);\n\t        var name = isStr ? stateOrName : stateOrName.name;\n\t        if (this.isRelative(name))\n\t            name = this.resolvePath(name, base);\n\t        var state = this._states[name];\n\t        if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) {\n\t            return state;\n\t        }\n\t        return undefined;\n\t    };\n\t    StateMatcher.prototype.resolvePath = function (name, base) {\n\t        if (!base)\n\t            throw new Error(\"No reference point given for path '\" + name + \"'\");\n\t        var baseState = this.find(base);\n\t        var splitName = name.split(\".\"), i = 0, pathLength = splitName.length, current = baseState;\n\t        for (; i < pathLength; i++) {\n\t            if (splitName[i] === \"\" && i === 0) {\n\t                current = baseState;\n\t                continue;\n\t            }\n\t            if (splitName[i] === \"^\") {\n\t                if (!current.parent)\n\t                    throw new Error(\"Path '\" + name + \"' not valid for state '\" + baseState.name + \"'\");\n\t                current = current.parent;\n\t                continue;\n\t            }\n\t            break;\n\t        }\n\t        var relName = splitName.slice(i).join(\".\");\n\t        return current.name + (current.name && relName ? \".\" : \"\") + relName;\n\t    };\n\t    return StateMatcher;\n\t}());\n\texports.StateMatcher = StateMatcher;\n\n\n/***/ },\n/* 40 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar strings_1 = __webpack_require__(9);\n\tvar hof_1 = __webpack_require__(5);\n\tvar param_1 = __webpack_require__(22);\n\tvar resolvable_1 = __webpack_require__(19);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar parseUrl = function (url) {\n\t    if (!predicates_1.isString(url))\n\t        return false;\n\t    var root = url.charAt(0) === '^';\n\t    return { val: root ? url.substring(1) : url, root: root };\n\t};\n\tfunction selfBuilder(state) {\n\t    state.self.$$state = function () { return state; };\n\t    return state.self;\n\t}\n\tfunction dataBuilder(state) {\n\t    if (state.parent && state.parent.data) {\n\t        state.data = state.self.data = common_1.inherit(state.parent.data, state.data);\n\t    }\n\t    return state.data;\n\t}\n\tvar getUrlBuilder = function ($urlMatcherFactoryProvider, root) {\n\t    return function urlBuilder(state) {\n\t        var stateDec = state;\n\t        var parsed = parseUrl(stateDec.url), parent = state.parent;\n\t        var url = !parsed ? stateDec.url : $urlMatcherFactoryProvider.compile(parsed.val, {\n\t            params: state.params || {},\n\t            paramMap: function (paramConfig, isSearch) {\n\t                if (stateDec.reloadOnSearch === false && isSearch)\n\t                    paramConfig = common_1.extend(paramConfig || {}, { dynamic: true });\n\t                return paramConfig;\n\t            }\n\t        });\n\t        if (!url)\n\t            return null;\n\t        if (!$urlMatcherFactoryProvider.isMatcher(url))\n\t            throw new Error(\"Invalid url '\" + url + \"' in state '\" + state + \"'\");\n\t        return (parsed && parsed.root) ? url : ((parent && parent.navigable) || root()).url.append(url);\n\t    };\n\t};\n\tvar getNavigableBuilder = function (isRoot) {\n\t    return function navigableBuilder(state) {\n\t        return !isRoot(state) && state.url ? state : (state.parent ? state.parent.navigable : null);\n\t    };\n\t};\n\tfunction paramsBuilder(state) {\n\t    var makeConfigParam = function (config, id) { return param_1.Param.fromConfig(id, null, config); };\n\t    var urlParams = (state.url && state.url.parameters({ inherit: false })) || [];\n\t    var nonUrlParams = common_1.values(common_1.map(common_1.omit(state.params || {}, urlParams.map(hof_1.prop('id'))), makeConfigParam));\n\t    return urlParams.concat(nonUrlParams).map(function (p) { return [p.id, p]; }).reduce(common_1.applyPairs, {});\n\t}\n\tfunction pathBuilder(state) {\n\t    return state.parent ? state.parent.path.concat(state) : [state];\n\t}\n\tfunction includesBuilder(state) {\n\t    var includes = state.parent ? common_1.extend({}, state.parent.includes) : {};\n\t    includes[state.name] = true;\n\t    return includes;\n\t}\n\t/**\n\t * This is a [[StateBuilder.builder]] function for the `resolve:` block on a [[StateDeclaration]].\n\t *\n\t * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder\n\t * validates the `resolve` property and converts it to a [[Resolvable]] array.\n\t *\n\t * resolve: input value can be:\n\t *\n\t * {\n\t *   // analyzed but not injected\n\t *   myFooResolve: function() { return \"myFooData\"; },\n\t *\n\t *   // function.toString() parsed, \"DependencyName\" dep as string (not min-safe)\n\t *   myBarResolve: function(DependencyName) { return DependencyName.fetchSomethingAsPromise() },\n\t *\n\t *   // Array split; \"DependencyName\" dep as string\n\t *   myBazResolve: [ \"DependencyName\", function(dep) { return dep.fetchSomethingAsPromise() },\n\t *\n\t *   // Array split; DependencyType dep as token (compared using ===)\n\t *   myQuxResolve: [ DependencyType, function(dep) { return dep.fetchSometingAsPromise() },\n\t *\n\t *   // val.$inject used as deps\n\t *   // where:\n\t *   //     corgeResolve.$inject = [\"DependencyName\"];\n\t *   //     function corgeResolve(dep) { dep.fetchSometingAsPromise() }\n\t *   // then \"DependencyName\" dep as string\n\t *   myCorgeResolve: corgeResolve,\n\t *\n\t *  // inject service by name\n\t *  // When a string is found, desugar creating a resolve that injects the named service\n\t *   myGraultResolve: \"SomeService\"\n\t * }\n\t *\n\t * or:\n\t *\n\t * [\n\t *   new Resolvable(\"myFooResolve\", function() { return \"myFooData\" }),\n\t *   new Resolvable(\"myBarResolve\", function(dep) { return dep.fetchSomethingAsPromise() }, [ \"DependencyName\" ]),\n\t *   { provide: \"myBazResolve\", useFactory: function(dep) { dep.fetchSomethingAsPromise() }, deps: [ \"DependencyName\" ] }\n\t * ]\n\t */\n\tfunction resolvablesBuilder(state) {\n\t    /** convert a resolve: {} object to an array of tuples */\n\t    var obj2Tuples = function (obj) { return Object.keys(obj || {}).map(function (token) { return ({ token: token, val: obj[token], deps: undefined }); }); };\n\t    /** fetch DI annotations from a function or ng1-style array */\n\t    var annotate = function (fn) { return fn.$inject || coreservices_1.services.$injector.annotate(fn, coreservices_1.services.$injector.strictDi); };\n\t    /** true if the object has both `token` and `resolveFn`, and is probably a [[ResolveLiteral]] */\n\t    var isResolveLiteral = function (obj) { return !!(obj.token && obj.resolveFn); };\n\t    /** true if the object looks like a provide literal, or a ng2 Provider */\n\t    var isLikeNg2Provider = function (obj) { return !!((obj.provide || obj.token) && (obj.useValue || obj.useFactory || obj.useExisting || obj.useClass)); };\n\t    /** true if the object looks like a tuple from obj2Tuples */\n\t    var isTupleFromObj = function (obj) { return !!(obj && obj.val && (predicates_1.isString(obj.val) || predicates_1.isArray(obj.val) || predicates_1.isFunction(obj.val))); };\n\t    /** extracts the token from a Provider or provide literal */\n\t    var token = function (p) { return p.provide || p.token; };\n\t    /** Given a literal resolve or provider object, returns a Resolvable */\n\t    var literal2Resolvable = hof_1.pattern([\n\t        [hof_1.prop('resolveFn'), function (p) { return new resolvable_1.Resolvable(token(p), p.resolveFn, p.deps, p.policy); }],\n\t        [hof_1.prop('useFactory'), function (p) { return new resolvable_1.Resolvable(token(p), p.useFactory, (p.deps || p.dependencies), p.policy); }],\n\t        [hof_1.prop('useClass'), function (p) { return new resolvable_1.Resolvable(token(p), function () { return new p.useClass(); }, [], p.policy); }],\n\t        [hof_1.prop('useValue'), function (p) { return new resolvable_1.Resolvable(token(p), function () { return p.useValue; }, [], p.policy, p.useValue); }],\n\t        [hof_1.prop('useExisting'), function (p) { return new resolvable_1.Resolvable(token(p), function (x) { return x; }, [p.useExisting], p.policy); }],\n\t    ]);\n\t    var tuple2Resolvable = hof_1.pattern([\n\t        [hof_1.pipe(hof_1.prop(\"val\"), predicates_1.isString), function (tuple) { return new resolvable_1.Resolvable(tuple.token, function (x) { return x; }, [tuple.val], tuple.policy); }],\n\t        [hof_1.pipe(hof_1.prop(\"val\"), predicates_1.isArray), function (tuple) { return new resolvable_1.Resolvable(tuple.token, common_1.tail(tuple.val), tuple.val.slice(0, -1), tuple.policy); }],\n\t        [hof_1.pipe(hof_1.prop(\"val\"), predicates_1.isFunction), function (tuple) { return new resolvable_1.Resolvable(tuple.token, tuple.val, annotate(tuple.val), tuple.policy); }],\n\t    ]);\n\t    var item2Resolvable = hof_1.pattern([\n\t        [hof_1.is(resolvable_1.Resolvable), function (r) { return r; }],\n\t        [isResolveLiteral, literal2Resolvable],\n\t        [isLikeNg2Provider, literal2Resolvable],\n\t        [isTupleFromObj, tuple2Resolvable],\n\t        [hof_1.val(true), function (tuple) { throw new Error(\"Invalid resolve value: \" + strings_1.stringify(tuple)); }]\n\t    ]);\n\t    // If resolveBlock is already an array, use it as-is.\n\t    // Otherwise, assume it's an object and convert to an Array of tuples\n\t    var decl = state.resolve;\n\t    var items = predicates_1.isArray(decl) ? decl : obj2Tuples(decl);\n\t    return items.map(item2Resolvable);\n\t}\n\texports.resolvablesBuilder = resolvablesBuilder;\n\t/**\n\t * @internalapi A internal global service\n\t *\n\t * StateBuilder is a factory for the internal [[State]] objects.\n\t *\n\t * When you register a state with the [[StateRegistry]], you register a plain old javascript object which\n\t * conforms to the [[StateDeclaration]] interface.  This factory takes that object and builds the corresponding\n\t * [[State]] object, which has an API and is used internally.\n\t *\n\t * Custom properties or API may be added to the internal [[State]] object by registering a decorator function\n\t * using the [[builder]] method.\n\t */\n\tvar StateBuilder = (function () {\n\t    function StateBuilder(matcher, $urlMatcherFactoryProvider) {\n\t        this.matcher = matcher;\n\t        var self = this;\n\t        var root = function () { return matcher.find(\"\"); };\n\t        var isRoot = function (state) { return state.name === \"\"; };\n\t        function parentBuilder(state) {\n\t            if (isRoot(state))\n\t                return null;\n\t            return matcher.find(self.parentName(state)) || root();\n\t        }\n\t        this.builders = {\n\t            self: [selfBuilder],\n\t            parent: [parentBuilder],\n\t            data: [dataBuilder],\n\t            // Build a URLMatcher if necessary, either via a relative or absolute URL\n\t            url: [getUrlBuilder($urlMatcherFactoryProvider, root)],\n\t            // Keep track of the closest ancestor state that has a URL (i.e. is navigable)\n\t            navigable: [getNavigableBuilder(isRoot)],\n\t            params: [paramsBuilder],\n\t            // Each framework-specific ui-router implementation should define its own `views` builder\n\t            // e.g., src/ng1/statebuilders/views.ts\n\t            views: [],\n\t            // Keep a full path from the root down to this state as this is needed for state activation.\n\t            path: [pathBuilder],\n\t            // Speed up $state.includes() as it's used a lot\n\t            includes: [includesBuilder],\n\t            resolvables: [resolvablesBuilder]\n\t        };\n\t    }\n\t    /**\n\t     * Registers a [[BuilderFunction]] for a specific [[State]] property (e.g., `parent`, `url`, or `path`).\n\t     * More than one BuilderFunction can be registered for a given property.\n\t     *\n\t     * The BuilderFunction(s) will be used to define the property on any subsequently built [[State]] objects.\n\t     *\n\t     * @param name The name of the State property being registered for.\n\t     * @param fn The BuilderFunction which will be used to build the State property\n\t     * @returns a function which deregisters the BuilderFunction\n\t     */\n\t    StateBuilder.prototype.builder = function (name, fn) {\n\t        var builders = this.builders;\n\t        var array = builders[name] || [];\n\t        // Backwards compat: if only one builder exists, return it, else return whole arary.\n\t        if (predicates_1.isString(name) && !predicates_1.isDefined(fn))\n\t            return array.length > 1 ? array : array[0];\n\t        if (!predicates_1.isString(name) || !predicates_1.isFunction(fn))\n\t            return;\n\t        builders[name] = array;\n\t        builders[name].push(fn);\n\t        return function () { return builders[name].splice(builders[name].indexOf(fn, 1)) && null; };\n\t    };\n\t    /**\n\t     * Builds all of the properties on an essentially blank State object, returning a State object which has all its\n\t     * properties and API built.\n\t     *\n\t     * @param state an uninitialized State object\n\t     * @returns the built State object\n\t     */\n\t    StateBuilder.prototype.build = function (state) {\n\t        var _a = this, matcher = _a.matcher, builders = _a.builders;\n\t        var parent = this.parentName(state);\n\t        if (parent && !matcher.find(parent))\n\t            return null;\n\t        for (var key in builders) {\n\t            if (!builders.hasOwnProperty(key))\n\t                continue;\n\t            var chain = builders[key].reduce(function (parentFn, step) { return function (_state) { return step(_state, parentFn); }; }, common_1.noop);\n\t            state[key] = chain(state);\n\t        }\n\t        return state;\n\t    };\n\t    StateBuilder.prototype.parentName = function (state) {\n\t        var name = state.name || \"\";\n\t        if (name.indexOf('.') !== -1)\n\t            return name.substring(0, name.lastIndexOf('.'));\n\t        if (!state.parent)\n\t            return \"\";\n\t        return predicates_1.isString(state.parent) ? state.parent : state.parent.name;\n\t    };\n\t    StateBuilder.prototype.name = function (state) {\n\t        var name = state.name;\n\t        if (name.indexOf('.') !== -1 || !state.parent)\n\t            return name;\n\t        var parentName = predicates_1.isString(state.parent) ? state.parent : state.parent.name;\n\t        return parentName ? parentName + \".\" + name : name;\n\t    };\n\t    return StateBuilder;\n\t}());\n\texports.StateBuilder = StateBuilder;\n\n\n/***/ },\n/* 41 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar stateObject_1 = __webpack_require__(42);\n\tvar StateQueueManager = (function () {\n\t    function StateQueueManager(states, builder, $urlRouterProvider) {\n\t        this.states = states;\n\t        this.builder = builder;\n\t        this.$urlRouterProvider = $urlRouterProvider;\n\t        this.queue = [];\n\t    }\n\t    StateQueueManager.prototype.register = function (config) {\n\t        var _a = this, states = _a.states, queue = _a.queue, $state = _a.$state;\n\t        // Wrap a new object around the state so we can store our private details easily.\n\t        // @TODO: state = new State(extend({}, config, { ... }))\n\t        var state = common_1.inherit(new stateObject_1.State(), common_1.extend({}, config, {\n\t            self: config,\n\t            resolve: config.resolve || [],\n\t            toString: function () { return config.name; }\n\t        }));\n\t        if (!predicates_1.isString(state.name))\n\t            throw new Error(\"State must have a valid name\");\n\t        if (states.hasOwnProperty(state.name) || common_1.pluck(queue, 'name').indexOf(state.name) !== -1)\n\t            throw new Error(\"State '\" + state.name + \"' is already defined\");\n\t        queue.push(state);\n\t        if (this.$state) {\n\t            this.flush($state);\n\t        }\n\t        return state;\n\t    };\n\t    StateQueueManager.prototype.flush = function ($state) {\n\t        var _a = this, queue = _a.queue, states = _a.states, builder = _a.builder;\n\t        var result, state, orphans = [], orphanIdx, previousQueueLength = {};\n\t        while (queue.length > 0) {\n\t            state = queue.shift();\n\t            result = builder.build(state);\n\t            orphanIdx = orphans.indexOf(state);\n\t            if (result) {\n\t                if (states.hasOwnProperty(state.name))\n\t                    throw new Error(\"State '\" + name + \"' is already defined\");\n\t                states[state.name] = state;\n\t                this.attachRoute($state, state);\n\t                if (orphanIdx >= 0)\n\t                    orphans.splice(orphanIdx, 1);\n\t                continue;\n\t            }\n\t            var prev = previousQueueLength[state.name];\n\t            previousQueueLength[state.name] = queue.length;\n\t            if (orphanIdx >= 0 && prev === queue.length) {\n\t                // Wait until two consecutive iterations where no additional states were dequeued successfully.\n\t                // throw new Error(`Cannot register orphaned state '${state.name}'`);\n\t                return states;\n\t            }\n\t            else if (orphanIdx < 0) {\n\t                orphans.push(state);\n\t            }\n\t            queue.push(state);\n\t        }\n\t        return states;\n\t    };\n\t    StateQueueManager.prototype.autoFlush = function ($state) {\n\t        this.$state = $state;\n\t        this.flush($state);\n\t    };\n\t    StateQueueManager.prototype.attachRoute = function ($state, state) {\n\t        var $urlRouterProvider = this.$urlRouterProvider;\n\t        if (state[common_1.abstractKey] || !state.url)\n\t            return;\n\t        $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {\n\t                if ($state.$current.navigable !== state || !common_1.equalForKeys($match, $stateParams)) {\n\t                    $state.transitionTo(state, $match, { inherit: true, location: false });\n\t                }\n\t            }]);\n\t    };\n\t    return StateQueueManager;\n\t}());\n\texports.StateQueueManager = StateQueueManager;\n\n\n/***/ },\n/* 42 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module state */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\t/**\n\t * @ngdoc object\n\t * @name ui.router.state.type:State\n\t *\n\t * @description\n\t * Definition object for states. Includes methods for manipulating the state heirarchy.\n\t *\n\t * @param {Object} config  A configuration object hash that includes the results of user-supplied\n\t *        values, as well as values from `StateBuilder`.\n\t *\n\t * @returns {Object}  Returns a new `State` object.\n\t */\n\tvar State = (function () {\n\t    function State(config) {\n\t        common_1.extend(this, config);\n\t        // Object.freeze(this);\n\t    }\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.type:State#is\n\t     * @methodOf ui.router.state.type:State\n\t     *\n\t     * @description\n\t     * Compares the identity of the state against the passed value, which is either an object\n\t     * reference to the actual `State` instance, the original definition object passed to\n\t     * `$stateProvider.state()`, or the fully-qualified name.\n\t     *\n\t     * @param {Object} ref Can be one of (a) a `State` instance, (b) an object that was passed\n\t     *        into `$stateProvider.state()`, (c) the fully-qualified name of a state as a string.\n\t     * @returns {boolean} Returns `true` if `ref` matches the current `State` instance.\n\t     */\n\t    State.prototype.is = function (ref) {\n\t        return this === ref || this.self === ref || this.fqn() === ref;\n\t    };\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.type:State#fqn\n\t     * @methodOf ui.router.state.type:State\n\t     *\n\t     * @description\n\t     * Returns the fully-qualified name of the state, based on its current position in the tree.\n\t     *\n\t     * @returns {string} Returns a dot-separated name of the state.\n\t     */\n\t    State.prototype.fqn = function () {\n\t        if (!this.parent || !(this.parent instanceof this.constructor))\n\t            return this.name;\n\t        var name = this.parent.fqn();\n\t        return name ? name + \".\" + this.name : this.name;\n\t    };\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.type:State#root\n\t     * @methodOf ui.router.state.type:State\n\t     *\n\t     * @description\n\t     * Returns the root node of this state's tree.\n\t     *\n\t     * @returns {State} The root of this state's tree.\n\t     */\n\t    State.prototype.root = function () {\n\t        return this.parent && this.parent.root() || this;\n\t    };\n\t    State.prototype.parameters = function (opts) {\n\t        opts = common_1.defaults(opts, { inherit: true });\n\t        var inherited = opts.inherit && this.parent && this.parent.parameters() || [];\n\t        return inherited.concat(common_1.values(this.params));\n\t    };\n\t    State.prototype.parameter = function (id, opts) {\n\t        if (opts === void 0) { opts = {}; }\n\t        return (this.url && this.url.parameter(id, opts) ||\n\t            common_1.find(common_1.values(this.params), hof_1.propEq('id', id)) ||\n\t            opts.inherit && this.parent && this.parent.parameter(id));\n\t    };\n\t    State.prototype.toString = function () {\n\t        return this.fqn();\n\t    };\n\t    return State;\n\t}());\n\texports.State = State;\n\n\n/***/ },\n/* 43 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module state */ /** */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar queue_1 = __webpack_require__(8);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar pathFactory_1 = __webpack_require__(20);\n\tvar node_1 = __webpack_require__(21);\n\tvar transitionService_1 = __webpack_require__(31);\n\tvar rejectFactory_1 = __webpack_require__(10);\n\tvar targetState_1 = __webpack_require__(14);\n\tvar param_1 = __webpack_require__(22);\n\tvar glob_1 = __webpack_require__(7);\n\tvar common_2 = __webpack_require__(3);\n\tvar common_3 = __webpack_require__(3);\n\tvar StateService = (function () {\n\t    /** @hidden */\n\t    function StateService(router) {\n\t        this.router = router;\n\t        /** @hidden */\n\t        this._defaultErrorHandler = function $defaultErrorHandler($error$) {\n\t            if ($error$ instanceof Error && $error$.stack) {\n\t                console.error($error$.stack);\n\t            }\n\t            else if ($error$ instanceof rejectFactory_1.Rejection) {\n\t                console.error($error$);\n\t                if ($error$.detail && $error$.detail.stack)\n\t                    console.error($error$.detail.stack);\n\t            }\n\t            else {\n\t                console.error($error$);\n\t            }\n\t        };\n\t        var getters = ['current', '$current', 'params', 'transition'];\n\t        var boundFns = Object.keys(StateService.prototype).filter(function (key) { return getters.indexOf(key) === -1; });\n\t        common_3.bindFunctions(StateService.prototype, this, this, boundFns);\n\t    }\n\t    Object.defineProperty(StateService.prototype, \"transition\", {\n\t        get: function () { return this.router.globals.transition; },\n\t        enumerable: true,\n\t        configurable: true\n\t    });\n\t    Object.defineProperty(StateService.prototype, \"params\", {\n\t        get: function () { return this.router.globals.params; },\n\t        enumerable: true,\n\t        configurable: true\n\t    });\n\t    Object.defineProperty(StateService.prototype, \"current\", {\n\t        get: function () { return this.router.globals.current; },\n\t        enumerable: true,\n\t        configurable: true\n\t    });\n\t    Object.defineProperty(StateService.prototype, \"$current\", {\n\t        get: function () { return this.router.globals.$current; },\n\t        enumerable: true,\n\t        configurable: true\n\t    });\n\t    /**\n\t     * Handler for when [[transitionTo]] is called with an invalid state.\n\t     *\n\t     * Invokes the [[onInvalid]] callbacks, in natural order.\n\t     * Each callback's return value is checked in sequence until one of them returns an instance of TargetState.\n\t     * The results of the callbacks are wrapped in $q.when(), so the callbacks may return promises.\n\t     *\n\t     * If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and the result returned.\n\t     */\n\t    StateService.prototype._handleInvalidTargetState = function (fromPath, $to$) {\n\t        var _this = this;\n\t        var globals = this.router.globals;\n\t        var latestThing = function () { return globals.transitionHistory.peekTail(); };\n\t        var latest = latestThing();\n\t        var $from$ = pathFactory_1.PathFactory.makeTargetState(fromPath);\n\t        var callbackQueue = new queue_1.Queue([].concat(this.router.stateProvider.invalidCallbacks));\n\t        var $q = coreservices_1.services.$q, $injector = coreservices_1.services.$injector;\n\t        var invokeCallback = function (callback) { return $q.when($injector.invoke(callback, null, { $to$: $to$, $from$: $from$ })); };\n\t        var checkForRedirect = function (result) {\n\t            if (!(result instanceof targetState_1.TargetState)) {\n\t                return;\n\t            }\n\t            var target = result;\n\t            // Recreate the TargetState, in case the state is now defined.\n\t            target = _this.target(target.identifier(), target.params(), target.options());\n\t            if (!target.valid())\n\t                return rejectFactory_1.Rejection.invalid(target.error()).toPromise();\n\t            if (latestThing() !== latest)\n\t                return rejectFactory_1.Rejection.superseded().toPromise();\n\t            return _this.transitionTo(target.identifier(), target.params(), target.options());\n\t        };\n\t        function invokeNextCallback() {\n\t            var nextCallback = callbackQueue.dequeue();\n\t            if (nextCallback === undefined)\n\t                return rejectFactory_1.Rejection.invalid($to$.error()).toPromise();\n\t            return invokeCallback(nextCallback).then(checkForRedirect).then(function (result) { return result || invokeNextCallback(); });\n\t        }\n\t        return invokeNextCallback();\n\t    };\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#reload\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * A method that force reloads the current state, or a partial state hierarchy. All resolves are re-resolved,\n\t     * controllers reinstantiated, and events re-fired.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * let app angular.module('app', ['ui.router']);\n\t     *\n\t     * app.controller('ctrl', function ($scope, $state) {\n\t     *   $scope.reload = function(){\n\t     *     $state.reload();\n\t     *   }\n\t     * });\n\t     * </pre>\n\t     *\n\t     * `reload()` is just an alias for:\n\t     * <pre>\n\t     * $state.transitionTo($state.current, $stateParams, {\n\t     *   reload: true, inherit: false, notify: true\n\t     * });\n\t     * </pre>\n\t     *\n\t     * @param {string=|object=} reloadState - A state name or a state object, which is the root of the resolves to be re-resolved.\n\t     * @example\n\t     * <pre>\n\t     * //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item'\n\t     * //and current state is 'contacts.detail.item'\n\t     * let app angular.module('app', ['ui.router']);\n\t     *\n\t     * app.controller('ctrl', function ($scope, $state) {\n\t     *   $scope.reload = function(){\n\t     *     //will reload 'contact.detail' and nested 'contact.detail.item' states\n\t     *     $state.reload('contact.detail');\n\t     *   }\n\t     * });\n\t     * </pre>\n\t     *\n\t     * @returns {promise} A promise representing the state of the new transition. See\n\t     * {@link ui.router.state.$state#methods_go $state.go}.\n\t     */\n\t    StateService.prototype.reload = function (reloadState) {\n\t        return this.transitionTo(this.current, this.params, {\n\t            reload: predicates_1.isDefined(reloadState) ? reloadState : true,\n\t            inherit: false,\n\t            notify: false\n\t        });\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#go\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * Convenience method for transitioning to a new state. `$state.go` calls\n\t     * `$state.transitionTo` internally but automatically sets options to\n\t     * `{ location: true, inherit: true, relative: $state.$current, notify: true }`.\n\t     * This allows you to easily use an absolute or relative to path and specify\n\t     * only the parameters you'd like to update (while letting unspecified parameters\n\t     * inherit from the currently active ancestor states).\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * let app = angular.module('app', ['ui.router']);\n\t     *\n\t     * app.controller('ctrl', function ($scope, $state) {\n\t     *   $scope.changeState = function () {\n\t     *     $state.go('contact.detail');\n\t     *   };\n\t     * });\n\t     * </pre>\n\t     * <img src='../ngdoc_assets/StateGoExamples.png'/>\n\t     *\n\t     * @param {string} to Absolute state name or relative state path. Some examples:\n\t     *\n\t     * - `$state.go('contact.detail')` - will go to the `contact.detail` state\n\t     * - `$state.go('^')` - will go to a parent state\n\t     * - `$state.go('^.sibling')` - will go to a sibling state\n\t     * - `$state.go('.child.grandchild')` - will go to grandchild state\n\t     *\n\t     * @param {object=} params A map of the parameters that will be sent to the state,\n\t     * will populate $stateParams. Any parameters that are not specified will be inherited from currently\n\t     * defined parameters. This allows, for example, going to a sibling state that shares parameters\n\t     * specified in a parent state. Parameter inheritance only works between common ancestor states, I.e.\n\t     * transitioning to a sibling will get you the parameters for all parents, transitioning to a child\n\t     * will get you all current parameters, etc.\n\t     * @param {object=} options Options object. The options are:\n\t     *\n\t     * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`\n\t     *    will not. If string, must be `\"replace\"`, which will update url and also replace last history record.\n\t     * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.\n\t     * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),\n\t     *    defines which state to be relative from.\n\t     * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.\n\t     * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params\n\t     *    have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd\n\t     *    use this when you want to force a reload when *everything* is the same, including search params.\n\t     *\n\t     * @returns {promise} A promise representing the state of the new transition.\n\t     *\n\t     * Possible success values:\n\t     *\n\t     * - $state.current\n\t     *\n\t     * <br/>Possible rejection values:\n\t     *\n\t     * - 'transition superseded' - when a newer transition has been started after this one\n\t     * - 'transition prevented' - when `event.preventDefault()` has been called in a `$stateChangeStart` listener\n\t     * - 'transition aborted' - when `event.preventDefault()` has been called in a `$stateNotFound` listener or\n\t     *   when a `$stateNotFound` `event.retry` promise errors.\n\t     * - 'transition failed' - when a state has been unsuccessfully found after 2 tries.\n\t     * - *resolve error* - when an error has occurred with a `resolve`\n\t     *\n\t     */\n\t    StateService.prototype.go = function (to, params, options) {\n\t        var defautGoOpts = { relative: this.$current, inherit: true };\n\t        var transOpts = common_1.defaults(options, defautGoOpts, transitionService_1.defaultTransOpts);\n\t        return this.transitionTo(to, params, transOpts);\n\t    };\n\t    ;\n\t    /** Factory method for creating a TargetState */\n\t    StateService.prototype.target = function (identifier, params, options) {\n\t        if (options === void 0) { options = {}; }\n\t        // If we're reloading, find the state object to reload from\n\t        if (predicates_1.isObject(options.reload) && !options.reload.name)\n\t            throw new Error('Invalid reload state object');\n\t        var reg = this.router.stateRegistry;\n\t        options.reloadState = options.reload === true ? reg.root() : reg.matcher.find(options.reload, options.relative);\n\t        if (options.reload && !options.reloadState)\n\t            throw new Error(\"No such reload state '\" + (predicates_1.isString(options.reload) ? options.reload : options.reload.name) + \"'\");\n\t        var stateDefinition = reg.matcher.find(identifier, options.relative);\n\t        return new targetState_1.TargetState(identifier, stateDefinition, params, options);\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#transitionTo\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * Low-level method for transitioning to a new state. {@link ui.router.state.$state#methods_go $state.go}\n\t     * uses `transitionTo` internally. `$state.go` is recommended in most situations.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * let app = angular.module('app', ['ui.router']);\n\t     *\n\t     * app.controller('ctrl', function ($scope, $state) {\n\t     *   $scope.changeState = function () {\n\t     *     $state.transitionTo('contact.detail');\n\t     *   };\n\t     * });\n\t     * </pre>\n\t     *\n\t     * @param {string} to State name.\n\t     * @param {object=} toParams A map of the parameters that will be sent to the state,\n\t     * will populate $stateParams.\n\t     * @param {object=} options Options object. The options are:\n\t     *\n\t     * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`\n\t     *    will not. If string, must be `\"replace\"`, which will update url and also replace last history record.\n\t     * - **`inherit`** - {boolean=false}, If `true` will inherit url parameters from current url.\n\t     * - **`relative`** - {object=}, When transitioning with relative path (e.g '^'),\n\t     *    defines which state to be relative from.\n\t     * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.\n\t     * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params\n\t     *    have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd\n\t     *    use this when you want to force a reload when *everything* is the same, including search params.\n\t     *\n\t     * @returns {promise} A promise representing the state of the new transition. See\n\t     * {@link ui.router.state.$state#methods_go $state.go}.\n\t     */\n\t    StateService.prototype.transitionTo = function (to, toParams, options) {\n\t        var _this = this;\n\t        if (toParams === void 0) { toParams = {}; }\n\t        if (options === void 0) { options = {}; }\n\t        var router = this.router;\n\t        var globals = router.globals;\n\t        var transHistory = globals.transitionHistory;\n\t        options = common_1.defaults(options, transitionService_1.defaultTransOpts);\n\t        options = common_1.extend(options, { current: transHistory.peekTail.bind(transHistory) });\n\t        var ref = this.target(to, toParams, options);\n\t        var latestSuccess = globals.successfulTransitions.peekTail();\n\t        var rootPath = function () { return [new node_1.PathNode(_this.router.stateRegistry.root())]; };\n\t        var currentPath = latestSuccess ? latestSuccess.treeChanges().to : rootPath();\n\t        if (!ref.exists())\n\t            return this._handleInvalidTargetState(currentPath, ref);\n\t        if (!ref.valid())\n\t            return common_1.silentRejection(ref.error());\n\t        /**\n\t         * Special handling for Ignored, Aborted, and Redirected transitions\n\t         *\n\t         * The semantics for the transition.run() promise and the StateService.transitionTo()\n\t         * promise differ. For instance, the run() promise may be rejected because it was\n\t         * IGNORED, but the transitionTo() promise is resolved because from the user perspective\n\t         * no error occurred.  Likewise, the transition.run() promise may be rejected because of\n\t         * a Redirect, but the transitionTo() promise is chained to the new Transition's promise.\n\t         */\n\t        var rejectedTransitionHandler = function (transition) { return function (error) {\n\t            if (error instanceof rejectFactory_1.Rejection) {\n\t                if (error.type === rejectFactory_1.RejectType.IGNORED) {\n\t                    router.urlRouter.update();\n\t                    return globals.current;\n\t                }\n\t                if (error.type === rejectFactory_1.RejectType.SUPERSEDED && error.redirected && error.detail instanceof targetState_1.TargetState) {\n\t                    var redirect = transition.redirect(error.detail);\n\t                    return redirect.run().catch(rejectedTransitionHandler(redirect));\n\t                }\n\t                if (error.type === rejectFactory_1.RejectType.ABORTED) {\n\t                    router.urlRouter.update();\n\t                    return coreservices_1.services.$q.reject(error);\n\t                }\n\t            }\n\t            var errorHandler = _this.defaultErrorHandler();\n\t            errorHandler(error);\n\t            return coreservices_1.services.$q.reject(error);\n\t        }; };\n\t        var transition = this.router.transitionService.create(currentPath, ref);\n\t        var transitionToPromise = transition.run().catch(rejectedTransitionHandler(transition));\n\t        common_1.silenceUncaughtInPromise(transitionToPromise); // issue #2676\n\t        // Return a promise for the transition, which also has the transition object on it.\n\t        return common_1.extend(transitionToPromise, { transition: transition });\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#is\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * Similar to {@link ui.router.state.$state#methods_includes $state.includes},\n\t     * but only checks for the full state name. If params is supplied then it will be\n\t     * tested for strict equality against the current active params object, so all params\n\t     * must match with none missing and no extras.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * $state.$current.name = 'contacts.details.item';\n\t     *\n\t     * // absolute name\n\t     * $state.is('contact.details.item'); // returns true\n\t     * $state.is(contactDetailItemStateObject); // returns true\n\t     *\n\t     * // relative name (. and ^), typically from a template\n\t     * // E.g. from the 'contacts.details' template\n\t     * <div ng-class=\"{highlighted: $state.is('.item')}\">Item</div>\n\t     * </pre>\n\t     *\n\t     * @param {string|object} stateOrName The state name (absolute or relative) or state object you'd like to check.\n\t     * @param {object=} params A param object, e.g. `{sectionId: section.id}`, that you'd like\n\t     * to test against the current active state.\n\t     * @param {object=} options An options object.  The options are:\n\t     *\n\t     * - **`relative`** - {string|object} -  If `stateOrName` is a relative state name and `options.relative` is set, .is will\n\t     * test relative to `options.relative` state (or name).\n\t     *\n\t     * @returns {boolean} Returns true if it is the state.\n\t     */\n\t    StateService.prototype.is = function (stateOrName, params, options) {\n\t        options = common_1.defaults(options, { relative: this.$current });\n\t        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative);\n\t        if (!predicates_1.isDefined(state))\n\t            return undefined;\n\t        if (this.$current !== state)\n\t            return false;\n\t        return predicates_1.isDefined(params) && params !== null ? param_1.Param.equals(state.parameters(), this.params, params) : true;\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#includes\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * A method to determine if the current active state is equal to or is the child of the\n\t     * state stateName. If any params are passed then they will be tested for a match as well.\n\t     * Not all the parameters need to be passed, just the ones you'd like to test for equality.\n\t     *\n\t     * @example\n\t     * Partial and relative names\n\t     * <pre>\n\t     * $state.$current.name = 'contacts.details.item';\n\t     *\n\t     * // Using partial names\n\t     * $state.includes(\"contacts\"); // returns true\n\t     * $state.includes(\"contacts.details\"); // returns true\n\t     * $state.includes(\"contacts.details.item\"); // returns true\n\t     * $state.includes(\"contacts.list\"); // returns false\n\t     * $state.includes(\"about\"); // returns false\n\t     *\n\t     * // Using relative names (. and ^), typically from a template\n\t     * // E.g. from the 'contacts.details' template\n\t     * <div ng-class=\"{highlighted: $state.includes('.item')}\">Item</div>\n\t     * </pre>\n\t     *\n\t     * Basic globbing patterns\n\t     * <pre>\n\t     * $state.$current.name = 'contacts.details.item.url';\n\t     *\n\t     * $state.includes(\"*.details.*.*\"); // returns true\n\t     * $state.includes(\"*.details.**\"); // returns true\n\t     * $state.includes(\"**.item.**\"); // returns true\n\t     * $state.includes(\"*.details.item.url\"); // returns true\n\t     * $state.includes(\"*.details.*.url\"); // returns true\n\t     * $state.includes(\"*.details.*\"); // returns false\n\t     * $state.includes(\"item.**\"); // returns false\n\t     * </pre>\n\t     *\n\t     * @param {string} stateOrName A partial name, relative name, or glob pattern\n\t     * to be searched for within the current state name.\n\t     * @param {object=} params A param object, e.g. `{sectionId: section.id}`,\n\t     * that you'd like to test against the current active state.\n\t     * @param {object=} options An options object.  The options are:\n\t     *\n\t     * - **`relative`** - {string|object=} -  If `stateOrName` is a relative state reference and `options.relative` is set,\n\t     * .includes will test relative to `options.relative` state (or name).\n\t     *\n\t     * @returns {boolean} Returns true if it does include the state\n\t     */\n\t    StateService.prototype.includes = function (stateOrName, params, options) {\n\t        options = common_1.defaults(options, { relative: this.$current });\n\t        var glob = predicates_1.isString(stateOrName) && glob_1.Glob.fromString(stateOrName);\n\t        if (glob) {\n\t            if (!glob.matches(this.$current.name))\n\t                return false;\n\t            stateOrName = this.$current.name;\n\t        }\n\t        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative), include = this.$current.includes;\n\t        if (!predicates_1.isDefined(state))\n\t            return undefined;\n\t        if (!predicates_1.isDefined(include[state.name]))\n\t            return false;\n\t        // @TODO Replace with Param.equals() ?\n\t        return params ? common_2.equalForKeys(param_1.Param.values(state.parameters(), params), this.params, Object.keys(params)) : true;\n\t    };\n\t    ;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$state#href\n\t     * @methodOf ui.router.state.$state\n\t     *\n\t     * @description\n\t     * A url generation method that returns the compiled url for the given state populated with the given params.\n\t     *\n\t     * @example\n\t     * <pre>\n\t     * expect($state.href(\"about.person\", { person: \"bob\" })).toEqual(\"/about/bob\");\n\t     * </pre>\n\t     *\n\t     * @param {string|object} stateOrName The state name or state object you'd like to generate a url from.\n\t     * @param {object=} params An object of parameter values to fill the state's required parameters.\n\t     * @param {object=} options Options object. The options are:\n\t     *\n\t     * - **`lossy`** - {boolean=true} -  If true, and if there is no url associated with the state provided in the\n\t     *    first parameter, then the constructed href url will be built from the first navigable ancestor (aka\n\t     *    ancestor with a valid url).\n\t     * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.\n\t     * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),\n\t     *    defines which state to be relative from.\n\t     * - **`absolute`** - {boolean=false},  If true will generate an absolute url, e.g. \"http://www.example.com/fullurl\".\n\t     *\n\t     * @returns {string} compiled state url\n\t     */\n\t    StateService.prototype.href = function (stateOrName, params, options) {\n\t        var defaultHrefOpts = {\n\t            lossy: true,\n\t            inherit: true,\n\t            absolute: false,\n\t            relative: this.$current\n\t        };\n\t        options = common_1.defaults(options, defaultHrefOpts);\n\t        var state = this.router.stateRegistry.matcher.find(stateOrName, options.relative);\n\t        if (!predicates_1.isDefined(state))\n\t            return null;\n\t        if (options.inherit)\n\t            params = this.params.$inherit(params || {}, this.$current, state);\n\t        var nav = (state && options.lossy) ? state.navigable : state;\n\t        if (!nav || nav.url === undefined || nav.url === null) {\n\t            return null;\n\t        }\n\t        return this.router.urlRouter.href(nav.url, param_1.Param.values(state.parameters(), params), {\n\t            absolute: options.absolute\n\t        });\n\t    };\n\t    ;\n\t    /**\n\t     * Sets or gets the default [[transitionTo]] error handler.\n\t     *\n\t     * The error handler is called when a [[Transition]] is rejected or when any error occurred during the Transition.\n\t     * This includes errors caused by resolves and transition hooks.\n\t     *\n\t     * The built-in default error handler logs the error to the console.\n\t     *\n\t     * You can provide your own custom handler.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * stateService.defaultErrorHandler(function() {\n\t     *   // Do not log transitionTo errors\n\t     * });\n\t     * ```\n\t     *\n\t     * @param handler a global error handler function\n\t     * @returns the current global error handler\n\t     */\n\t    StateService.prototype.defaultErrorHandler = function (handler) {\n\t        return this._defaultErrorHandler = handler || this._defaultErrorHandler;\n\t    };\n\t    StateService.prototype.get = function (stateOrName, base) {\n\t        var reg = this.router.stateRegistry;\n\t        if (arguments.length === 0)\n\t            return reg.get();\n\t        return reg.get(stateOrName, base || this.$current);\n\t    };\n\t    return StateService;\n\t}());\n\texports.StateService = StateService;\n\n\n/***/ },\n/* 44 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module core */ /** */\n\tvar stateParams_1 = __webpack_require__(45);\n\tvar queue_1 = __webpack_require__(8);\n\tvar common_1 = __webpack_require__(3);\n\t/**\n\t * Global mutable state\n\t */\n\tvar Globals = (function () {\n\t    function Globals(transitionService) {\n\t        var _this = this;\n\t        this.params = new stateParams_1.StateParams();\n\t        this.transitionHistory = new queue_1.Queue([], 1);\n\t        this.successfulTransitions = new queue_1.Queue([], 1);\n\t        var beforeNewTransition = function ($transition$) {\n\t            _this.transition = $transition$;\n\t            _this.transitionHistory.enqueue($transition$);\n\t            var updateGlobalState = function () {\n\t                _this.successfulTransitions.enqueue($transition$);\n\t                _this.$current = $transition$.$to();\n\t                _this.current = _this.$current.self;\n\t                common_1.copy($transition$.params(), _this.params);\n\t            };\n\t            $transition$.onSuccess({}, updateGlobalState, { priority: 10000 });\n\t            var clearCurrentTransition = function () { if (_this.transition === $transition$)\n\t                _this.transition = null; };\n\t            $transition$.promise.then(clearCurrentTransition, clearCurrentTransition);\n\t        };\n\t        transitionService.onBefore({}, beforeNewTransition);\n\t    }\n\t    return Globals;\n\t}());\n\texports.Globals = Globals;\n\n\n/***/ },\n/* 45 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module params */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar StateParams = (function () {\n\t    function StateParams(params) {\n\t        if (params === void 0) { params = {}; }\n\t        common_1.extend(this, params);\n\t    }\n\t    /**\n\t     * Merges a set of parameters with all parameters inherited between the common parents of the\n\t     * current state and a given destination state.\n\t     *\n\t     * @param {Object} newParams The set of parameters which will be composited with inherited params.\n\t     * @param {Object} $current Internal definition of object representing the current state.\n\t     * @param {Object} $to Internal definition of object representing state to transition to.\n\t     */\n\t    StateParams.prototype.$inherit = function (newParams, $current, $to) {\n\t        var parents = common_1.ancestors($current, $to), parentParams, inherited = {}, inheritList = [];\n\t        for (var i in parents) {\n\t            if (!parents[i] || !parents[i].params)\n\t                continue;\n\t            parentParams = Object.keys(parents[i].params);\n\t            if (!parentParams.length)\n\t                continue;\n\t            for (var j in parentParams) {\n\t                if (inheritList.indexOf(parentParams[j]) >= 0)\n\t                    continue;\n\t                inheritList.push(parentParams[j]);\n\t                inherited[parentParams[j]] = this[parentParams[j]];\n\t            }\n\t        }\n\t        return common_1.extend({}, inherited, newParams);\n\t    };\n\t    ;\n\t    return StateParams;\n\t}());\n\texports.StateParams = StateParams;\n\n\n/***/ },\n/* 46 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/**\n\t * This module contains code for State Parameters.\n\t *\n\t * See [[ParamDeclaration]]\n\t * @module params\n\t * @preferred doc\n\t */\n\t/** for typedoc */\n\t__export(__webpack_require__(22));\n\t__export(__webpack_require__(25));\n\t__export(__webpack_require__(45));\n\t__export(__webpack_require__(24));\n\n\n/***/ },\n/* 47 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module path */ /** for typedoc */\n\t__export(__webpack_require__(21));\n\t__export(__webpack_require__(20));\n\n\n/***/ },\n/* 48 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module resolve */ /** for typedoc */\n\t__export(__webpack_require__(18));\n\t__export(__webpack_require__(19));\n\t__export(__webpack_require__(17));\n\n\n/***/ },\n/* 49 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module state */ /** for typedoc */\n\t__export(__webpack_require__(30));\n\t__export(__webpack_require__(40));\n\t__export(__webpack_require__(42));\n\t__export(__webpack_require__(39));\n\t__export(__webpack_require__(41));\n\t__export(__webpack_require__(38));\n\t__export(__webpack_require__(43));\n\t__export(__webpack_require__(14));\n\n\n/***/ },\n/* 50 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/**\n\t * This module contains APIs related to a Transition.\n\t *\n\t * See [[Transition]], [[$transitions]]\n\t *\n\t * @module transition\n\t * @preferred\n\t */\n\t/** for typedoc */\n\t__export(__webpack_require__(16));\n\t__export(__webpack_require__(15));\n\t__export(__webpack_require__(10));\n\t__export(__webpack_require__(11));\n\t__export(__webpack_require__(13));\n\t__export(__webpack_require__(31));\n\n\n/***/ },\n/* 51 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module url */ /** for typedoc */\n\t__export(__webpack_require__(28));\n\t__export(__webpack_require__(23));\n\t__export(__webpack_require__(27));\n\t__export(__webpack_require__(29));\n\n\n/***/ },\n/* 52 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tfunction __export(m) {\n\t    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n\t}\n\t/** @module view */ /** for typedoc */\n\t__export(__webpack_require__(37));\n\n\n/***/ },\n/* 53 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * # UI-Router for Angular 1\n\t *\n\t * - Provides an implementation for the [[CoreServices]] API, based on angular 1 services.\n\t * - Also registers some services with the angular 1 injector.\n\t * - Creates and bootstraps a new [[UIRouter]] object.  Ties it to the the angular 1 lifecycle.\n\t *\n\t * @module ng1\n\t * @preferred\n\t */\n\t\"use strict\";\n\t/** for typedoc */\n\tvar router_1 = __webpack_require__(26);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar common_1 = __webpack_require__(3);\n\tvar hof_1 = __webpack_require__(5);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar resolveService_1 = __webpack_require__(54);\n\tvar trace_1 = __webpack_require__(12);\n\tvar views_1 = __webpack_require__(55);\n\tvar templateFactory_1 = __webpack_require__(56);\n\tvar onEnterExitRetain_1 = __webpack_require__(57);\n\t/** @hidden */\n\tvar app = angular.module(\"ui.router.angular1\", []);\n\t/**\n\t * @ngdoc overview\n\t * @name ui.router.util\n\t *\n\t * @description\n\t * # ui.router.util sub-module\n\t *\n\t * This module is a dependency of other sub-modules. Do not include this module as a dependency\n\t * in your angular app (use {@link ui.router} module instead).\n\t *\n\t */\n\tangular.module('ui.router.util', ['ng', 'ui.router.init']);\n\t/**\n\t * @ngdoc overview\n\t * @name ui.router.router\n\t *\n\t * @requires ui.router.util\n\t *\n\t * @description\n\t * # ui.router.router sub-module\n\t *\n\t * This module is a dependency of other sub-modules. Do not include this module as a dependency\n\t * in your angular app (use {@link ui.router} module instead).\n\t */\n\tangular.module('ui.router.router', ['ui.router.util']);\n\t/**\n\t * @ngdoc overview\n\t * @name ui.router.state\n\t *\n\t * @requires ui.router.router\n\t * @requires ui.router.util\n\t *\n\t * @description\n\t * # ui.router.state sub-module\n\t *\n\t * This module is a dependency of the main ui.router module. Do not include this module as a dependency\n\t * in your angular app (use {@link ui.router} module instead).\n\t *\n\t */\n\tangular.module('ui.router.state', ['ui.router.router', 'ui.router.util', 'ui.router.angular1']);\n\t/**\n\t * @ngdoc overview\n\t * @name ui.router\n\t *\n\t * @requires ui.router.state\n\t *\n\t * @description\n\t * # ui.router\n\t *\n\t * ## The main module for ui.router\n\t * There are several sub-modules included with the ui.router module, however only this module is needed\n\t * as a dependency within your angular app. The other modules are for organization purposes.\n\t *\n\t * The modules are:\n\t * * ui.router - the main \"umbrella\" module\n\t * * ui.router.router -\n\t *\n\t * *You'll need to include **only** this module as the dependency within your angular app.*\n\t *\n\t * <pre>\n\t * <!doctype html>\n\t * <html ng-app=\"myApp\">\n\t * <head>\n\t *   <script src=\"js/angular.js\"></script>\n\t *   <!-- Include the ui-router script -->\n\t *   <script src=\"js/angular-ui-router.min.js\"></script>\n\t *   <script>\n\t *     // ...and add 'ui.router' as a dependency\n\t *     var myApp = angular.module('myApp', ['ui.router']);\n\t *   </script>\n\t * </head>\n\t * <body>\n\t * </body>\n\t * </html>\n\t * </pre>\n\t */\n\tangular.module('ui.router', ['ui.router.init', 'ui.router.state', 'ui.router.angular1']);\n\tangular.module('ui.router.compat', ['ui.router']);\n\t/**\n\t * Annotates a controller expression (may be a controller function(), a \"controllername\",\n\t * or \"controllername as name\")\n\t *\n\t * - Temporarily decorates $injector.instantiate.\n\t * - Invokes $controller() service\n\t *   - Calls $injector.instantiate with controller constructor\n\t * - Annotate constructor\n\t * - Undecorate $injector\n\t *\n\t * returns an array of strings, which are the arguments of the controller expression\n\t */\n\tfunction annotateController(controllerExpression) {\n\t    var $injector = coreservices_1.services.$injector;\n\t    var $controller = $injector.get(\"$controller\");\n\t    var oldInstantiate = $injector.instantiate;\n\t    try {\n\t        var deps_1;\n\t        $injector.instantiate = function fakeInstantiate(constructorFunction) {\n\t            $injector.instantiate = oldInstantiate; // Un-decorate ASAP\n\t            deps_1 = $injector.annotate(constructorFunction);\n\t        };\n\t        $controller(controllerExpression, { $scope: {} });\n\t        return deps_1;\n\t    }\n\t    finally {\n\t        $injector.instantiate = oldInstantiate;\n\t    }\n\t}\n\texports.annotateController = annotateController;\n\trunBlock.$inject = ['$injector', '$q'];\n\tfunction runBlock($injector, $q) {\n\t    coreservices_1.services.$injector = $injector;\n\t    coreservices_1.services.$q = $q;\n\t}\n\tapp.run(runBlock);\n\tvar router = null;\n\tng1UIRouter.$inject = ['$locationProvider'];\n\t/** This angular 1 provider instantiates a Router and exposes its services via the angular injector */\n\tfunction ng1UIRouter($locationProvider) {\n\t    // Create a new instance of the Router when the ng1UIRouterProvider is initialized\n\t    router = new router_1.UIRouter();\n\t    // Apply ng1 specific StateBuilder code for `views`, `resolve`, and `onExit/Retain/Enter` properties\n\t    router.stateRegistry.decorator(\"views\", views_1.ng1ViewsBuilder);\n\t    router.stateRegistry.decorator(\"onExit\", onEnterExitRetain_1.getStateHookBuilder(\"onExit\"));\n\t    router.stateRegistry.decorator(\"onRetain\", onEnterExitRetain_1.getStateHookBuilder(\"onRetain\"));\n\t    router.stateRegistry.decorator(\"onEnter\", onEnterExitRetain_1.getStateHookBuilder(\"onEnter\"));\n\t    router.viewService.viewConfigFactory('ng1', views_1.ng1ViewConfigFactory);\n\t    // Bind LocationConfig.hashPrefix to $locationProvider.hashPrefix\n\t    common_1.bindFunctions($locationProvider, coreservices_1.services.locationConfig, $locationProvider, ['hashPrefix']);\n\t    // Create a LocationService.onChange registry\n\t    var urlListeners = [];\n\t    coreservices_1.services.location.onChange = function (callback) {\n\t        urlListeners.push(callback);\n\t        return function () { return common_1.removeFrom(urlListeners)(callback); };\n\t    };\n\t    this.$get = $get;\n\t    $get.$inject = ['$location', '$browser', '$sniffer', '$rootScope', '$http', '$templateCache'];\n\t    function $get($location, $browser, $sniffer, $rootScope, $http, $templateCache) {\n\t        // Bind $locationChangeSuccess to the listeners registered in LocationService.onChange\n\t        $rootScope.$on(\"$locationChangeSuccess\", function (evt) { return urlListeners.forEach(function (fn) { return fn(evt); }); });\n\t        // Bind LocationConfig.html5Mode to $locationProvider.html5Mode and $sniffer.history\n\t        coreservices_1.services.locationConfig.html5Mode = function () {\n\t            var html5Mode = $locationProvider.html5Mode();\n\t            html5Mode = predicates_1.isObject(html5Mode) ? html5Mode.enabled : html5Mode;\n\t            return html5Mode && $sniffer.history;\n\t        };\n\t        coreservices_1.services.template.get = function (url) {\n\t            return $http.get(url, { cache: $templateCache, headers: { Accept: 'text/html' } }).then(hof_1.prop(\"data\"));\n\t        };\n\t        // Bind these LocationService functions to $location\n\t        common_1.bindFunctions($location, coreservices_1.services.location, $location, [\"replace\", \"url\", \"path\", \"search\", \"hash\"]);\n\t        // Bind these LocationConfig functions to $location\n\t        common_1.bindFunctions($location, coreservices_1.services.locationConfig, $location, ['port', 'protocol', 'host']);\n\t        // Bind these LocationConfig functions to $browser\n\t        common_1.bindFunctions($browser, coreservices_1.services.locationConfig, $browser, ['baseHref']);\n\t        return router;\n\t    }\n\t}\n\tfunction $stateParamsFactory(ng1UIRouter) {\n\t    return ng1UIRouter.globals.params;\n\t}\n\t// The 'ui.router' ng1 module depends on 'ui.router.init' module.\n\tangular.module('ui.router.init', []).provider(\"ng1UIRouter\", ng1UIRouter);\n\t// This effectively calls $get() to init when we enter runtime\n\tangular.module('ui.router.init').run(['ng1UIRouter', function (ng1UIRouter) { }]);\n\t// $urlMatcherFactory service and $urlMatcherFactoryProvider\n\tangular.module('ui.router.util').provider('$urlMatcherFactory', ['ng1UIRouterProvider', function () { return router.urlMatcherFactory; }]);\n\tangular.module('ui.router.util').run(['$urlMatcherFactory', function ($urlMatcherFactory) { }]);\n\t// $urlRouter service and $urlRouterProvider\n\tfunction getUrlRouterProvider() {\n\t    router.urlRouterProvider[\"$get\"] = function () {\n\t        router.urlRouter.update(true);\n\t        if (!this.interceptDeferred)\n\t            router.urlRouter.listen();\n\t        return router.urlRouter;\n\t    };\n\t    return router.urlRouterProvider;\n\t}\n\tangular.module('ui.router.router').provider('$urlRouter', ['ng1UIRouterProvider', getUrlRouterProvider]);\n\tangular.module('ui.router.router').run(['$urlRouter', function ($urlRouter) { }]);\n\t// $state service and $stateProvider\n\t// $urlRouter service and $urlRouterProvider\n\tfunction getStateProvider() {\n\t    router.stateProvider[\"$get\"] = function () {\n\t        // Autoflush once we are in runtime\n\t        router.stateRegistry.stateQueue.autoFlush(router.stateService);\n\t        return router.stateService;\n\t    };\n\t    return router.stateProvider;\n\t}\n\tangular.module('ui.router.state').provider('$state', ['ng1UIRouterProvider', getStateProvider]);\n\tangular.module('ui.router.state').run(['$state', function ($state) { }]);\n\t// $stateParams service\n\tangular.module('ui.router.state').factory('$stateParams', ['ng1UIRouter', function (ng1UIRouter) {\n\t        return ng1UIRouter.globals.params;\n\t    }]);\n\t// $transitions service and $transitionsProvider\n\tfunction getTransitionsProvider() {\n\t    router.transitionService[\"$get\"] = function () { return router.transitionService; };\n\t    return router.transitionService;\n\t}\n\tangular.module('ui.router.state').provider('$transitions', ['ng1UIRouterProvider', getTransitionsProvider]);\n\t// $templateFactory service\n\tangular.module('ui.router.util').factory('$templateFactory', ['ng1UIRouter', function () { return new templateFactory_1.TemplateFactory(); }]);\n\t// The $view service\n\tangular.module('ui.router').factory('$view', function () { return router.viewService; });\n\t// The old $resolve service\n\tangular.module('ui.router').factory('$resolve', resolveService_1.resolveFactory);\n\t// $trace service\n\tangular.module(\"ui.router\").service(\"$trace\", function () { return trace_1.trace; });\n\twatchDigests.$inject = ['$rootScope'];\n\tfunction watchDigests($rootScope) {\n\t    $rootScope.$watch(function () { trace_1.trace.approximateDigests++; });\n\t}\n\texports.watchDigests = watchDigests;\n\tangular.module(\"ui.router\").run(watchDigests);\n\texports.getLocals = function (ctx) {\n\t    var tokens = ctx.getTokens().filter(predicates_1.isString);\n\t    var tuples = tokens.map(function (key) { return [key, ctx.getResolvable(key).data]; });\n\t    return tuples.reduce(common_1.applyPairs, {});\n\t};\n\t/** Injectable services */\n\t/**\n\t * An injectable service object which has the current state parameters\n\t *\n\t * This angular service (singleton object) holds the current state parameters.\n\t * The values in `$stateParams` are not updated until *after* a [[Transition]] successfully completes.\n\t *\n\t * This object can be injected into other services.\n\t *\n\t * @example\n\t * ```js\n\t *\n\t * SomeService.$inject = ['$http', '$stateParams'];\n\t * function SomeService($http, $stateParams) {\n\t *   return {\n\t *     getUser: function() {\n\t *       return $http.get('/api/users/' + $stateParams.username);\n\t *     }\n\t *   }\n\t * };\n\t * angular.service('SomeService', SomeService);\n\t * ```\n\t *\n\t * ### Deprecation warning:\n\t *\n\t * When `$stateParams` is injected into transition hooks, resolves and view controllers, they receive a different\n\t * object than this global service object.  In those cases, the injected object has the parameter values for the\n\t * *pending* Transition.\n\t *\n\t * Because of these confusing details, this service is deprecated.\n\t *\n\t * @deprecated Instead of using `$stateParams, inject the current [[Transition]] as `$transition$` and use [[Transition.params]]\n\t * ```js\n\t * MyController.$inject = ['$transition$'];\n\t * function MyController($transition$) {\n\t *   var username = $transition$.params().username;\n\t *   // .. do something with username\n\t * }\n\t * ```\n\t */\n\tvar $stateParams;\n\t/**\n\t * An injectable service primarily used to register transition hooks\n\t *\n\t * This angular service exposes the [[TransitionService]] singleton, which is primarily used to add transition hooks.\n\t *\n\t * The same object is also exposed as [[$transitionsProvider]] for injection during angular config time.\n\t */\n\tvar $transitions;\n\t/**\n\t * A config-time injectable provider primarily used to register transition hooks\n\t *\n\t * This angular provider exposes the [[TransitionService]] singleton, which is primarily used to add transition hooks.\n\t *\n\t * The same object is also exposed as [[$transitions]] for injection at runtime.\n\t */\n\tvar $transitionsProvider;\n\t/**\n\t * An injectable service used to query for current state information.\n\t *\n\t * This angular service exposes the [[StateService]] singleton.\n\t */\n\tvar $state;\n\t/**\n\t * A config-time injectable provider used to register states.\n\t *\n\t * This angular service exposes the [[StateProvider]] singleton.\n\t */\n\tvar $stateProvider;\n\t/**\n\t * A config-time injectable provider used to manage the URL.\n\t *\n\t * This angular service exposes the [[UrlRouterProvider]] singleton.\n\t */\n\tvar $urlRouterProvider;\n\t/**\n\t * An injectable service used to configure URL redirects.\n\t *\n\t * This angular service exposes the [[UrlRouter]] singleton.\n\t */\n\tvar $urlRouter;\n\t/**\n\t * An injectable service used to configure the URL.\n\t *\n\t * This service is used to set url mapping options, and create [[UrlMatcher]] objects.\n\t *\n\t * This angular service exposes the [[UrlMatcherFactory]] singleton.\n\t * The singleton is also exposed at config-time as the [[$urlMatcherFactoryProvider]].\n\t */\n\tvar $urlMatcherFactory;\n\t/**\n\t * An injectable service used to configure the URL.\n\t *\n\t * This service is used to set url mapping options, and create [[UrlMatcher]] objects.\n\t *\n\t * This angular service exposes the [[UrlMatcherFactory]] singleton at config-time.\n\t * The singleton is also exposed at runtime as the [[$urlMatcherFactory]].\n\t */\n\tvar $urlMatcherFactoryProvider;\n\n\n/***/ },\n/* 54 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module ng1 */ /** */\n\tvar stateObject_1 = __webpack_require__(42);\n\tvar node_1 = __webpack_require__(21);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar common_1 = __webpack_require__(3);\n\tvar stateBuilder_1 = __webpack_require__(40);\n\t/**\n\t * Implementation of the legacy `$resolve` service for angular 1.\n\t */\n\tvar $resolve = {\n\t    /**\n\t     * Asynchronously injects a resolve block.\n\t     *\n\t     * This emulates most of the behavior of the ui-router 0.2.x $resolve.resolve() service API.\n\t     *\n\t     * Given an object `invocables`, where keys are strings and values are injectable functions,\n\t     * injects each function, and waits for the resulting promise to resolve.\n\t     * When all resulting promises are resolved, returns the results as an object.\n\t     *\n\t     * @example\n\t     * ```js\n\t     *\n\t     * let invocables = {\n\t     *   foo: [ '$http', ($http) =>\n\t     *            $http.get('/api/foo').then(resp => resp.data) ],\n\t     *   bar: [ 'foo', '$http', (foo, $http) =>\n\t     *            $http.get('/api/bar/' + foo.barId).then(resp => resp.data) ]\n\t     * }\n\t     * $resolve.resolve(invocables)\n\t     *     .then(results => console.log(results.foo, results.bar))\n\t     * // Logs foo and bar:\n\t     * // { id: 123, barId: 456, fooData: 'foo data' }\n\t     * // { id: 456, barData: 'bar data' }\n\t     * ```\n\t     *\n\t     * @param invocables an object which looks like an [[StateDefinition.resolve]] object; keys are resolve names and values are injectable functions\n\t     * @param locals key/value pre-resolved data (locals)\n\t     * @param parent a promise for a \"parent resolve\"\n\t     */\n\t    resolve: function (invocables, locals, parent) {\n\t        if (locals === void 0) { locals = {}; }\n\t        var parentNode = new node_1.PathNode(new stateObject_1.State({ params: {}, resolvables: [] }));\n\t        var node = new node_1.PathNode(new stateObject_1.State({ params: {}, resolvables: [] }));\n\t        var context = new resolveContext_1.ResolveContext([parentNode, node]);\n\t        context.addResolvables(stateBuilder_1.resolvablesBuilder({ resolve: invocables }), node.state);\n\t        var resolveData = function (parentLocals) {\n\t            var rewrap = function (_locals) { return stateBuilder_1.resolvablesBuilder({ resolve: common_1.map(_locals, function (local) { return function () { return local; }; }) }); };\n\t            context.addResolvables(rewrap(parentLocals), parentNode.state);\n\t            context.addResolvables(rewrap(locals), node.state);\n\t            var tuples2ObjR = function (acc, tuple) {\n\t                acc[tuple.token] = tuple.value;\n\t                return acc;\n\t            };\n\t            return context.resolvePath().then(function (results) { return results.reduce(tuples2ObjR, {}); });\n\t        };\n\t        return parent ? parent.then(resolveData) : resolveData({});\n\t    }\n\t};\n\t/** @hidden */\n\texports.resolveFactory = function () { return $resolve; };\n\n\n/***/ },\n/* 55 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar strings_1 = __webpack_require__(9);\n\tvar view_1 = __webpack_require__(37);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar trace_1 = __webpack_require__(12);\n\tvar templateFactory_1 = __webpack_require__(56);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar resolvable_1 = __webpack_require__(19);\n\texports.ng1ViewConfigFactory = function (path, view) { return new Ng1ViewConfig(path, view); };\n\t/**\n\t * This is a [[StateBuilder.builder]] function for angular1 `views`.\n\t *\n\t * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder\n\t * handles the `views` property with logic specific to angular-ui-router (ng1).\n\t *\n\t * If no `views: {}` property exists on the [[StateDeclaration]], then it creates the `views` object\n\t * and applies the state-level configuration to a view named `$default`.\n\t */\n\tfunction ng1ViewsBuilder(state) {\n\t    var tplKeys = ['templateProvider', 'templateUrl', 'template', 'notify', 'async'], ctrlKeys = ['controller', 'controllerProvider', 'controllerAs', 'resolveAs'], compKeys = ['component', 'bindings'], nonCompKeys = tplKeys.concat(ctrlKeys), allKeys = compKeys.concat(nonCompKeys);\n\t    var views = {}, viewsObject = state.views || { \"$default\": common_1.pick(state, allKeys) };\n\t    common_1.forEach(viewsObject, function (config, name) {\n\t        // Account for views: { \"\": { template... } }\n\t        name = name || \"$default\";\n\t        // Account for views: { header: \"headerComponent\" }\n\t        if (predicates_1.isString(config))\n\t            config = { component: config };\n\t        if (!Object.keys(config).length)\n\t            return;\n\t        // Configure this view for routing to an angular 1.5+ style .component (or any directive, really)\n\t        if (config.component) {\n\t            if (nonCompKeys.map(function (key) { return predicates_1.isDefined(config[key]); }).reduce(common_1.anyTrueR, false)) {\n\t                throw new Error(\"Cannot combine: \" + compKeys.join(\"|\") + \" with: \" + nonCompKeys.join(\"|\") + \" in stateview: 'name@\" + state.name + \"'\");\n\t            }\n\t            // Dynamically build a template like \"<component-name input1='::$resolve.foo'></component-name>\"\n\t            config.templateProvider = ['$injector', function ($injector) {\n\t                    var resolveFor = function (key) { return config.bindings && config.bindings[key] || key; };\n\t                    var prefix = angular.version.minor >= 3 ? \"::\" : \"\";\n\t                    var attributeTpl = function (input) {\n\t                        var attrName = strings_1.kebobString(input.name);\n\t                        var resolveName = resolveFor(input.name);\n\t                        if (input.type === '@')\n\t                            return attrName + \"='{{\" + prefix + \"$resolve.\" + resolveName + \"}}'\";\n\t                        return attrName + \"='\" + prefix + \"$resolve.\" + resolveName + \"'\";\n\t                    };\n\t                    var attrs = getComponentInputs($injector, config.component).map(attributeTpl).join(\" \");\n\t                    var kebobName = strings_1.kebobString(config.component);\n\t                    return \"<\" + kebobName + \" \" + attrs + \"></\" + kebobName + \">\";\n\t                }];\n\t        }\n\t        config.resolveAs = config.resolveAs || '$resolve';\n\t        config.$type = \"ng1\";\n\t        config.$context = state;\n\t        config.$name = name;\n\t        var normalized = view_1.ViewService.normalizeUIViewTarget(config.$context, config.$name);\n\t        config.$uiViewName = normalized.uiViewName;\n\t        config.$uiViewContextAnchor = normalized.uiViewContextAnchor;\n\t        views[name] = config;\n\t    });\n\t    return views;\n\t}\n\texports.ng1ViewsBuilder = ng1ViewsBuilder;\n\t// for ng 1.2 style, process the scope: { input: \"=foo\" }\n\t// for ng 1.3 through ng 1.5, process the component's bindToController: { input: \"=foo\" } object\n\tvar scopeBindings = function (bindingsObj) { return Object.keys(bindingsObj || {})\n\t    .map(function (key) { return [key, /^([=<@])[?]?(.*)/.exec(bindingsObj[key])]; }) // [ 'input', [ '=foo', '=', 'foo' ] ]\n\t    .filter(function (tuple) { return predicates_1.isDefined(tuple) && predicates_1.isDefined(tuple[1]); }) // skip malformed values\n\t    .map(function (tuple) { return ({ name: tuple[1][2] || tuple[0], type: tuple[1][1] }); }); }; // { name: ('foo' || 'input'), type: '=' }\n\t// Given a directive definition, find its object input attributes\n\t// Use different properties, depending on the type of directive (component, bindToController, normal)\n\tvar getBindings = function (def) {\n\t    if (predicates_1.isObject(def.bindToController))\n\t        return scopeBindings(def.bindToController);\n\t    return scopeBindings(def.scope);\n\t};\n\t// Gets all the directive(s)' inputs ('@', '=', and '<')\n\tfunction getComponentInputs($injector, name) {\n\t    var cmpDefs = $injector.get(name + \"Directive\"); // could be multiple\n\t    if (!cmpDefs || !cmpDefs.length)\n\t        throw new Error(\"Unable to find component named '\" + name + \"'\");\n\t    return cmpDefs.map(getBindings).reduce(common_1.unnestR, []);\n\t}\n\tvar id = 0;\n\tvar Ng1ViewConfig = (function () {\n\t    function Ng1ViewConfig(path, viewDecl) {\n\t        this.path = path;\n\t        this.viewDecl = viewDecl;\n\t        this.$id = id++;\n\t        this.loaded = false;\n\t    }\n\t    Ng1ViewConfig.prototype.load = function () {\n\t        var _this = this;\n\t        var $q = coreservices_1.services.$q;\n\t        if (!this.hasTemplate())\n\t            throw new Error(\"No template configuration specified for '\" + this.viewDecl.$uiViewName + \"@\" + this.viewDecl.$uiViewContextAnchor + \"'\");\n\t        var context = new resolveContext_1.ResolveContext(this.path);\n\t        var params = this.path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {});\n\t        var promises = {\n\t            template: $q.when(this.getTemplate(params, new templateFactory_1.TemplateFactory(), context)),\n\t            controller: $q.when(this.getController(context))\n\t        };\n\t        return $q.all(promises).then(function (results) {\n\t            trace_1.trace.traceViewServiceEvent(\"Loaded\", _this);\n\t            _this.controller = results.controller;\n\t            _this.template = results.template;\n\t        });\n\t    };\n\t    /**\n\t     * Checks a view configuration to ensure that it specifies a template.\n\t     *\n\t     * @return {boolean} Returns `true` if the configuration contains a valid template, otherwise `false`.\n\t     */\n\t    Ng1ViewConfig.prototype.hasTemplate = function () {\n\t        return !!(this.viewDecl.template || this.viewDecl.templateUrl || this.viewDecl.templateProvider);\n\t    };\n\t    Ng1ViewConfig.prototype.getTemplate = function (params, $factory, context) {\n\t        return $factory.fromConfig(this.viewDecl, params, context);\n\t    };\n\t    /**\n\t     * Gets the controller for a view configuration.\n\t     *\n\t     * @returns {Function|Promise.<Function>} Returns a controller, or a promise that resolves to a controller.\n\t     */\n\t    Ng1ViewConfig.prototype.getController = function (context) {\n\t        var provider = this.viewDecl.controllerProvider;\n\t        if (!predicates_1.isInjectable(provider))\n\t            return this.viewDecl.controller;\n\t        var deps = coreservices_1.services.$injector.annotate(provider);\n\t        var providerFn = predicates_1.isArray(provider) ? common_1.tail(provider) : provider;\n\t        var resolvable = new resolvable_1.Resolvable(\"\", providerFn, deps);\n\t        return resolvable.get(context);\n\t    };\n\t    return Ng1ViewConfig;\n\t}());\n\texports.Ng1ViewConfig = Ng1ViewConfig;\n\n\n/***/ },\n/* 56 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/** @module view */ /** for typedoc */\n\tvar predicates_1 = __webpack_require__(4);\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar common_1 = __webpack_require__(3);\n\tvar resolvable_1 = __webpack_require__(19);\n\t/**\n\t * Service which manages loading of templates from a ViewConfig.\n\t */\n\tvar TemplateFactory = (function () {\n\t    function TemplateFactory() {\n\t    }\n\t    /**\n\t     * Creates a template from a configuration object.\n\t     *\n\t     * @param config Configuration object for which to load a template.\n\t     * The following properties are search in the specified order, and the first one\n\t     * that is defined is used to create the template:\n\t     *\n\t     * @param params  Parameters to pass to the template function.\n\t     * @param context The resolve context associated with the template's view\n\t     *\n\t     * @return {string|object}  The template html as a string, or a promise for\n\t     * that string,or `null` if no template is configured.\n\t     */\n\t    TemplateFactory.prototype.fromConfig = function (config, params, context) {\n\t        return (predicates_1.isDefined(config.template) ? this.fromString(config.template, params) :\n\t            predicates_1.isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :\n\t                predicates_1.isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, context) :\n\t                    null);\n\t    };\n\t    ;\n\t    /**\n\t     * Creates a template from a string or a function returning a string.\n\t     *\n\t     * @param template html template as a string or function that returns an html template as a string.\n\t     * @param params Parameters to pass to the template function.\n\t     *\n\t     * @return {string|object} The template html as a string, or a promise for that\n\t     * string.\n\t     */\n\t    TemplateFactory.prototype.fromString = function (template, params) {\n\t        return predicates_1.isFunction(template) ? template(params) : template;\n\t    };\n\t    ;\n\t    /**\n\t     * Loads a template from the a URL via `$http` and `$templateCache`.\n\t     *\n\t     * @param {string|Function} url url of the template to load, or a function\n\t     * that returns a url.\n\t     * @param {Object} params Parameters to pass to the url function.\n\t     * @return {string|Promise.<string>} The template html as a string, or a promise\n\t     * for that string.\n\t     */\n\t    TemplateFactory.prototype.fromUrl = function (url, params) {\n\t        if (predicates_1.isFunction(url))\n\t            url = url(params);\n\t        if (url == null)\n\t            return null;\n\t        return coreservices_1.services.template.get(url);\n\t    };\n\t    ;\n\t    /**\n\t     * Creates a template by invoking an injectable provider function.\n\t     *\n\t     * @param provider Function to invoke via `locals`\n\t     * @param {Function} injectFn a function used to invoke the template provider\n\t     * @return {string|Promise.<string>} The template html as a string, or a promise\n\t     * for that string.\n\t     */\n\t    TemplateFactory.prototype.fromProvider = function (provider, params, context) {\n\t        var deps = coreservices_1.services.$injector.annotate(provider);\n\t        var providerFn = predicates_1.isArray(provider) ? common_1.tail(provider) : provider;\n\t        var resolvable = new resolvable_1.Resolvable(\"\", providerFn, deps);\n\t        return resolvable.get(context);\n\t    };\n\t    ;\n\t    return TemplateFactory;\n\t}());\n\texports.TemplateFactory = TemplateFactory;\n\n\n/***/ },\n/* 57 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\tvar coreservices_1 = __webpack_require__(6);\n\tvar services_1 = __webpack_require__(53);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar common_1 = __webpack_require__(3);\n\t/**\n\t * This is a [[StateBuilder.builder]] function for angular1 `onEnter`, `onExit`,\n\t * `onRetain` callback hooks on a [[Ng1StateDeclaration]].\n\t *\n\t * When the [[StateBuilder]] builds a [[State]] object from a raw [[StateDeclaration]], this builder\n\t * ensures that those hooks are injectable for angular-ui-router (ng1).\n\t */\n\texports.getStateHookBuilder = function (hookName) {\n\t    return function stateHookBuilder(state, parentFn) {\n\t        var hook = state[hookName];\n\t        function decoratedNg1Hook(trans, state) {\n\t            var resolveContext = new resolveContext_1.ResolveContext(trans.treeChanges().to);\n\t            return coreservices_1.services.$injector.invoke(hook, this, common_1.extend({ $state$: state }, services_1.getLocals(resolveContext)));\n\t        }\n\t        return hook ? decoratedNg1Hook : undefined;\n\t    };\n\t};\n\n\n/***/ },\n/* 58 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t/**\n\t * These are the UI-Router angular 1 directives.\n\t *\n\t * These directives are used in templates to create viewports and navigate to states\n\t *\n\t * @preferred @module ng1_directives\n\t */ /** for typedoc */\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar hof_1 = __webpack_require__(5);\n\t/** @hidden */\n\tfunction parseStateRef(ref, current) {\n\t    var preparsed = ref.match(/^\\s*({[^}]*})\\s*$/), parsed;\n\t    if (preparsed)\n\t        ref = current + '(' + preparsed[1] + ')';\n\t    parsed = ref.replace(/\\n/g, \" \").match(/^([^(]+?)\\s*(\\((.*)\\))?$/);\n\t    if (!parsed || parsed.length !== 4)\n\t        throw new Error(\"Invalid state ref '\" + ref + \"'\");\n\t    return { state: parsed[1], paramExpr: parsed[3] || null };\n\t}\n\t/** @hidden */\n\tfunction stateContext(el) {\n\t    var $uiView = el.parent().inheritedData('$uiView');\n\t    var path = hof_1.parse('$cfg.path')($uiView);\n\t    return path ? common_1.tail(path).state.name : undefined;\n\t}\n\t/** @hidden */\n\tfunction getTypeInfo(el) {\n\t    // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.\n\t    var isSvg = Object.prototype.toString.call(el.prop('href')) === '[object SVGAnimatedString]';\n\t    var isForm = el[0].nodeName === \"FORM\";\n\t    return {\n\t        attr: isForm ? \"action\" : (isSvg ? 'xlink:href' : 'href'),\n\t        isAnchor: el.prop(\"tagName\").toUpperCase() === \"A\",\n\t        clickable: !isForm\n\t    };\n\t}\n\t/** @hidden */\n\tfunction clickHook(el, $state, $timeout, type, current) {\n\t    return function (e) {\n\t        var button = e.which || e.button, target = current();\n\t        if (!(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || el.attr('target'))) {\n\t            // HACK: This is to allow ng-clicks to be processed before the transition is initiated:\n\t            var transition = $timeout(function () {\n\t                $state.go(target.state, target.params, target.options);\n\t            });\n\t            e.preventDefault();\n\t            // if the state has no URL, ignore one preventDefault from the <a> directive.\n\t            var ignorePreventDefaultCount = type.isAnchor && !target.href ? 1 : 0;\n\t            e.preventDefault = function () {\n\t                if (ignorePreventDefaultCount-- <= 0)\n\t                    $timeout.cancel(transition);\n\t            };\n\t        }\n\t    };\n\t}\n\t/** @hidden */\n\tfunction defaultOpts(el, $state) {\n\t    return { relative: stateContext(el) || $state.$current, inherit: true };\n\t}\n\t/**\n\t * `ui-sref`: A directive for linking to a state\n\t *\n\t * A directive that binds a link (`<a>` tag) to a state.\n\t * If the state has an associated URL, the directive will automatically generate and\n\t * update the `href` attribute via the [[StateService.href]]  method.\n\t * Clicking the link will trigger a state transition with optional parameters.\n\t *\n\t * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be\n\t * handled natively by the browser.\n\t *\n\t * You can also use relative state paths within ui-sref, just like the relative\n\t * paths passed to `$state.go()`.\n\t * You just need to be aware that the path is relative to the state that the link lives in.\n\t * In other words, the state that created the view containing the link.\n\t *\n\t * You can specify options to pass to [[StateService.go]] using the `ui-sref-opts` attribute.\n\t * Options are restricted to `location`, `inherit`, and `reload`.\n\t *\n\t * Here's an example of how you'd use ui-sref and how it would compile.\n\t * If you have the following template:\n\t *\n\t * @example\n\t * ```html\n\t *\n\t * <pre>\n\t * <a ui-sref=\"home\">Home</a> | <a ui-sref=\"about\">About</a> | <a ui-sref=\"{page: 2}\">Next page</a>\n\t *\n\t * <ul>\n\t *     <li ng-repeat=\"contact in contacts\">\n\t *         <a ui-sref=\"contacts.detail({ id: contact.id })\">{{ contact.name }}</a>\n\t *     </li>\n\t * </ul>\n\t * </pre>\n\t * ```\n\t *\n\t * Then the compiled html would be (assuming Html5Mode is off and current state is contacts):\n\t *\n\t * ```html\n\t *\n\t * <pre>\n\t * <a href=\"#/home\" ui-sref=\"home\">Home</a> | <a href=\"#/about\" ui-sref=\"about\">About</a> | <a href=\"#/contacts?page=2\" ui-sref=\"{page: 2}\">Next page</a>\n\t *\n\t * <ul>\n\t *     <li ng-repeat=\"contact in contacts\">\n\t *         <a href=\"#/contacts/1\" ui-sref=\"contacts.detail({ id: contact.id })\">Joe</a>\n\t *     </li>\n\t *     <li ng-repeat=\"contact in contacts\">\n\t *         <a href=\"#/contacts/2\" ui-sref=\"contacts.detail({ id: contact.id })\">Alice</a>\n\t *     </li>\n\t *     <li ng-repeat=\"contact in contacts\">\n\t *         <a href=\"#/contacts/3\" ui-sref=\"contacts.detail({ id: contact.id })\">Bob</a>\n\t *     </li>\n\t * </ul>\n\t *\n\t * <a ui-sref=\"home\" ui-sref-opts=\"{reload: true}\">Home</a>\n\t * </pre>\n\t * ```\n\t *\n\t * @param {string} ui-sref 'stateName' can be any valid absolute or relative state\n\t * @param {Object} ui-sref-opts options to pass to [[StateService.go]]\n\t */\n\tvar uiSref = ['$state', '$timeout',\n\t    function $StateRefDirective($state, $timeout) {\n\t        return {\n\t            restrict: 'A',\n\t            require: ['?^uiSrefActive', '?^uiSrefActiveEq'],\n\t            link: function (scope, element, attrs, uiSrefActive) {\n\t                var ref = parseStateRef(attrs.uiSref, $state.current.name);\n\t                var def = { state: ref.state, href: null, params: null, options: null };\n\t                var type = getTypeInfo(element);\n\t                var active = uiSrefActive[1] || uiSrefActive[0];\n\t                var unlinkInfoFn = null;\n\t                def.options = common_1.extend(defaultOpts(element, $state), attrs.uiSrefOpts ? scope.$eval(attrs.uiSrefOpts) : {});\n\t                var update = function (val) {\n\t                    if (val)\n\t                        def.params = angular.copy(val);\n\t                    def.href = $state.href(ref.state, def.params, def.options);\n\t                    if (unlinkInfoFn)\n\t                        unlinkInfoFn();\n\t                    if (active)\n\t                        unlinkInfoFn = active.$$addStateInfo(ref.state, def.params);\n\t                    if (def.href !== null)\n\t                        attrs.$set(type.attr, def.href);\n\t                };\n\t                if (ref.paramExpr) {\n\t                    scope.$watch(ref.paramExpr, function (val) { if (val !== def.params)\n\t                        update(val); }, true);\n\t                    def.params = angular.copy(scope.$eval(ref.paramExpr));\n\t                }\n\t                update();\n\t                if (!type.clickable)\n\t                    return;\n\t                element.bind(\"click\", clickHook(element, $state, $timeout, type, function () { return def; }));\n\t            }\n\t        };\n\t    }];\n\t/**\n\t * `ui-state`: A dynamic version of `ui-sref`\n\t *\n\t * Much like ui-sref, but will accept named $scope properties to evaluate for a state definition,\n\t * params and override options.\n\t *\n\t * @example\n\t * ```html\n\t *\n\t * <li ng-repeat=\"nav in navlinks\">\n\t *   <a ui-state=\"nav.statename\">{{nav.description}}</a>\n\t * </li>\n\t *\n\t * @param {string} ui-state 'stateName' can be any valid absolute or relative state\n\t * @param {Object} ui-state-params params to pass to [[StateService.href]]\n\t * @param {Object} ui-state-opts options to pass to [[StateService.go]]\n\t */\n\tvar uiState = ['$state', '$timeout',\n\t    function $StateRefDynamicDirective($state, $timeout) {\n\t        return {\n\t            restrict: 'A',\n\t            require: ['?^uiSrefActive', '?^uiSrefActiveEq'],\n\t            link: function (scope, element, attrs, uiSrefActive) {\n\t                var type = getTypeInfo(element);\n\t                var active = uiSrefActive[1] || uiSrefActive[0];\n\t                var group = [attrs.uiState, attrs.uiStateParams || null, attrs.uiStateOpts || null];\n\t                var watch = '[' + group.map(function (val) { return val || 'null'; }).join(', ') + ']';\n\t                var def = { state: null, params: null, options: null, href: null };\n\t                var unlinkInfoFn = null;\n\t                function runStateRefLink(group) {\n\t                    def.state = group[0];\n\t                    def.params = group[1];\n\t                    def.options = group[2];\n\t                    def.href = $state.href(def.state, def.params, def.options);\n\t                    if (unlinkInfoFn)\n\t                        unlinkInfoFn();\n\t                    if (active)\n\t                        unlinkInfoFn = active.$$addStateInfo(def.state, def.params);\n\t                    if (def.href)\n\t                        attrs.$set(type.attr, def.href);\n\t                }\n\t                scope.$watch(watch, runStateRefLink, true);\n\t                runStateRefLink(scope.$eval(watch));\n\t                if (!type.clickable)\n\t                    return;\n\t                element.bind(\"click\", clickHook(element, $state, $timeout, type, function () { return def; }));\n\t            }\n\t        };\n\t    }];\n\t/**\n\t * `ui-sref-active` and `ui-sref-active-eq`: A directive that adds a CSS class when a `ui-sref` is active\n\t *\n\t * A directive working alongside ui-sref to add classes to an element when the\n\t * related ui-sref directive's state is active, and removing them when it is inactive.\n\t * The primary use-case is to simplify the special appearance of navigation menus\n\t * relying on `ui-sref`, by having the \"active\" state's menu button appear different,\n\t * distinguishing it from the inactive menu items.\n\t *\n\t * ui-sref-active can live on the same element as ui-sref or on a parent element. The first\n\t * ui-sref-active found at the same level or above the ui-sref will be used.\n\t *\n\t * Will activate when the ui-sref's target state or any child state is active. If you\n\t * need to activate only when the ui-sref target state is active and *not* any of\n\t * it's children, then you will use ui-sref-active-eq\n\t *\n\t * Given the following template:\n\t * @example\n\t * ```html\n\t *\n\t * <pre>\n\t * <ul>\n\t *   <li ui-sref-active=\"active\" class=\"item\">\n\t *     <a href ui-sref=\"app.user({user: 'bilbobaggins'})\">@bilbobaggins</a>\n\t *   </li>\n\t * </ul>\n\t * </pre>\n\t * ```\n\t *\n\t *\n\t * When the app state is \"app.user\" (or any children states), and contains the state parameter \"user\" with value \"bilbobaggins\",\n\t * the resulting HTML will appear as (note the 'active' class):\n\t *\n\t * ```html\n\t *\n\t * <pre>\n\t * <ul>\n\t *   <li ui-sref-active=\"active\" class=\"item active\">\n\t *     <a ui-sref=\"app.user({user: 'bilbobaggins'})\" href=\"/users/bilbobaggins\">@bilbobaggins</a>\n\t *   </li>\n\t * </ul>\n\t * </pre>\n\t * ```\n\t *\n\t * The class name is interpolated **once** during the directives link time (any further changes to the\n\t * interpolated value are ignored).\n\t *\n\t * Multiple classes may be specified in a space-separated format:\n\t *\n\t * ```html\n\t * <pre>\n\t * <ul>\n\t *   <li ui-sref-active='class1 class2 class3'>\n\t *     <a ui-sref=\"app.user\">link</a>\n\t *   </li>\n\t * </ul>\n\t * </pre>\n\t * ```\n\t *\n\t * It is also possible to pass ui-sref-active an expression that evaluates\n\t * to an object hash, whose keys represent active class names and whose\n\t * values represent the respective state names/globs.\n\t * ui-sref-active will match if the current active state **includes** any of\n\t * the specified state names/globs, even the abstract ones.\n\t *\n\t * Given the following template, with \"admin\" being an abstract state:\n\t * @example\n\t * ```html\n\t *\n\t * <pre>\n\t * <div ui-sref-active=\"{'active': 'admin.*'}\">\n\t *   <a ui-sref-active=\"active\" ui-sref=\"admin.roles\">Roles</a>\n\t * </div>\n\t * </pre>\n\t * ```\n\t *\n\t * When the current state is \"admin.roles\" the \"active\" class will be applied\n\t * to both the <div> and <a> elements. It is important to note that the state\n\t * names/globs passed to ui-sref-active shadow the state provided by ui-sref.\n\t */\n\tvar uiSrefActive = ['$state', '$stateParams', '$interpolate', '$transitions',\n\t    function $StateRefActiveDirective($state, $stateParams, $interpolate, $transitions) {\n\t        return {\n\t            restrict: \"A\",\n\t            controller: ['$scope', '$element', '$attrs', '$timeout', function ($scope, $element, $attrs, $timeout) {\n\t                    var states = [], activeClasses = {}, activeEqClass, uiSrefActive;\n\t                    // There probably isn't much point in $observing this\n\t                    // uiSrefActive and uiSrefActiveEq share the same directive object with some\n\t                    // slight difference in logic routing\n\t                    activeEqClass = $interpolate($attrs.uiSrefActiveEq || '', false)($scope);\n\t                    try {\n\t                        uiSrefActive = $scope.$eval($attrs.uiSrefActive);\n\t                    }\n\t                    catch (e) {\n\t                    }\n\t                    uiSrefActive = uiSrefActive || $interpolate($attrs.uiSrefActive || '', false)($scope);\n\t                    if (predicates_1.isObject(uiSrefActive)) {\n\t                        common_1.forEach(uiSrefActive, function (stateOrName, activeClass) {\n\t                            if (predicates_1.isString(stateOrName)) {\n\t                                var ref = parseStateRef(stateOrName, $state.current.name);\n\t                                addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);\n\t                            }\n\t                        });\n\t                    }\n\t                    // Allow uiSref to communicate with uiSrefActive[Equals]\n\t                    this.$$addStateInfo = function (newState, newParams) {\n\t                        // we already got an explicit state provided by ui-sref-active, so we\n\t                        // shadow the one that comes from ui-sref\n\t                        if (predicates_1.isObject(uiSrefActive) && states.length > 0) {\n\t                            return;\n\t                        }\n\t                        var deregister = addState(newState, newParams, uiSrefActive);\n\t                        update();\n\t                        return deregister;\n\t                    };\n\t                    $scope.$on('$stateChangeSuccess', update);\n\t                    $scope.$on('$destroy', $transitions.onStart({}, function (trans) { return trans.promise.then(update) && null; }));\n\t                    function addState(stateName, stateParams, activeClass) {\n\t                        var state = $state.get(stateName, stateContext($element));\n\t                        var stateHash = createStateHash(stateName, stateParams);\n\t                        var stateInfo = {\n\t                            state: state || { name: stateName },\n\t                            params: stateParams,\n\t                            hash: stateHash\n\t                        };\n\t                        states.push(stateInfo);\n\t                        activeClasses[stateHash] = activeClass;\n\t                        return function removeState() {\n\t                            var idx = states.indexOf(stateInfo);\n\t                            if (idx !== -1)\n\t                                states.splice(idx, 1);\n\t                        };\n\t                    }\n\t                    /**\n\t                     * @param {string} state\n\t                     * @param {Object|string} [params]\n\t                     * @return {string}\n\t                     */\n\t                    function createStateHash(state, params) {\n\t                        if (!predicates_1.isString(state)) {\n\t                            throw new Error('state should be a string');\n\t                        }\n\t                        if (predicates_1.isObject(params)) {\n\t                            return state + common_1.toJson(params);\n\t                        }\n\t                        params = $scope.$eval(params);\n\t                        if (predicates_1.isObject(params)) {\n\t                            return state + common_1.toJson(params);\n\t                        }\n\t                        return state;\n\t                    }\n\t                    // Update route state\n\t                    function update() {\n\t                        for (var i = 0; i < states.length; i++) {\n\t                            if (anyMatch(states[i].state, states[i].params)) {\n\t                                addClass($element, activeClasses[states[i].hash]);\n\t                            }\n\t                            else {\n\t                                removeClass($element, activeClasses[states[i].hash]);\n\t                            }\n\t                            if (exactMatch(states[i].state, states[i].params)) {\n\t                                addClass($element, activeEqClass);\n\t                            }\n\t                            else {\n\t                                removeClass($element, activeEqClass);\n\t                            }\n\t                        }\n\t                    }\n\t                    function addClass(el, className) { $timeout(function () { el.addClass(className); }); }\n\t                    function removeClass(el, className) { el.removeClass(className); }\n\t                    function anyMatch(state, params) { return $state.includes(state.name, params); }\n\t                    function exactMatch(state, params) { return $state.is(state.name, params); }\n\t                    update();\n\t                }]\n\t        };\n\t    }];\n\tangular.module('ui.router.state')\n\t    .directive('uiSref', uiSref)\n\t    .directive('uiSrefActive', uiSrefActive)\n\t    .directive('uiSrefActiveEq', uiSrefActive)\n\t    .directive('uiState', uiState);\n\n\n/***/ },\n/* 59 */\n/***/ function(module, exports) {\n\n\t/** @module state */ /** for typedoc */\n\t\"use strict\";\n\t/**\n\t * @ngdoc filter\n\t * @name ui.router.state.filter:isState\n\t *\n\t * @requires ui.router.state.$state\n\t *\n\t * @description\n\t * Translates to {@link ui.router.state.$state#methods_is $state.is(\"stateName\")}.\n\t */\n\t$IsStateFilter.$inject = ['$state'];\n\tfunction $IsStateFilter($state) {\n\t    var isFilter = function (state, params, options) {\n\t        return $state.is(state, params, options);\n\t    };\n\t    isFilter.$stateful = true;\n\t    return isFilter;\n\t}\n\texports.$IsStateFilter = $IsStateFilter;\n\t/**\n\t * @ngdoc filter\n\t * @name ui.router.state.filter:includedByState\n\t *\n\t * @requires ui.router.state.$state\n\t *\n\t * @description\n\t * Translates to {@link ui.router.state.$state#methods_includes $state.includes('fullOrPartialStateName')}.\n\t */\n\t$IncludedByStateFilter.$inject = ['$state'];\n\tfunction $IncludedByStateFilter($state) {\n\t    var includesFilter = function (state, params, options) {\n\t        return $state.includes(state, params, options);\n\t    };\n\t    includesFilter.$stateful = true;\n\t    return includesFilter;\n\t}\n\texports.$IncludedByStateFilter = $IncludedByStateFilter;\n\tangular.module('ui.router.state')\n\t    .filter('isState', $IsStateFilter)\n\t    .filter('includedByState', $IncludedByStateFilter);\n\n\n/***/ },\n/* 60 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/** @module ng1_directives */ /** for typedoc */\n\t\"use strict\";\n\tvar common_1 = __webpack_require__(3);\n\tvar predicates_1 = __webpack_require__(4);\n\tvar trace_1 = __webpack_require__(12);\n\tvar views_1 = __webpack_require__(55);\n\tvar hof_1 = __webpack_require__(5);\n\tvar resolveContext_1 = __webpack_require__(17);\n\tvar strings_1 = __webpack_require__(9);\n\tvar services_1 = __webpack_require__(53);\n\t/**\n\t * `ui-view`: A viewport directive which is filled in by a view from the active state.\n\t *\n\t * @param {string=} name A view name. The name should be unique amongst the other views in the\n\t * same state. You can have views of the same name that live in different states.\n\t *\n\t * @param {string=} autoscroll It allows you to set the scroll behavior of the browser window\n\t * when a view is populated. By default, $anchorScroll is overridden by ui-router's custom scroll\n\t * service, {@link ui.router.state.$uiViewScroll}. This custom service let's you\n\t * scroll ui-view elements into view when they are populated during a state activation.\n\t *\n\t * *Note: To revert back to old [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll)\n\t * functionality, call `$uiViewScrollProvider.useAnchorScroll()`.*\n\t *\n\t * @param {string=} onload Expression to evaluate whenever the view updates.\n\t *\n\t * A view can be unnamed or named.\n\t * @example\n\t * ```html\n\t *\n\t * <!-- Unnamed -->\n\t * <div ui-view></div>\n\t *\n\t * <!-- Named -->\n\t * <div ui-view=\"viewName\"></div>\n\t * ```\n\t *\n\t * You can only have one unnamed view within any template (or root html). If you are only using a\n\t * single view and it is unnamed then you can populate it like so:\n\t * ```\n\t *\n\t * <div ui-view></div>\n\t * $stateProvider.state(\"home\", {\n\t *   template: \"<h1>HELLO!</h1>\"\n\t * })\n\t * ```\n\t *\n\t * The above is a convenient shortcut equivalent to specifying your view explicitly with the {@link ui.router.state.$stateProvider#views `views`}\n\t * config property, by name, in this case an empty name:\n\t * ```js\n\t *\n\t * $stateProvider.state(\"home\", {\n\t *   views: {\n\t *     \"\": {\n\t *       template: \"<h1>HELLO!</h1>\"\n\t *     }\n\t *   }\n\t * })\n\t * ```\n\t *\n\t * But typically you'll only use the views property if you name your view or have more than one view\n\t * in the same template. There's not really a compelling reason to name a view if its the only one,\n\t * but you could if you wanted, like so:\n\t *\n\t * ```html\n\t *\n\t * <div ui-view=\"main\"></div>\n\t * ```\n\t *\n\t * ```js\n\t *\n\t * $stateProvider.state(\"home\", {\n\t *   views: {\n\t *     \"main\": {\n\t *       template: \"<h1>HELLO!</h1>\"\n\t *     }\n\t *   }\n\t * })\n\t * ```\n\t *\n\t * Really though, you'll use views to set up multiple views:\n\t * ```html\n\t *\n\t * <div ui-view></div>\n\t * <div ui-view=\"chart\"></div>\n\t * <div ui-view=\"data\"></div>\n\t * ```\n\t *\n\t * ```js\n\t * $stateProvider.state(\"home\", {\n\t *   views: {\n\t *     \"\": {\n\t *       template: \"<h1>HELLO!</h1>\"\n\t *     },\n\t *     \"chart\": {\n\t *       template: \"<chart_thing/>\"\n\t *     },\n\t *     \"data\": {\n\t *       template: \"<data_thing/>\"\n\t *     }\n\t *   }\n\t * })\n\t * ```\n\t *\n\t * Examples for `autoscroll`:\n\t *\n\t * ```html\n\t *\n\t * <!-- If autoscroll present with no expression,\n\t *      then scroll ui-view into view -->\n\t * <ui-view autoscroll/>\n\t *\n\t * <!-- If autoscroll present with valid expression,\n\t *      then scroll ui-view into view if expression evaluates to true -->\n\t * <ui-view autoscroll='true'/>\n\t * <ui-view autoscroll='false'/>\n\t * <ui-view autoscroll='scopeVariable'/>\n\t * ```\n\t *\n\t * Resolve data:\n\t *\n\t * The resolved data from the state's `resolve` block is placed on the scope as `$resolve` (this\n\t * can be customized using [[ViewDeclaration.resolveAs]]).  This can be then accessed from the template.\n\t *\n\t * Note that when `controllerAs` is being used, `$resolve` is set on the controller instance *after* the\n\t * controller is instantiated.  The `$onInit()` hook can be used to perform initialization code which\n\t * depends on `$resolve` data.\n\t *\n\t * @example\n\t * ```js\n\t *\n\t * $stateProvider.state('home', {\n\t *   template: '<my-component user=\"$resolve.user\"></my-component>',\n\t *   resolve: {\n\t *     user: function(UserService) { return UserService.fetchUser(); }\n\t *   }\n\t * });\n\t * ```\n\t */\n\tvar uiView = ['$view', '$animate', '$uiViewScroll', '$interpolate', '$q',\n\t    function $ViewDirective($view, $animate, $uiViewScroll, $interpolate, $q) {\n\t        function getRenderer(attrs, scope) {\n\t            return {\n\t                enter: function (element, target, cb) {\n\t                    if (angular.version.minor > 2) {\n\t                        $animate.enter(element, null, target).then(cb);\n\t                    }\n\t                    else {\n\t                        $animate.enter(element, null, target, cb);\n\t                    }\n\t                },\n\t                leave: function (element, cb) {\n\t                    if (angular.version.minor > 2) {\n\t                        $animate.leave(element).then(cb);\n\t                    }\n\t                    else {\n\t                        $animate.leave(element, cb);\n\t                    }\n\t                }\n\t            };\n\t        }\n\t        function configsEqual(config1, config2) {\n\t            return config1 === config2;\n\t        }\n\t        var rootData = {\n\t            $cfg: { viewDecl: { $context: $view.rootContext() } },\n\t            $uiView: {}\n\t        };\n\t        var directive = {\n\t            count: 0,\n\t            restrict: 'ECA',\n\t            terminal: true,\n\t            priority: 400,\n\t            transclude: 'element',\n\t            compile: function (tElement, tAttrs, $transclude) {\n\t                return function (scope, $element, attrs) {\n\t                    var previousEl, currentEl, currentScope, unregister, onloadExp = attrs.onload || '', autoScrollExp = attrs.autoscroll, renderer = getRenderer(attrs, scope), viewConfig = undefined, inherited = $element.inheritedData('$uiView') || rootData, name = $interpolate(attrs.uiView || attrs.name || '')(scope) || '$default';\n\t                    var activeUIView = {\n\t                        $type: 'ng1',\n\t                        id: directive.count++,\n\t                        name: name,\n\t                        fqn: inherited.$uiView.fqn ? inherited.$uiView.fqn + \".\" + name : name,\n\t                        config: null,\n\t                        configUpdated: configUpdatedCallback,\n\t                        get creationContext() {\n\t                            return hof_1.parse('$cfg.viewDecl.$context')(inherited);\n\t                        }\n\t                    };\n\t                    trace_1.trace.traceUIViewEvent(\"Linking\", activeUIView);\n\t                    function configUpdatedCallback(config) {\n\t                        if (config && !(config instanceof views_1.Ng1ViewConfig))\n\t                            return;\n\t                        if (configsEqual(viewConfig, config))\n\t                            return;\n\t                        trace_1.trace.traceUIViewConfigUpdated(activeUIView, config && config.viewDecl && config.viewDecl.$context);\n\t                        viewConfig = config;\n\t                        updateView(config);\n\t                    }\n\t                    $element.data('$uiView', { $uiView: activeUIView });\n\t                    updateView();\n\t                    unregister = $view.registerUIView(activeUIView);\n\t                    scope.$on(\"$destroy\", function () {\n\t                        trace_1.trace.traceUIViewEvent(\"Destroying/Unregistering\", activeUIView);\n\t                        unregister();\n\t                    });\n\t                    function cleanupLastView() {\n\t                        if (previousEl) {\n\t                            trace_1.trace.traceUIViewEvent(\"Removing (previous) el\", previousEl.data('$uiView'));\n\t                            previousEl.remove();\n\t                            previousEl = null;\n\t                        }\n\t                        if (currentScope) {\n\t                            trace_1.trace.traceUIViewEvent(\"Destroying scope\", activeUIView);\n\t                            currentScope.$destroy();\n\t                            currentScope = null;\n\t                        }\n\t                        if (currentEl) {\n\t                            var _viewData_1 = currentEl.data('$uiView');\n\t                            trace_1.trace.traceUIViewEvent(\"Animate out\", _viewData_1);\n\t                            renderer.leave(currentEl, function () {\n\t                                _viewData_1.$$animLeave.resolve();\n\t                                previousEl = null;\n\t                            });\n\t                            previousEl = currentEl;\n\t                            currentEl = null;\n\t                        }\n\t                    }\n\t                    function updateView(config) {\n\t                        var newScope = scope.$new();\n\t                        trace_1.trace.traceUIViewScopeCreated(activeUIView, newScope);\n\t                        var animEnter = $q.defer(), animLeave = $q.defer();\n\t                        var $uiViewData = {\n\t                            $cfg: config,\n\t                            $uiView: activeUIView,\n\t                            $animEnter: animEnter.promise,\n\t                            $animLeave: animLeave.promise,\n\t                            $$animLeave: animLeave\n\t                        };\n\t                        var cloned = $transclude(newScope, function (clone) {\n\t                            renderer.enter(clone.data('$uiView', $uiViewData), $element, function onUIViewEnter() {\n\t                                animEnter.resolve();\n\t                                if (currentScope)\n\t                                    currentScope.$emit('$viewContentAnimationEnded');\n\t                                if (predicates_1.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) {\n\t                                    $uiViewScroll(clone);\n\t                                }\n\t                            });\n\t                            cleanupLastView();\n\t                        });\n\t                        currentEl = cloned;\n\t                        currentScope = newScope;\n\t                        /**\n\t                         * @ngdoc event\n\t                         * @name ui.router.state.directive:ui-view#$viewContentLoaded\n\t                         * @eventOf ui.router.state.directive:ui-view\n\t                         * @eventType emits on ui-view directive scope\n\t                         * @description           *\n\t                         * Fired once the view is **loaded**, *after* the DOM is rendered.\n\t                         *\n\t                         * @param {Object} event Event object.\n\t                         */\n\t                        currentScope.$emit('$viewContentLoaded', config || viewConfig);\n\t                        currentScope.$eval(onloadExp);\n\t                    }\n\t                };\n\t            }\n\t        };\n\t        return directive;\n\t    }];\n\t$ViewDirectiveFill.$inject = ['$compile', '$controller', '$transitions', '$view', '$timeout'];\n\t/** @hidden */\n\tfunction $ViewDirectiveFill($compile, $controller, $transitions, $view, $timeout) {\n\t    var getControllerAs = hof_1.parse('viewDecl.controllerAs');\n\t    var getResolveAs = hof_1.parse('viewDecl.resolveAs');\n\t    return {\n\t        restrict: 'ECA',\n\t        priority: -400,\n\t        compile: function (tElement) {\n\t            var initial = tElement.html();\n\t            return function (scope, $element) {\n\t                var data = $element.data('$uiView');\n\t                if (!data)\n\t                    return;\n\t                var cfg = data.$cfg || { viewDecl: {} };\n\t                $element.html(cfg.template || initial);\n\t                trace_1.trace.traceUIViewFill(data.$uiView, $element.html());\n\t                var link = $compile($element.contents());\n\t                var controller = cfg.controller;\n\t                var controllerAs = getControllerAs(cfg);\n\t                var resolveAs = getResolveAs(cfg);\n\t                var resolveCtx = cfg.path && new resolveContext_1.ResolveContext(cfg.path);\n\t                var locals = resolveCtx && services_1.getLocals(resolveCtx);\n\t                scope[resolveAs] = locals;\n\t                if (controller) {\n\t                    var controllerInstance = $controller(controller, common_1.extend({}, locals, { $scope: scope, $element: $element }));\n\t                    if (controllerAs) {\n\t                        scope[controllerAs] = controllerInstance;\n\t                        scope[controllerAs][resolveAs] = locals;\n\t                    }\n\t                    // TODO: Use $view service as a central point for registering component-level hooks\n\t                    // Then, when a component is created, tell the $view service, so it can invoke hooks\n\t                    // $view.componentLoaded(controllerInstance, { $scope: scope, $element: $element });\n\t                    // scope.$on('$destroy', () => $view.componentUnloaded(controllerInstance, { $scope: scope, $element: $element }));\n\t                    $element.data('$ngControllerController', controllerInstance);\n\t                    $element.children().data('$ngControllerController', controllerInstance);\n\t                    registerControllerCallbacks($transitions, controllerInstance, scope, cfg);\n\t                }\n\t                // Wait for the component to appear in the DOM\n\t                if (predicates_1.isString(cfg.viewDecl.component)) {\n\t                    var cmp_1 = cfg.viewDecl.component;\n\t                    var kebobName_1 = strings_1.kebobString(cmp_1);\n\t                    var getComponentController = function () {\n\t                        var directiveEl = [].slice.call($element[0].children)\n\t                            .filter(function (el) { return el && el.tagName && el.tagName.toLowerCase() === kebobName_1; });\n\t                        return directiveEl && angular.element(directiveEl).data(\"$\" + cmp_1 + \"Controller\");\n\t                    };\n\t                    var deregisterWatch_1 = scope.$watch(getComponentController, function (ctrlInstance) {\n\t                        if (!ctrlInstance)\n\t                            return;\n\t                        registerControllerCallbacks($transitions, ctrlInstance, scope, cfg);\n\t                        deregisterWatch_1();\n\t                    });\n\t                }\n\t                link(scope);\n\t            };\n\t        }\n\t    };\n\t}\n\t/** @hidden */\n\tvar hasComponentImpl = typeof angular.module('ui.router')['component'] === 'function';\n\t/** @hidden TODO: move these callbacks to $view and/or `/hooks/components.ts` or something */\n\tfunction registerControllerCallbacks($transitions, controllerInstance, $scope, cfg) {\n\t    // Call $onInit() ASAP\n\t    if (predicates_1.isFunction(controllerInstance.$onInit) && !(cfg.viewDecl.component && hasComponentImpl))\n\t        controllerInstance.$onInit();\n\t    var viewState = common_1.tail(cfg.path).state.self;\n\t    var hookOptions = { bind: controllerInstance };\n\t    // Add component-level hook for onParamsChange\n\t    if (predicates_1.isFunction(controllerInstance.uiOnParamsChanged)) {\n\t        var resolveContext = new resolveContext_1.ResolveContext(cfg.path);\n\t        var viewCreationTrans_1 = resolveContext.getResolvable('$transition$').data;\n\t        // Fire callback on any successful transition\n\t        var paramsUpdated = function ($transition$) {\n\t            // Exit early if the $transition$ is the same as the view was created within.\n\t            // Exit early if the $transition$ will exit the state the view is for.\n\t            if ($transition$ === viewCreationTrans_1 || $transition$.exiting().indexOf(viewState) !== -1)\n\t                return;\n\t            var toParams = $transition$.params(\"to\");\n\t            var fromParams = $transition$.params(\"from\");\n\t            var toSchema = $transition$.treeChanges().to.map(function (node) { return node.paramSchema; }).reduce(common_1.unnestR, []);\n\t            var fromSchema = $transition$.treeChanges().from.map(function (node) { return node.paramSchema; }).reduce(common_1.unnestR, []);\n\t            // Find the to params that have different values than the from params\n\t            var changedToParams = toSchema.filter(function (param) {\n\t                var idx = fromSchema.indexOf(param);\n\t                return idx === -1 || !fromSchema[idx].type.equals(toParams[param.id], fromParams[param.id]);\n\t            });\n\t            // Only trigger callback if a to param has changed or is new\n\t            if (changedToParams.length) {\n\t                var changedKeys_1 = changedToParams.map(function (x) { return x.id; });\n\t                // Filter the params to only changed/new to params.  `$transition$.params()` may be used to get all params.\n\t                controllerInstance.uiOnParamsChanged(common_1.filter(toParams, function (val, key) { return changedKeys_1.indexOf(key) !== -1; }), $transition$);\n\t            }\n\t        };\n\t        $scope.$on('$destroy', $transitions.onSuccess({}, paramsUpdated, hookOptions));\n\t    }\n\t    // Add component-level hook for uiCanExit\n\t    if (predicates_1.isFunction(controllerInstance.uiCanExit)) {\n\t        var criteria = { exiting: viewState.name };\n\t        $scope.$on('$destroy', $transitions.onBefore(criteria, controllerInstance.uiCanExit, hookOptions));\n\t    }\n\t}\n\tangular.module('ui.router.state').directive('uiView', uiView);\n\tangular.module('ui.router.state').directive('uiView', $ViewDirectiveFill);\n\n\n/***/ },\n/* 61 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t/**\n\t * @ngdoc object\n\t * @name ui.router.state.$uiViewScrollProvider\n\t *\n\t * @description\n\t * Provider that returns the {@link ui.router.state.$uiViewScroll} service function.\n\t */\n\tfunction $ViewScrollProvider() {\n\t    var useAnchorScroll = false;\n\t    /**\n\t     * @ngdoc function\n\t     * @name ui.router.state.$uiViewScrollProvider#useAnchorScroll\n\t     * @methodOf ui.router.state.$uiViewScrollProvider\n\t     *\n\t     * @description\n\t     * Reverts back to using the core [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll) service for\n\t     * scrolling based on the url anchor.\n\t     */\n\t    this.useAnchorScroll = function () {\n\t        useAnchorScroll = true;\n\t    };\n\t    /**\n\t     * @ngdoc object\n\t     * @name ui.router.state.$uiViewScroll\n\t     *\n\t     * @requires $anchorScroll\n\t     * @requires $timeout\n\t     *\n\t     * @description\n\t     * When called with a jqLite element, it scrolls the element into view (after a\n\t     * `$timeout` so the DOM has time to refresh).\n\t     *\n\t     * If you prefer to rely on `$anchorScroll` to scroll the view to the anchor,\n\t     * this can be enabled by calling {@link ui.router.state.$uiViewScrollProvider#methods_useAnchorScroll `$uiViewScrollProvider.useAnchorScroll()`}.\n\t     */\n\t    this.$get = ['$anchorScroll', '$timeout', function ($anchorScroll, $timeout) {\n\t            if (useAnchorScroll) {\n\t                return $anchorScroll;\n\t            }\n\t            return function ($element) {\n\t                return $timeout(function () {\n\t                    $element[0].scrollIntoView();\n\t                }, 0, false);\n\t            };\n\t        }];\n\t}\n\tangular.module('ui.router.state').provider('$uiViewScroll', $ViewScrollProvider);\n\n\n/***/ }\n/******/ ])\n});\n;\n//# sourceMappingURL=angular-ui-router.js.map\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-ui-router/release/angular-ui-router.js\n// module id = 3\n// module chunks = 0","\n/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nlet self;\n\nclass ElineSide {\n\n  static $inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr'];\n\n  constructor(\n    private XosSidePanel: any,\n    private XosModelStore: any,\n    private $http: any,\n    private $log: any,\n    private toastr: any,\n  ) {\n    self = this;\n  }\n\n  public saveEline(item: any) {\n    let path = item.path;\n    delete item.path;\n    item.$save().then((res) => {\n      item.path = path;\n      this.toastr.success(`${item.name} successfully saved!`);\n    })\n      .catch((error) => {\n        this.toastr.error(`Error while saving ${item.name}: ${error.specific_error}`);\n      });\n  }\n\n  public deleteEline(item: any) {\n    let name = item.name;\n    item.$delete().then((res) => {\n      this.toastr.success(`${name} successfully deleted!`);\n    })\n    .catch((error) => {\n        this.toastr.error(`Error while deleting ${name}: ${error.specific_error}`);\n      });\n  }\n\n\n}\n\nexport const elineSide: angular.IComponentOptions = {\n  template: require('./eline-side.component.html'),\n  controllerAs: 'vm',\n  controller: ElineSide,\n  bindings: {\n    eng: '='\n  }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./~/tslint-loader!./src/app/components/eline-side.component.ts","/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\"use strict\";\nexports.__esModule = true;\nvar self;\nvar ElineSide = (function () {\n    function ElineSide(XosSidePanel, XosModelStore, $http, $log, toastr) {\n        this.XosSidePanel = XosSidePanel;\n        this.XosModelStore = XosModelStore;\n        this.$http = $http;\n        this.$log = $log;\n        this.toastr = toastr;\n        self = this;\n    }\n    ElineSide.prototype.saveEline = function (item) {\n        var _this = this;\n        var path = item.path;\n        delete item.path;\n        item.$save().then(function (res) {\n            item.path = path;\n            _this.toastr.success(item.name + \" successfully saved!\");\n        })[\"catch\"](function (error) {\n            _this.toastr.error(\"Error while saving \" + item.name + \": \" + error.specific_error);\n        });\n    };\n    ElineSide.prototype.deleteEline = function (item) {\n        var _this = this;\n        var name = item.name;\n        item.$delete().then(function (res) {\n            _this.toastr.success(name + \" successfully deleted!\");\n        })[\"catch\"](function (error) {\n            _this.toastr.error(\"Error while deleting \" + name + \": \" + error.specific_error);\n        });\n    };\n    return ElineSide;\n}());\nElineSide.$inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr'];\nexports.elineSide = {\n    template: require('./eline-side.component.html'),\n    controllerAs: 'vm',\n    controller: ElineSide,\n    bindings: {\n        eng: '='\n    }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/components/eline-side.component.ts","\n/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nimport {NgMap} from 'ngmap';\nimport {Subscription} from 'rxjs/Subscription';\nimport * as _ from 'lodash';\n\ndeclare var google;\n\nlet self;\n\nexport class EngMap {\n\n  static $inject = [\n    'NgMap',\n    'XosModelStore',\n    'AppConfig',\n    '$resource',\n    'XosSidePanel',\n    'XosModelDiscoverer',\n    'ModelRest',\n    'MapConfig',\n  ];\n\n  public unis = [];\n  public elines = [];\n  public cpilatlng = new Map();\n  public paths = [];\n  public bwps = [];\n  public map;\n  public panelOpen = false;\n  public createMode = false;\n  public canCreateEline = true;\n  public eline;\n  public current_uni;\n  public mapStyles = [{'featureType': 'administrative', 'elementType': 'labels.text.fill', 'stylers': [{'color': '#444444'}]}, {'featureType': 'landscape', 'elementType': 'all', 'stylers': [{'color': '#f2f2f2'}]}, {'featureType': 'poi', 'elementType': 'all', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'road', 'elementType': 'all', 'stylers': [{'saturation': -100}, {'lightness': 45}]}, {'featureType': 'road.highway', 'elementType': 'all', 'stylers': [{'visibility': 'simplified'}]}, {'featureType': 'road.arterial', 'elementType': 'labels.icon', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'transit', 'elementType': 'all', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'water', 'elementType': 'all', 'stylers': [{'color': '#9ce1fc'}, {'visibility': 'on'}]}];\n\n  private uniSubscription: Subscription;\n  private elineSubscription: Subscription;\n  private bwpSubscription: Subscription;\n\n  constructor(\n    private NgMap: any,\n    private XosModelStore: any,\n    private AppConfig: any,\n    private $resource: any,\n    private XosSidePanel: any,\n    private XosModelDiscoverer: any,\n    private ModelRest: any,\n    private MapConfig: any,\n  ) {\n    self = this;\n  }\n\n  $onInit() {\n    this.NgMap.getMap().then(map => {\n      this.map = map;\n      this.uniSubscription = this.XosModelStore.query('UserNetworkInterface', '/vnaas/usernetworkinterfaces/').subscribe(\n        res => {\n          this.unis = res;\n          this.renderMap(map);\n        }\n      );\n      this.elineSubscription = this.XosModelStore.query('ELine', '/vnaas/elines/').subscribe(\n        res => {\n          this.elines = res;\n          this.createPaths();\n          this.renderMap(map);\n        }\n      );\n      this.bwpSubscription = this.XosModelStore.query('BandwidthProfile', '/vnaas/bandwidthprofiles/').subscribe(\n        res => {\n          this.bwps = res;\n        }\n      );\n    });\n  }\n\n  $onDestroy() {\n    if (this.uniSubscription) {\n      this.uniSubscription.unsubscribe();\n    }\n  }\n\n  public renderMap(map: NgMap) {\n\n    let bounds = new google.maps.LatLngBounds();\n\n    for (let i = 0; i < self.unis.length; i++) {\n      self.unis[i].eline_start = false;\n      let curr = JSON.parse(self.unis[i].latlng);\n      this.cpilatlng.set(self.unis[i].cpe_id, curr);\n      let latlng = new google.maps.LatLng(curr[0], curr[1]);\n      bounds.extend(latlng);\n    }\n    map.setCenter(bounds.getCenter());\n    map.fitBounds(bounds);\n\n  }\n\n  public createPaths() {\n    this.elines.forEach((eline: any) => {\n      let latlng_start = this.cpilatlng.get(eline.connect_point_1_id);\n      let latlng_end = this.cpilatlng.get(eline.connect_point_2_id);\n      eline.path = [latlng_start, latlng_end];\n    });\n\n  }\n\n  public colorLine(eline_status : any) {\n    let status = parseInt(eline_status, 10);\n    switch (status) {\n      case 0:\n        return '#f39c12';\n      case 1:\n        return '#2ecc71';\n      default:\n        return '#e74c3c';\n    }\n\n  }\n\n  public showUni(e: any, uni: any) {\n    self.current_uni = uni;\n    self.map.showInfoWindow('uni-info', this);\n  }\n\n  // do not display backend status or ID in create mode\n\n  public elinePanel(e: any, eline: any, exists: boolean) {\n    self.panelOpen = !self.panelOpen;\n    if (exists) {\n      self.eline = _.find(self.elines, {id: eline.id});\n    }\n    self.XosSidePanel.toggleComponent('elineSide', {eline: self.eline, bwplist: self.bwps, eng: self}, false);\n    if (!self.panelOpen && self.createMode) {\n      self.createMode = false;\n      self.canCreateEline = true;\n      self.current_uni.eline_start = false;\n    }\n\n  }\n\n  public createConnection(uni: any) {\n    return () => {\n      self.canCreateEline = false;\n      self.createMode = true;\n      uni.eline_start = true;\n      self.current_uni = uni;\n      self.eline = {\n        name: uni.name,\n        uni1name: uni.name,\n        connect_point_1_id: uni.cpe_id,\n      };\n      self.elinePanel({}, self.eline, false);\n    };\n\n  }\n\n  public finishConnection(uni: any) {\n    self.eline.connect_point_2_id = uni.cpe_id;\n    if (self.eline.name === self.eline.uni1name) {\n      self.eline.name = self.eline.name + uni.name;\n    }\n    delete self.eline.uni1name;\n    const resource = this.ModelRest.getResource('/vnaas/elines/');\n    let res = new resource({});\n    for (let attr in self.eline) {\n      if (true) {\n        res[attr] = self.eline[attr];\n      }\n\n    }\n    self.eline = res;\n  }\n\n}\n\nexport const engMap: angular.IComponentOptions = {\n  template: require('./engMap.component.html'),\n  controllerAs: 'vm',\n  controller: EngMap,\n};\n\n\n\n// WEBPACK FOOTER //\n// ./~/tslint-loader!./src/app/components/engMap.component.ts","/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\"use strict\";\nexports.__esModule = true;\nvar _ = require(\"lodash\");\nvar self;\nvar EngMap = (function () {\n    function EngMap(NgMap, XosModelStore, AppConfig, $resource, XosSidePanel, XosModelDiscoverer, ModelRest, MapConfig) {\n        this.NgMap = NgMap;\n        this.XosModelStore = XosModelStore;\n        this.AppConfig = AppConfig;\n        this.$resource = $resource;\n        this.XosSidePanel = XosSidePanel;\n        this.XosModelDiscoverer = XosModelDiscoverer;\n        this.ModelRest = ModelRest;\n        this.MapConfig = MapConfig;\n        this.unis = [];\n        this.elines = [];\n        this.cpilatlng = new Map();\n        this.paths = [];\n        this.bwps = [];\n        this.panelOpen = false;\n        this.createMode = false;\n        this.canCreateEline = true;\n        this.mapStyles = [{ 'featureType': 'administrative', 'elementType': 'labels.text.fill', 'stylers': [{ 'color': '#444444' }] }, { 'featureType': 'landscape', 'elementType': 'all', 'stylers': [{ 'color': '#f2f2f2' }] }, { 'featureType': 'poi', 'elementType': 'all', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'road', 'elementType': 'all', 'stylers': [{ 'saturation': -100 }, { 'lightness': 45 }] }, { 'featureType': 'road.highway', 'elementType': 'all', 'stylers': [{ 'visibility': 'simplified' }] }, { 'featureType': 'road.arterial', 'elementType': 'labels.icon', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'transit', 'elementType': 'all', 'stylers': [{ 'visibility': 'off' }] }, { 'featureType': 'water', 'elementType': 'all', 'stylers': [{ 'color': '#9ce1fc' }, { 'visibility': 'on' }] }];\n        self = this;\n    }\n    EngMap.prototype.$onInit = function () {\n        var _this = this;\n        this.NgMap.getMap().then(function (map) {\n            _this.map = map;\n            _this.uniSubscription = _this.XosModelStore.query('UserNetworkInterface', '/vnaas/usernetworkinterfaces/').subscribe(function (res) {\n                _this.unis = res;\n                _this.renderMap(map);\n            });\n            _this.elineSubscription = _this.XosModelStore.query('ELine', '/vnaas/elines/').subscribe(function (res) {\n                _this.elines = res;\n                _this.createPaths();\n                _this.renderMap(map);\n            });\n            _this.bwpSubscription = _this.XosModelStore.query('BandwidthProfile', '/vnaas/bandwidthprofiles/').subscribe(function (res) {\n                _this.bwps = res;\n            });\n        });\n    };\n    EngMap.prototype.$onDestroy = function () {\n        if (this.uniSubscription) {\n            this.uniSubscription.unsubscribe();\n        }\n    };\n    EngMap.prototype.renderMap = function (map) {\n        var bounds = new google.maps.LatLngBounds();\n        for (var i = 0; i < self.unis.length; i++) {\n            self.unis[i].eline_start = false;\n            var curr = JSON.parse(self.unis[i].latlng);\n            this.cpilatlng.set(self.unis[i].cpe_id, curr);\n            var latlng = new google.maps.LatLng(curr[0], curr[1]);\n            bounds.extend(latlng);\n        }\n        map.setCenter(bounds.getCenter());\n        map.fitBounds(bounds);\n    };\n    EngMap.prototype.createPaths = function () {\n        var _this = this;\n        this.elines.forEach(function (eline) {\n            var latlng_start = _this.cpilatlng.get(eline.connect_point_1_id);\n            var latlng_end = _this.cpilatlng.get(eline.connect_point_2_id);\n            eline.path = [latlng_start, latlng_end];\n        });\n    };\n    EngMap.prototype.colorLine = function (eline_status) {\n        var status = parseInt(eline_status, 10);\n        switch (status) {\n            case 0:\n                return '#f39c12';\n            case 1:\n                return '#2ecc71';\n            default:\n                return '#e74c3c';\n        }\n    };\n    EngMap.prototype.showUni = function (e, uni) {\n        self.current_uni = uni;\n        self.map.showInfoWindow('uni-info', this);\n    };\n    // do not display backend status or ID in create mode\n    EngMap.prototype.elinePanel = function (e, eline, exists) {\n        self.panelOpen = !self.panelOpen;\n        if (exists) {\n            self.eline = _.find(self.elines, { id: eline.id });\n        }\n        self.XosSidePanel.toggleComponent('elineSide', { eline: self.eline, bwplist: self.bwps, eng: self }, false);\n        if (!self.panelOpen && self.createMode) {\n            self.createMode = false;\n            self.canCreateEline = true;\n            self.current_uni.eline_start = false;\n        }\n    };\n    EngMap.prototype.createConnection = function (uni) {\n        return function () {\n            self.canCreateEline = false;\n            self.createMode = true;\n            uni.eline_start = true;\n            self.current_uni = uni;\n            self.eline = {\n                name: uni.name,\n                uni1name: uni.name,\n                connect_point_1_id: uni.cpe_id\n            };\n            self.elinePanel({}, self.eline, false);\n        };\n    };\n    EngMap.prototype.finishConnection = function (uni) {\n        self.eline.connect_point_2_id = uni.cpe_id;\n        if (self.eline.name === self.eline.uni1name) {\n            self.eline.name = self.eline.name + uni.name;\n        }\n        delete self.eline.uni1name;\n        var resource = this.ModelRest.getResource('/vnaas/elines/');\n        var res = new resource({});\n        for (var attr in self.eline) {\n            if (true) {\n                res[attr] = self.eline[attr];\n            }\n        }\n        self.eline = res;\n    };\n    return EngMap;\n}());\nEngMap.$inject = [\n    'NgMap',\n    'XosModelStore',\n    'AppConfig',\n    '$resource',\n    'XosSidePanel',\n    'XosModelDiscoverer',\n    'ModelRest',\n    'MapConfig',\n];\nexports.EngMap = EngMap;\nexports.engMap = {\n    template: require('./engMap.component.html'),\n    controllerAs: 'vm',\n    controller: EngMap\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/components/engMap.component.ts","\n/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nexport default routesConfig;\n\nfunction routesConfig($stateProvider: angular.ui.IStateProvider, $locationProvider: angular.ILocationProvider) {\n  $locationProvider.html5Mode(false).hashPrefix('');\n\n  $stateProvider\n    .state('xos.vnaasgui', {\n      url: 'vnaasgui',\n      parent: 'xos',\n      component: 'engMap'\n    });\n}\n\n\n\n// WEBPACK FOOTER //\n// ./~/tslint-loader!./src/routes.ts","/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\"use strict\";\nexports.__esModule = true;\nexports[\"default\"] = routesConfig;\nfunction routesConfig($stateProvider, $locationProvider) {\n    $locationProvider.html5Mode(false).hashPrefix('');\n    $stateProvider\n        .state('xos.vnaasgui', {\n        url: 'vnaasgui',\n        parent: 'xos',\n        component: 'engMap'\n    });\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/routes.ts","(function(root, factory) {\r\nif (typeof exports === \"object\") {\r\nmodule.exports = factory(require('angular'));\r\n} else if (typeof define === \"function\" && define.amd) {\r\ndefine(['angular'], factory);\r\n} else{\r\nfactory(root.angular);\r\n}\r\n}(this, function(angular) {\r\n/**\n * AngularJS Google Maps Ver. 1.18.3\n *\n * The MIT License (MIT)\n * \n * Copyright (c) 2014, 2015, 1016 Allen Kim\n * \n * Permission is hereby granted, free of charge, to any person obtaining a copy of\n * this software and associated documentation files (the \"Software\"), to deal in\n * the Software without restriction, including without limitation the rights to\n * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n * the Software, and to permit persons to whom the Software is furnished to do so,\n * subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\nangular.module('ngMap', []);\n\n/**\n * @ngdoc controller\n * @name MapController\n */\n(function() {\n  'use strict';\n  var Attr2MapOptions;\n\n  var __MapController = function(\n      $scope, $element, $attrs, $parse, $interpolate, _Attr2MapOptions_, NgMap, NgMapPool, escapeRegExp\n    ) {\n    Attr2MapOptions = _Attr2MapOptions_;\n    var vm = this;\n    var exprStartSymbol = $interpolate.startSymbol();\n    var exprEndSymbol = $interpolate.endSymbol();\n\n    vm.mapOptions; /** @memberof __MapController */\n    vm.mapEvents;  /** @memberof __MapController */\n    vm.eventListeners;  /** @memberof __MapController */\n\n    /**\n     * Add an object to the collection of group\n     * @memberof __MapController\n     * @function addObject\n     * @param groupName the name of collection that object belongs to\n     * @param obj  an object to add into a collection, i.e. marker, shape\n     */\n    vm.addObject = function(groupName, obj) {\n      if (vm.map) {\n        vm.map[groupName] = vm.map[groupName] || {};\n        var len = Object.keys(vm.map[groupName]).length;\n        vm.map[groupName][obj.id || len] = obj;\n\n        if (vm.map instanceof google.maps.Map) {\n          //infoWindow.setMap works like infoWindow.open\n          if (groupName != \"infoWindows\" && obj.setMap) {\n            obj.setMap && obj.setMap(vm.map);\n          }\n          if (obj.centered && obj.position) {\n            vm.map.setCenter(obj.position);\n          }\n          (groupName == 'markers') && vm.objectChanged('markers');\n          (groupName == 'customMarkers') && vm.objectChanged('customMarkers');\n        }\n      }\n    };\n\n    /**\n     * Delete an object from the collection and remove from map\n     * @memberof __MapController\n     * @function deleteObject\n     * @param {Array} objs the collection of objects. i.e., map.markers\n     * @param {Object} obj the object to be removed. i.e., marker\n     */\n    vm.deleteObject = function(groupName, obj) {\n      /* delete from group */\n      if (obj.map) {\n        var objs = obj.map[groupName];\n        for (var name in objs) {\n          if (objs[name] === obj) {\n            void 0;\n            google.maps.event.clearInstanceListeners(obj);\n            delete objs[name];\n          }\n        }\n\n        /* delete from map */\n        obj.map && obj.setMap && obj.setMap(null);\n\n        (groupName == 'markers') && vm.objectChanged('markers');\n        (groupName == 'customMarkers') && vm.objectChanged('customMarkers');\n      }\n    };\n\n    /**\n     * @memberof __MapController\n     * @function observeAttrSetObj\n     * @param {Hash} orgAttrs attributes before its initialization\n     * @param {Hash} attrs    attributes after its initialization\n     * @param {Object} obj    map object that an action is to be done\n     * @description watch changes of attribute values and\n     * do appropriate action based on attribute name\n     */\n    vm.observeAttrSetObj = function(orgAttrs, attrs, obj) {\n      if (attrs.noWatcher) {\n        return false;\n      }\n      var attrsToObserve = Attr2MapOptions.getAttrsToObserve(orgAttrs);\n      for (var i=0; i<attrsToObserve.length; i++) {\n        var attrName = attrsToObserve[i];\n        attrs.$observe(attrName, NgMap.observeAndSet(attrName, obj));\n      }\n    };\n\n    /**\n     * @memberof __MapController\n     * @function zoomToIncludeMarkers\n     */\n    vm.zoomToIncludeMarkers = function() {\n      // Only fit to bounds if we have any markers\n      // object.keys is supported in all major browsers (IE9+)\n      if ((vm.map.markers != null && Object.keys(vm.map.markers).length > 0) || (vm.map.customMarkers != null && Object.keys(vm.map.customMarkers).length > 0)) {\n        var bounds = new google.maps.LatLngBounds();\n        for (var k1 in vm.map.markers) {\n          bounds.extend(vm.map.markers[k1].getPosition());\n        }\n        for (var k2 in vm.map.customMarkers) {\n          bounds.extend(vm.map.customMarkers[k2].getPosition());\n        }\n    \t  if (vm.mapOptions.maximumZoom) {\n    \t\t  vm.enableMaximumZoomCheck = true; //enable zoom check after resizing for markers\n    \t  }\n        vm.map.fitBounds(bounds);\n      }\n    };\n\n    /**\n     * @memberof __MapController\n     * @function objectChanged\n     * @param {String} group name of group e.g., markers\n     */\n    vm.objectChanged = function(group) {\n      if ( vm.map &&\n        (group == 'markers' || group == 'customMarkers') &&\n        vm.map.zoomToIncludeMarkers == 'auto'\n      ) {\n        vm.zoomToIncludeMarkers();\n      }\n    };\n\n    /**\n     * @memberof __MapController\n     * @function initializeMap\n     * @description\n     *  . initialize Google map on <div> tag\n     *  . set map options, events, and observers\n     *  . reset zoom to include all (custom)markers\n     */\n    vm.initializeMap = function() {\n      var mapOptions = vm.mapOptions,\n          mapEvents = vm.mapEvents;\n\n      var lazyInitMap = vm.map; //prepared for lazy init\n      vm.map = NgMapPool.getMapInstance($element[0]);\n      NgMap.setStyle($element[0]);\n\n      // set objects for lazyInit\n      if (lazyInitMap) {\n\n        /**\n         * rebuild mapOptions for lazyInit\n         * because attributes values might have been changed\n         */\n        var filtered = Attr2MapOptions.filter($attrs);\n        var options = Attr2MapOptions.getOptions(filtered);\n        var controlOptions = Attr2MapOptions.getControlOptions(filtered);\n        mapOptions = angular.extend(options, controlOptions);\n        void 0;\n\n        for (var group in lazyInitMap) {\n          var groupMembers = lazyInitMap[group]; //e.g. markers\n          if (typeof groupMembers == 'object') {\n            for (var id in groupMembers) {\n              vm.addObject(group, groupMembers[id]);\n            }\n          }\n        }\n        vm.map.showInfoWindow = vm.showInfoWindow;\n        vm.map.hideInfoWindow = vm.hideInfoWindow;\n      }\n\n      // set options\n      mapOptions.zoom = mapOptions.zoom || 15;\n      var center = mapOptions.center;\n      var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '.*' + escapeRegExp(exprEndSymbol));\n\n      if (!mapOptions.center ||\n        ((typeof center === 'string') && center.match(exprRegExp))\n      ) {\n        mapOptions.center = new google.maps.LatLng(0, 0);\n      } else if( (typeof center === 'string') && center.match(/^[0-9.-]*,[0-9.-]*$/) ){\n        var lat = parseFloat(center.split(',')[0]);\n        var lng = parseFloat(center.split(',')[1]);\n        mapOptions.center = new google.maps.LatLng(lat, lng);\n      } else if (!(center instanceof google.maps.LatLng)) {\n        var geoCenter = mapOptions.center;\n        delete mapOptions.center;\n        NgMap.getGeoLocation(geoCenter, mapOptions.geoLocationOptions).\n          then(function (latlng) {\n            vm.map.setCenter(latlng);\n            var geoCallback = mapOptions.geoCallback;\n            geoCallback && $parse(geoCallback)($scope);\n          }, function () {\n            if (mapOptions.geoFallbackCenter) {\n              vm.map.setCenter(mapOptions.geoFallbackCenter);\n            }\n          });\n      }\n      vm.map.setOptions(mapOptions);\n\n      // set events\n      for (var eventName in mapEvents) {\n        var event = mapEvents[eventName];\n        var listener = google.maps.event.addListener(vm.map, eventName, event);\n        vm.eventListeners[eventName] = listener;\n      }\n\n      // set observers\n      vm.observeAttrSetObj(orgAttrs, $attrs, vm.map);\n      vm.singleInfoWindow = mapOptions.singleInfoWindow;\n\n      google.maps.event.trigger(vm.map, 'resize');\n\n      google.maps.event.addListenerOnce(vm.map, \"idle\", function () {\n        NgMap.addMap(vm);\n        if (mapOptions.zoomToIncludeMarkers) {\n          vm.zoomToIncludeMarkers();\n        }\n        //TODO: it's for backward compatibiliy. will be removed\n        $scope.map = vm.map;\n        $scope.$emit('mapInitialized', vm.map);\n\n        //callback\n        if ($attrs.mapInitialized) {\n          $parse($attrs.mapInitialized)($scope, {map: vm.map});\n        }\n      });\n\n\t  //add maximum zoom listeners if zoom-to-include-markers and and maximum-zoom are valid attributes\n\t  if (mapOptions.zoomToIncludeMarkers && mapOptions.maximumZoom) {\n\t    google.maps.event.addListener(vm.map, 'zoom_changed', function() {\n          if (vm.enableMaximumZoomCheck == true) {\n\t\t\tvm.enableMaximumZoomCheck = false;\n\t        google.maps.event.addListenerOnce(vm.map, 'bounds_changed', function() {\n\t\t      vm.map.setZoom(Math.min(mapOptions.maximumZoom, vm.map.getZoom()));\n\t\t    });\n\t  \t  }\n\t    });\n\t  }\n    };\n\n    $scope.google = google; //used by $scope.eval to avoid eval()\n\n    /**\n     * get map options and events\n     */\n    var orgAttrs = Attr2MapOptions.orgAttributes($element);\n    var filtered = Attr2MapOptions.filter($attrs);\n    var options = Attr2MapOptions.getOptions(filtered, {scope: $scope});\n    var controlOptions = Attr2MapOptions.getControlOptions(filtered);\n    var mapOptions = angular.extend(options, controlOptions);\n    var mapEvents = Attr2MapOptions.getEvents($scope, filtered);\n    void 0;\n    Object.keys(mapEvents).length && void 0;\n\n    vm.mapOptions = mapOptions;\n    vm.mapEvents = mapEvents;\n    vm.eventListeners = {};\n\n    if (options.lazyInit) { // allows controlled initialization\n      // parse angular expression for dynamic ids\n      if (!!$attrs.id &&\n      \t  // starts with, at position 0\n\t  $attrs.id.indexOf(exprStartSymbol, 0) === 0 &&\n\t  // ends with\n\t  $attrs.id.indexOf(exprEndSymbol, $attrs.id.length - exprEndSymbol.length) !== -1) {\n        var idExpression = $attrs.id.slice(2,-2);\n        var mapId = $parse(idExpression)($scope);\n      } else {\n        var mapId = $attrs.id;\n      }\n      vm.map = {id: mapId}; //set empty, not real, map\n      NgMap.addMap(vm);\n    } else {\n      vm.initializeMap();\n    }\n\n    //Trigger Resize\n    if(options.triggerResize) {\n      google.maps.event.trigger(vm.map, 'resize');\n    }\n\n    $element.bind('$destroy', function() {\n      NgMapPool.returnMapInstance(vm.map);\n      NgMap.deleteMap(vm);\n    });\n  }; // __MapController\n\n  __MapController.$inject = [\n    '$scope', '$element', '$attrs', '$parse', '$interpolate', 'Attr2MapOptions', 'NgMap', 'NgMapPool', 'escapeRegexpFilter'\n  ];\n  angular.module('ngMap').controller('__MapController', __MapController);\n})();\n\n/**\n * @ngdoc directive\n * @name bicycling-layer\n * @param Attr2Options {service}\n *   convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n *\n *   <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *     <bicycling-layer></bicycling-layer>\n *    </map>\n */\n(function() {\n  'use strict';\n  var parser;\n\n  var linkFunc = function(scope, element, attrs, mapController) {\n    mapController = mapController[0]||mapController[1];\n    var orgAttrs = parser.orgAttributes(element);\n    var filtered = parser.filter(attrs);\n    var options = parser.getOptions(filtered, {scope: scope});\n    var events = parser.getEvents(scope, filtered);\n\n    void 0;\n\n    var layer = getLayer(options, events);\n    mapController.addObject('bicyclingLayers', layer);\n    mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers\n    element.bind('$destroy', function() {\n      mapController.deleteObject('bicyclingLayers', layer);\n    });\n  };\n\n  var getLayer = function(options, events) {\n    var layer = new google.maps.BicyclingLayer(options);\n    for (var eventName in events) {\n      google.maps.event.addListener(layer, eventName, events[eventName]);\n    }\n    return layer;\n  };\n\n  var bicyclingLayer= function(Attr2MapOptions) {\n    parser = Attr2MapOptions;\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n     };\n  };\n  bicyclingLayer.$inject = ['Attr2MapOptions'];\n\n  angular.module('ngMap').directive('bicyclingLayer', bicyclingLayer);\n})();\n\n/**\n * @ngdoc directive\n * @name custom-control\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @param $compile {service} AngularJS $compile service\n * @description\n *   Build custom control and set to the map with position\n *\n *   Requires:  map directive\n *\n *   Restrict To:  Element\n *\n * @attr {String} position position of this control\n *        i.e. TOP_RIGHT\n * @attr {Number} index index of the control\n * @example\n *\n * Example:\n *  <map center=\"41.850033,-87.6500523\" zoom=\"3\">\n *    <custom-control id=\"home\" position=\"TOP_LEFT\" index=\"1\">\n *      <div style=\"background-color: white;\">\n *        <b>Home</b>\n *      </div>\n *    </custom-control>\n *  </map>\n *\n */\n(function() {\n  'use strict';\n  var parser, NgMap;\n\n  var linkFunc = function(scope, element, attrs, mapController, $transclude) {\n    mapController = mapController[0]||mapController[1];\n    var filtered = parser.filter(attrs);\n    var options = parser.getOptions(filtered, {scope: scope});\n    var events = parser.getEvents(scope, filtered);\n\n    /**\n     * build a custom control element\n     */\n    var customControlEl = element[0].parentElement.removeChild(element[0]);\n    var content = $transclude();\n    angular.element(customControlEl).append(content);\n\n    /**\n     * set events\n     */\n    for (var eventName in events) {\n      google.maps.event.addDomListener(customControlEl, eventName, events[eventName]);\n    }\n\n    mapController.addObject('customControls', customControlEl);\n    var position = options.position;\n    mapController.map.controls[google.maps.ControlPosition[position]].push(customControlEl);\n\n    element.bind('$destroy', function() {\n      mapController.deleteObject('customControls', customControlEl);\n    });\n  };\n\n  var customControl =  function(Attr2MapOptions, _NgMap_)  {\n    parser = Attr2MapOptions, NgMap = _NgMap_;\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc,\n      transclude: true\n    }; // return\n  };\n  customControl.$inject = ['Attr2MapOptions', 'NgMap'];\n\n  angular.module('ngMap').directive('customControl', customControl);\n})();\n\n/**\n * @ngdoc directive\n * @memberof ngmap\n * @name custom-marker\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @param $timeout {service} AngularJS $timeout\n * @description\n *   Marker with html\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @attr {String} position required, position on map\n * @attr {Number} z-index optional\n * @attr {Boolean} visible optional\n * @example\n *\n * Example:\n *   <map center=\"41.850033,-87.6500523\" zoom=\"3\">\n *     <custom-marker position=\"41.850033,-87.6500523\">\n *       <div>\n *         <b>Home</b>\n *       </div>\n *     </custom-marker>\n *   </map>\n *\n */\n/* global document */\n(function() {\n  'use strict';\n  var parser, $timeout, $compile, NgMap;\n\n  var CustomMarker = function(options) {\n    options = options || {};\n\n    this.el = document.createElement('div');\n    this.el.style.display = 'inline-block';\n    this.el.style.visibility = \"hidden\";\n    this.visible = true;\n    for (var key in options) { /* jshint ignore:line */\n     this[key] = options[key];\n    }\n  };\n\n  var setCustomMarker = function() {\n\n    CustomMarker.prototype = new google.maps.OverlayView();\n\n    CustomMarker.prototype.setContent = function(html, scope) {\n      this.el.innerHTML = html;\n      this.el.style.position = 'absolute';\n      if (scope) {\n        $compile(angular.element(this.el).contents())(scope);\n      }\n    };\n\n    CustomMarker.prototype.getDraggable = function() {\n      return this.draggable;\n    };\n\n    CustomMarker.prototype.setDraggable = function(draggable) {\n      this.draggable = draggable;\n    };\n\n    CustomMarker.prototype.getPosition = function() {\n      return this.position;\n    };\n\n    CustomMarker.prototype.setPosition = function(position) {\n      position && (this.position = position); /* jshint ignore:line */\n      var _this = this;\n      if (this.getProjection() && typeof this.position.lng == 'function') {\n        void 0;\n        var setPosition = function() {\n          if (!_this.getProjection()) { return; }\n          var posPixel = _this.getProjection().fromLatLngToDivPixel(_this.position);\n          var x = Math.round(posPixel.x - (_this.el.offsetWidth/2));\n          var y = Math.round(posPixel.y - _this.el.offsetHeight - 10); // 10px for anchor\n          _this.el.style.left = x + \"px\";\n          _this.el.style.top = y + \"px\";\n          _this.el.style.visibility = \"visible\";\n        };\n        if (_this.el.offsetWidth && _this.el.offsetHeight) {\n          setPosition();\n        } else {\n          //delayed left/top calculation when width/height are not set instantly\n          $timeout(setPosition, 300);\n        }\n      }\n    };\n\n    CustomMarker.prototype.setZIndex = function(zIndex) {\n      zIndex && (this.zIndex = zIndex); /* jshint ignore:line */\n      this.el.style.zIndex = this.zIndex;\n    };\n\n    CustomMarker.prototype.getVisible = function() {\n      return this.visible;\n    };\n\n    CustomMarker.prototype.setVisible = function(visible) {\n      this.el.style.display = visible ? 'inline-block' : 'none';\n      this.visible = visible;\n    };\n\n    CustomMarker.prototype.addClass = function(className) {\n      var classNames = this.el.className.trim().split(' ');\n      (classNames.indexOf(className) == -1) && classNames.push(className); /* jshint ignore:line */\n      this.el.className = classNames.join(' ');\n    };\n\n    CustomMarker.prototype.removeClass = function(className) {\n      var classNames = this.el.className.split(' ');\n      var index = classNames.indexOf(className);\n      (index > -1) && classNames.splice(index, 1); /* jshint ignore:line */\n      this.el.className = classNames.join(' ');\n    };\n\n    CustomMarker.prototype.onAdd = function() {\n      this.getPanes().overlayMouseTarget.appendChild(this.el);\n    };\n\n    CustomMarker.prototype.draw = function() {\n      this.setPosition();\n      this.setZIndex(this.zIndex);\n      this.setVisible(this.visible);\n    };\n\n    CustomMarker.prototype.onRemove = function() {\n      this.el.parentNode.removeChild(this.el);\n      //this.el = null;\n    };\n  };\n\n  var linkFunc = function(orgHtml, varsToWatch) {\n    //console.log('orgHtml', orgHtml, 'varsToWatch', varsToWatch);\n\n    return function(scope, element, attrs, mapController) {\n      mapController = mapController[0]||mapController[1];\n      var orgAttrs = parser.orgAttributes(element);\n\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var events = parser.getEvents(scope, filtered);\n\n      /**\n       * build a custom marker element\n       */\n      element[0].style.display = 'none';\n      void 0;\n      var customMarker = new CustomMarker(options);\n\n      $timeout(function() { //apply contents, class, and location after it is compiled\n\n        scope.$watch('[' + varsToWatch.join(',') + ']', function() {\n          customMarker.setContent(orgHtml, scope);\n        }, true);\n\n        customMarker.setContent(element[0].innerHTML, scope);\n        var classNames = element[0].firstElementChild.className;\n        customMarker.addClass('custom-marker');\n        customMarker.addClass(classNames);\n        void 0;\n\n        if (!(options.position instanceof google.maps.LatLng)) {\n          NgMap.getGeoLocation(options.position).then(\n                function(latlng) {\n                  customMarker.setPosition(latlng);\n                }\n          );\n        }\n\n      });\n\n      void 0;\n      for (var eventName in events) { /* jshint ignore:line */\n        google.maps.event.addDomListener(\n          customMarker.el, eventName, events[eventName]);\n      }\n      mapController.addObject('customMarkers', customMarker);\n\n      //set observers\n      mapController.observeAttrSetObj(orgAttrs, attrs, customMarker);\n\n      element.bind('$destroy', function() {\n        //Is it required to remove event listeners when DOM is removed?\n        mapController.deleteObject('customMarkers', customMarker);\n      });\n\n    }; // linkFunc\n  };\n\n\n  var customMarkerDirective = function(\n      _$timeout_, _$compile_, $interpolate, Attr2MapOptions, _NgMap_, escapeRegExp\n    )  {\n    parser = Attr2MapOptions;\n    $timeout = _$timeout_;\n    $compile = _$compile_;\n    NgMap = _NgMap_;\n\n    var exprStartSymbol = $interpolate.startSymbol();\n    var exprEndSymbol = $interpolate.endSymbol();\n    var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '([^' + exprEndSymbol.substring(0, 1) + ']+)' + escapeRegExp(exprEndSymbol), 'g');\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      compile: function(element) {\n        setCustomMarker();\n        element[0].style.display ='none';\n        var orgHtml = element.html();\n        var matches = orgHtml.match(exprRegExp);\n        var varsToWatch = [];\n        //filter out that contains '::', 'this.'\n        (matches || []).forEach(function(match) {\n          var toWatch = match.replace(exprStartSymbol,'').replace(exprEndSymbol,'');\n          if (match.indexOf('::') == -1 &&\n            match.indexOf('this.') == -1 &&\n            varsToWatch.indexOf(toWatch) == -1) {\n            varsToWatch.push(match.replace(exprStartSymbol,'').replace(exprEndSymbol,''));\n          }\n        });\n\n        return linkFunc(orgHtml, varsToWatch);\n      }\n    }; // return\n  };// function\n  customMarkerDirective.$inject =\n    ['$timeout', '$compile', '$interpolate', 'Attr2MapOptions', 'NgMap', 'escapeRegexpFilter'];\n\n  angular.module('ngMap').directive('customMarker', customMarkerDirective);\n})();\n\n/**\n * @ngdoc directive\n * @name directions\n * @description\n *   Enable directions on map.\n *   e.g., origin, destination, draggable, waypoints, etc\n *\n *   Requires:  map directive\n *\n *   Restrict To:  Element\n *\n * @attr {String} DirectionsRendererOptions\n *   [Any DirectionsRendererOptions](https://developers.google.com/maps/documentation/javascript/reference#DirectionsRendererOptions)\n * @attr {String} DirectionsRequestOptions\n *   [Any DirectionsRequest options](https://developers.google.com/maps/documentation/javascript/reference#DirectionsRequest)\n * @example\n *  <map zoom=\"14\" center=\"37.7699298, -122.4469157\">\n *    <directions\n *      draggable=\"true\"\n *      panel=\"directions-panel\"\n *      travel-mode=\"{{travelMode}}\"\n *      waypoints=\"[{location:'kingston', stopover:true}]\"\n *      origin=\"{{origin}}\"\n *      destination=\"{{destination}}\">\n *    </directions>\n *  </map>\n */\n/* global document */\n(function() {\n  'use strict';\n  var NgMap, $timeout, NavigatorGeolocation;\n\n  var getDirectionsRenderer = function(options, events) {\n    if (options.panel) {\n      options.panel = document.getElementById(options.panel) ||\n        document.querySelector(options.panel);\n    }\n    var renderer = new google.maps.DirectionsRenderer(options);\n    for (var eventName in events) {\n      google.maps.event.addListener(renderer, eventName, events[eventName]);\n    }\n    return renderer;\n  };\n\n  var updateRoute = function(renderer, options) {\n    var directionsService = new google.maps.DirectionsService();\n\n    /* filter out valid keys only for DirectionsRequest object*/\n    var request = options;\n    request.travelMode = request.travelMode || 'DRIVING';\n    var validKeys = [\n      'origin', 'destination', 'travelMode', 'transitOptions', 'unitSystem',\n      'durationInTraffic', 'waypoints', 'optimizeWaypoints', \n      'provideRouteAlternatives', 'avoidHighways', 'avoidTolls', 'region'\n    ];\n    for(var key in request){\n      (validKeys.indexOf(key) === -1) && (delete request[key]);\n    }\n\n    if(request.waypoints) {\n      // Check fo valid values\n      if(request.waypoints == \"[]\" || request.waypoints === \"\") {\n        delete request.waypoints;\n      }\n    }\n\n    var showDirections = function(request) {\n      directionsService.route(request, function(response, status) {\n        if (status == google.maps.DirectionsStatus.OK) {\n          $timeout(function() {\n            renderer.setDirections(response);\n          });\n        }\n      });\n    };\n\n    if (request.origin && request.destination) {\n      if (request.origin == 'current-location') {\n        NavigatorGeolocation.getCurrentPosition().then(function(ll) {\n          request.origin = new google.maps.LatLng(ll.coords.latitude, ll.coords.longitude);\n          showDirections(request);\n        });\n      } else if (request.destination == 'current-location') {\n        NavigatorGeolocation.getCurrentPosition().then(function(ll) {\n          request.destination = new google.maps.LatLng(ll.coords.latitude, ll.coords.longitude);\n          showDirections(request);\n        });\n      } else {\n        showDirections(request);\n      }\n    }\n  };\n\n  var directions = function(\n      Attr2MapOptions, _$timeout_, _NavigatorGeolocation_, _NgMap_) {\n    var parser = Attr2MapOptions;\n    NgMap = _NgMap_;\n    $timeout = _$timeout_;\n    NavigatorGeolocation = _NavigatorGeolocation_;\n\n    var linkFunc = function(scope, element, attrs, mapController) {\n      mapController = mapController[0]||mapController[1];\n\n      var orgAttrs = parser.orgAttributes(element);\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var events = parser.getEvents(scope, filtered);\n      var attrsToObserve = parser.getAttrsToObserve(orgAttrs);\n\n      var renderer = getDirectionsRenderer(options, events);\n      mapController.addObject('directionsRenderers', renderer);\n\n      attrsToObserve.forEach(function(attrName) {\n        (function(attrName) {\n          attrs.$observe(attrName, function(val) {\n            if (attrName == 'panel') {\n              $timeout(function(){\n                var panel =\n                  document.getElementById(val) || document.querySelector(val);\n                void 0;\n                panel && renderer.setPanel(panel);\n              });\n            } else if (options[attrName] !== val) { //apply only if changed\n              var optionValue = parser.toOptionValue(val, {key: attrName});\n              void 0;\n              options[attrName] = optionValue;\n              updateRoute(renderer, options);\n            }\n          });\n        })(attrName);\n      });\n\n      NgMap.getMap().then(function() {\n        updateRoute(renderer, options);\n      });\n      element.bind('$destroy', function() {\n        mapController.deleteObject('directionsRenderers', renderer);\n      });\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n    };\n  }; // var directions\n  directions.$inject =\n    ['Attr2MapOptions', '$timeout', 'NavigatorGeolocation', 'NgMap'];\n\n  angular.module('ngMap').directive('directions', directions);\n})();\n\n\n/**\n * @ngdoc directive\n * @name drawing-manager\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n *  <map zoom=\"13\" center=\"37.774546, -122.433523\" map-type-id=\"SATELLITE\">\n *    <drawing-manager\n *      on-overlaycomplete=\"onMapOverlayCompleted()\"\n *      position=\"ControlPosition.TOP_CENTER\"\n *      drawingModes=\"POLYGON,CIRCLE\"\n *      drawingControl=\"true\"\n *      circleOptions=\"fillColor: '#FFFF00';fillOpacity: 1;strokeWeight: 5;clickable: false;zIndex: 1;editable: true;\" >\n *    </drawing-manager>\n *  </map>\n *\n *  TODO: Add remove button.\n *  currently, for our solution, we have the shapes/markers in our own\n *  controller, and we use some css classes to change the shape button\n *  to a remove button (<div>X</div>) and have the remove operation in our own controller.\n */\n(function() {\n  'use strict';\n  angular.module('ngMap').directive('drawingManager', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var controlOptions = parser.getControlOptions(filtered);\n        var events = parser.getEvents(scope, filtered);\n\n        /**\n         * set options\n         */\n        var drawingManager = new google.maps.drawing.DrawingManager({\n          drawingMode: options.drawingmode,\n          drawingControl: options.drawingcontrol,\n          drawingControlOptions: controlOptions.drawingControlOptions,\n          circleOptions:options.circleoptions,\n          markerOptions:options.markeroptions,\n          polygonOptions:options.polygonoptions,\n          polylineOptions:options.polylineoptions,\n          rectangleOptions:options.rectangleoptions\n        });\n\n        //Observers\n        attrs.$observe('drawingControlOptions', function (newValue) {\n          drawingManager.drawingControlOptions = parser.getControlOptions({drawingControlOptions: newValue}).drawingControlOptions;\n          drawingManager.setDrawingMode(null);\n          drawingManager.setMap(mapController.map);\n        });\n\n\n        /**\n         * set events\n         */\n        for (var eventName in events) {\n          google.maps.event.addListener(drawingManager, eventName, events[eventName]);\n        }\n\n        mapController.addObject('mapDrawingManager', drawingManager);\n\n        element.bind('$destroy', function() {\n          mapController.deleteObject('mapDrawingManager', drawingManager);\n        });\n      }\n    }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name dynamic-maps-engine-layer\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *   <map zoom=\"14\" center=\"[59.322506, 18.010025]\">\n *     <dynamic-maps-engine-layer\n *       layer-id=\"06673056454046135537-08896501997766553811\">\n *     </dynamic-maps-engine-layer>\n *    </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('dynamicMapsEngineLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getDynamicMapsEngineLayer = function(options, events) {\n      var layer = new google.maps.visualization.DynamicMapsEngineLayer(options);\n\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered, events);\n\n        var layer = getDynamicMapsEngineLayer(options, events);\n        mapController.addObject('mapsEngineLayers', layer);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name fusion-tables-layer\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *   <map zoom=\"11\" center=\"41.850033, -87.6500523\">\n *     <fusion-tables-layer query=\"{\n *       select: 'Geocodable address',\n *       from: '1mZ53Z70NsChnBMm-qEYmSDOvLXgrreLTkQUvvg'}\">\n *     </fusion-tables-layer>\n *   </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('fusionTablesLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getLayer = function(options, events) {\n      var layer = new google.maps.FusionTablesLayer(options);\n\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered, events);\n        void 0;\n\n        var layer = getLayer(options, events);\n        mapController.addObject('fusionTablesLayers', layer);\n        element.bind('$destroy', function() {\n          mapController.deleteObject('fusionTablesLayers', layer);\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name heatmap-layer\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n *\n * <map zoom=\"11\" center=\"[41.875696,-87.624207]\">\n *   <heatmap-layer data=\"taxiData\"></heatmap-layer>\n * </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('heatmapLayer', [\n    'Attr2MapOptions', '$window', function(Attr2MapOptions, $window) {\n    var parser = Attr2MapOptions;\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n\n        /**\n         * set options\n         */\n        var options = parser.getOptions(filtered, {scope: scope});\n        options.data = $window[attrs.data] || scope[attrs.data];\n        if (options.data instanceof Array) {\n          options.data = new google.maps.MVCArray(options.data);\n        } else {\n          throw \"invalid heatmap data\";\n        }\n        var layer = new google.maps.visualization.HeatmapLayer(options);\n\n        /**\n         * set events\n         */\n        var events = parser.getEvents(scope, filtered);\n        void 0;\n\n        mapController.addObject('heatmapLayers', layer);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name info-window\n * @param Attr2MapOptions {service}\n *   convert html attribute to Google map api options\n * @param $compile {service} $compile service\n * @description\n *  Defines infoWindow and provides compile method\n *\n *  Requires:  map directive\n *\n *  Restrict To:  Element\n *\n *  NOTE: this directive should **NOT** be used with `ng-repeat`\n *  because InfoWindow itself is a template, and a template must be\n *  reused by each marker, thus, should not be redefined repeatedly\n *  by `ng-repeat`.\n *\n * @attr {Boolean} visible\n *   Indicates to show it when map is initialized\n * @attr {Boolean} visible-on-marker\n *   Indicates to show it on a marker when map is initialized\n * @attr {Expression} geo-callback\n *   if position is an address, the expression is will be performed\n *   when geo-lookup is successful. e.g., geo-callback=\"showDetail()\"\n * @attr {String} &lt;InfoWindowOption> Any InfoWindow options,\n *   https://developers.google.com/maps/documentation/javascript/reference?csw=1#InfoWindowOptions\n * @attr {String} &lt;InfoWindowEvent> Any InfoWindow events,\n *   https://developers.google.com/maps/documentation/javascript/reference\n * @example\n * Usage:\n *   <map MAP_ATTRIBUTES>\n *    <info-window id=\"foo\" ANY_OPTIONS ANY_EVENTS\"></info-window>\n *   </map>\n *\n * Example:\n *  <map center=\"41.850033,-87.6500523\" zoom=\"3\">\n *    <info-window id=\"1\" position=\"41.850033,-87.6500523\" >\n *      <div ng-non-bindable>\n *        Chicago, IL<br/>\n *        LatLng: {{chicago.lat()}}, {{chicago.lng()}}, <br/>\n *        World Coordinate: {{worldCoordinate.x}}, {{worldCoordinate.y}}, <br/>\n *        Pixel Coordinate: {{pixelCoordinate.x}}, {{pixelCoordinate.y}}, <br/>\n *        Tile Coordinate: {{tileCoordinate.x}}, {{tileCoordinate.y}} at Zoom Level {{map.getZoom()}}\n *      </div>\n *    </info-window>\n *  </map>\n */\n/* global google */\n(function() {\n  'use strict';\n\n  var infoWindow = function(Attr2MapOptions, $compile, $q, $templateRequest, $timeout, $parse, NgMap)  {\n    var parser = Attr2MapOptions;\n\n    var getInfoWindow = function(options, events, element) {\n      var infoWindow;\n\n      /**\n       * set options\n       */\n      if (options.position && !(options.position instanceof google.maps.LatLng)) {\n        delete options.position;\n      }\n      infoWindow = new google.maps.InfoWindow(options);\n\n      /**\n       * set events\n       */\n      for (var eventName in events) {\n        if (eventName) {\n          google.maps.event.addListener(infoWindow, eventName, events[eventName]);\n        }\n      }\n\n      /**\n       * set template and template-related functions\n       * it must have a container element with ng-non-bindable\n       */\n      var templatePromise = $q(function(resolve) {\n        if (angular.isString(element)) {\n          $templateRequest(element).then(function (requestedTemplate) {\n            resolve(angular.element(requestedTemplate).wrap('<div>').parent());\n          }, function(message) {\n            throw \"info-window template request failed: \" + message;\n          });\n        }\n        else {\n          resolve(element);\n        }\n      }).then(function(resolvedTemplate) {\n        var template = resolvedTemplate.html().trim();\n        if (angular.element(template).length != 1) {\n          throw \"info-window working as a template must have a container\";\n        }\n        infoWindow.__template = template.replace(/\\s?ng-non-bindable[='\"]+/,\"\");\n      });\n\n      infoWindow.__open = function(map, scope, anchor) {\n        templatePromise.then(function() {\n          $timeout(function() {\n            anchor && (scope.anchor = anchor);\n            var el = $compile(infoWindow.__template)(scope);\n            infoWindow.setContent(el[0]);\n            scope.$apply();\n            if (anchor && anchor.getPosition) {\n              infoWindow.open(map, anchor);\n            } else if (anchor && anchor instanceof google.maps.LatLng) {\n              infoWindow.open(map);\n              infoWindow.setPosition(anchor);\n            } else {\n              infoWindow.open(map);\n            }\n            var infoWindowContainerEl = infoWindow.content.parentElement.parentElement.parentElement;\n            infoWindowContainerEl.className = \"ng-map-info-window\";\n          });\n        });\n      };\n\n      return infoWindow;\n    };\n\n    var linkFunc = function(scope, element, attrs, mapController) {\n      mapController = mapController[0]||mapController[1];\n\n      element.css('display','none');\n\n      var orgAttrs = parser.orgAttributes(element);\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var events = parser.getEvents(scope, filtered);\n\n      var infoWindow = getInfoWindow(options, events, options.template || element);\n      var address;\n      if (options.position && !(options.position instanceof google.maps.LatLng)) {\n        address = options.position;\n      }\n      if (address) {\n        NgMap.getGeoLocation(address).then(function(latlng) {\n          infoWindow.setPosition(latlng);\n          infoWindow.__open(mapController.map, scope, latlng);\n          var geoCallback = attrs.geoCallback;\n          geoCallback && $parse(geoCallback)(scope);\n        });\n      }\n\n      mapController.addObject('infoWindows', infoWindow);\n      mapController.observeAttrSetObj(orgAttrs, attrs, infoWindow);\n\n      mapController.showInfoWindow =\n      mapController.map.showInfoWindow = mapController.showInfoWindow ||\n        function(p1, p2, p3) { //event, id, marker\n          var id = typeof p1 == 'string' ? p1 : p2;\n          var marker = typeof p1 == 'string' ? p2 : p3;\n          if (typeof marker == 'string') {\n            //Check if markers if defined to avoid odd 'undefined' errors\n            if (\n              typeof mapController.map.markers != \"undefined\"\n              && typeof mapController.map.markers[marker] != \"undefined\") {\n                marker = mapController.map.markers[marker];\n            } else if (\n              //additionally check if that marker is a custom marker\n              typeof mapController.map.customMarkers !== \"undefined\"\n              && typeof mapController.map.customMarkers[marker] !== \"undefined\") {\n                marker = mapController.map.customMarkers[marker];\n            } else {\n              //Better error output if marker with that id is not defined\n              throw new Error(\"Cant open info window for id \" + marker + \". Marker or CustomMarker is not defined\")\n            }\n          }\n\n          var infoWindow = mapController.map.infoWindows[id];\n          var anchor = marker ? marker : (this.getPosition ? this : null);\n          infoWindow.__open(mapController.map, scope, anchor);\n          if(mapController.singleInfoWindow) {\n            if(mapController.lastInfoWindow) {\n              scope.hideInfoWindow(mapController.lastInfoWindow);\n            }\n            mapController.lastInfoWindow = id;\n          }\n        };\n\n      mapController.hideInfoWindow =\n      mapController.map.hideInfoWindow = mapController.hideInfoWindow ||\n        function(p1, p2) {\n          var id = typeof p1 == 'string' ? p1 : p2;\n          var infoWindow = mapController.map.infoWindows[id];\n          infoWindow.close();\n        };\n\n      //TODO DEPRECATED\n      scope.showInfoWindow = mapController.map.showInfoWindow;\n      scope.hideInfoWindow = mapController.map.hideInfoWindow;\n\n      var map = infoWindow.mapId ? {id:infoWindow.mapId} : 0;\n      NgMap.getMap(map).then(function(map) {\n        infoWindow.visible && infoWindow.__open(map, scope);\n        if (infoWindow.visibleOnMarker) {\n          var markerId = infoWindow.visibleOnMarker;\n          infoWindow.__open(map, scope, map.markers[markerId]);\n        }\n      });\n\n    }; //link\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n    };\n\n  }; // infoWindow\n  infoWindow.$inject =\n    ['Attr2MapOptions', '$compile', '$q', '$templateRequest', '$timeout', '$parse', 'NgMap'];\n\n  angular.module('ngMap').directive('infoWindow', infoWindow);\n})();\n\n/**\n * @ngdoc directive\n * @name kml-layer\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   renders Kml layer on a map\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @attr {Url} url url of the kml layer\n * @attr {KmlLayerOptions} KmlLayerOptions\n *   (https://developers.google.com/maps/documentation/javascript/reference#KmlLayerOptions) \n * @attr {String} &lt;KmlLayerEvent> Any KmlLayer events,\n *   https://developers.google.com/maps/documentation/javascript/reference\n * @example\n * Usage:\n *   <map MAP_ATTRIBUTES>\n *    <kml-layer ANY_KML_LAYER ANY_KML_LAYER_EVENTS\"></kml-layer>\n *   </map>\n *\n * Example:\n *\n * <map zoom=\"11\" center=\"[41.875696,-87.624207]\">\n *   <kml-layer url=\"https://gmaps-samples.googlecode.com/svn/trunk/ggeoxml/cta.kml\" >\n *   </kml-layer>\n * </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('kmlLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getKmlLayer = function(options, events) {\n      var kmlLayer = new google.maps.KmlLayer(options);\n      for (var eventName in events) {\n        google.maps.event.addListener(kmlLayer, eventName, events[eventName]);\n      }\n      return kmlLayer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var orgAttrs = parser.orgAttributes(element);\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered);\n        void 0;\n\n        var kmlLayer = getKmlLayer(options, events);\n        mapController.addObject('kmlLayers', kmlLayer);\n        mapController.observeAttrSetObj(orgAttrs, attrs, kmlLayer);  //observers\n        element.bind('$destroy', function() {\n          mapController.deleteObject('kmlLayers', kmlLayer);\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name map-data\n * @param Attr2MapOptions {service}\n *   convert html attribute to Google map api options\n * @description\n *   set map data\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @wn {String} method-name, run map.data[method-name] with attribute value\n * @example\n * Example:\n *\n *  <map zoom=\"11\" center=\"[41.875696,-87.624207]\">\n *    <map-data load-geo-json=\"https://storage.googleapis.com/maps-devrel/google.json\"></map-data>\n *   </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('mapData', [\n    'Attr2MapOptions', 'NgMap', function(Attr2MapOptions, NgMap) {\n    var parser = Attr2MapOptions;\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0] || mapController[1];\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered, events);\n\n        void 0;\n        NgMap.getMap(mapController.map.id).then(function(map) {\n          //options\n          for (var key in options) {\n            var val = options[key];\n            if (typeof scope[val] === \"function\") {\n              map.data[key](scope[val]);\n            } else {\n              map.data[key](val);\n            }\n          }\n\n          //events\n          for (var eventName in events) {\n            map.data.addListener(eventName, events[eventName]);\n          }\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name map-lazy-load\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @description\n *  Requires: Delay the initialization of map directive\n *    until the map is ready to be rendered\n *  Restrict To: Attribute\n *\n * @attr {String} map-lazy-load\n *    Maps api script source file location.\n *    Example:\n *      'https://maps.google.com/maps/api/js'\n * @attr {String} map-lazy-load-params\n *   Maps api script source file location via angular scope variable.\n *   Also requires the map-lazy-load attribute to be present in the directive.\n *   Example: In your controller, set\n *     $scope.googleMapsURL = 'https://maps.google.com/maps/api/js?v=3.20&client=XXXXXenter-api-key-hereXXXX'\n *\n * @example\n * Example:\n *\n *   <div map-lazy-load=\"http://maps.google.com/maps/api/js\">\n *     <map center=\"Brampton\" zoom=\"10\">\n *       <marker position=\"Brampton\"></marker>\n *     </map>\n *   </div>\n *\n *   <div map-lazy-load=\"http://maps.google.com/maps/api/js\"\n *        map-lazy-load-params=\"{{googleMapsUrl}}\">\n *     <map center=\"Brampton\" zoom=\"10\">\n *       <marker position=\"Brampton\"></marker>\n *     </map>\n *   </div>\n */\n/* global window, document */\n(function() {\n  'use strict';\n  var $timeout, $compile, src, savedHtml = [], elements = [];\n\n  var preLinkFunc = function(scope, element, attrs) {\n    var mapsUrl = attrs.mapLazyLoadParams || attrs.mapLazyLoad;\n\n    if(window.google === undefined || window.google.maps === undefined) {\n      elements.push({\n        scope: scope,\n        element: element,\n        savedHtml: savedHtml[elements.length],\n      });\n\n      window.lazyLoadCallback = function() {\n        void 0;\n        $timeout(function() { /* give some time to load */\n          elements.forEach(function(elm) {\n              elm.element.html(elm.savedHtml);\n              $compile(elm.element.contents())(elm.scope);\n          });\n        }, 100);\n      };\n\n      var scriptEl = document.createElement('script');\n      void 0;\n\n      scriptEl.src = mapsUrl +\n        (mapsUrl.indexOf('?') > -1 ? '&' : '?') +\n        'callback=lazyLoadCallback';\n\n        if (!document.querySelector('script[src=\"' + scriptEl.src + '\"]')) {\n          document.body.appendChild(scriptEl);\n        }\n    } else {\n      element.html(savedHtml);\n      $compile(element.contents())(scope);\n    }\n  };\n\n  var compileFunc = function(tElement, tAttrs) {\n\n    (!tAttrs.mapLazyLoad) && void 0;\n    savedHtml.push(tElement.html());\n    src = tAttrs.mapLazyLoad;\n\n    /**\n     * if already loaded, stop processing it\n     */\n    if(window.google !== undefined && window.google.maps !== undefined) {\n      return false;\n    }\n\n    tElement.html('');  // will compile again after script is loaded\n\n    return {\n      pre: preLinkFunc\n    };\n  };\n\n  var mapLazyLoad = function(_$compile_, _$timeout_) {\n    $compile = _$compile_, $timeout = _$timeout_;\n    return {\n      compile: compileFunc\n    };\n  };\n  mapLazyLoad.$inject = ['$compile','$timeout'];\n\n  angular.module('ngMap').directive('mapLazyLoad', mapLazyLoad);\n})();\n\n/**\n * @ngdoc directive\n * @name map-type\n * @param Attr2MapOptions {service} \n *   convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n *   <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *     <map-type name=\"coordinate\" object=\"coordinateMapType\"></map-type>\n *   </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('mapType', ['$parse', 'NgMap',\n    function($parse, NgMap) {\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var mapTypeName = attrs.name, mapTypeObject;\n        if (!mapTypeName) {\n          throw \"invalid map-type name\";\n        }\n        mapTypeObject = $parse(attrs.object)(scope);\n        if (!mapTypeObject) {\n          throw \"invalid map-type object\";\n        }\n\n        NgMap.getMap().then(function(map) {\n          map.mapTypes.set(mapTypeName, mapTypeObject);\n        });\n        mapController.addObject('mapTypes', mapTypeObject);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @memberof ngMap\n * @name ng-map\n * @param Attr2Options {service}\n *  convert html attribute to Google map api options\n * @description\n * Implementation of {@link __MapController}\n * Initialize a Google map within a `<div>` tag\n *   with given options and register events\n *\n * @attr {Expression} map-initialized\n *   callback function when map is initialized\n *   e.g., map-initialized=\"mycallback(map)\"\n * @attr {Expression} geo-callback if center is an address or current location,\n *   the expression is will be executed when geo-lookup is successful.\n *   e.g., geo-callback=\"showMyStoreInfo()\"\n * @attr {Array} geo-fallback-center\n *   The center of map incase geolocation failed. i.e. [0,0]\n * @attr {Object} geo-location-options\n *  The navigator geolocation options.\n *  e.g., { maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }.\n *  If none specified, { timeout: 5000 }.\n *  If timeout not specified, timeout: 5000 added\n * @attr {Boolean} zoom-to-include-markers\n *  When true, map boundary will be changed automatially\n *  to include all markers when initialized\n * @attr {Boolean} default-style\n *  When false, the default styling,\n *  `display:block;height:300px`, will be ignored.\n * @attr {String} &lt;MapOption> Any Google map options,\n *  https://developers.google.com/maps/documentation/javascript/reference?csw=1#MapOptions\n * @attr {String} &lt;MapEvent> Any Google map events,\n *  https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/map_events.html\n * @attr {Boolean} single-info-window\n *  When true the map will only display one info window at the time,\n *  if not set or false,\n *  everytime an info window is open it will be displayed with the othe one.\n * @attr {Boolean} trigger-resize\n *  Default to false.  Set to true to trigger resize of the map.  Needs to be done anytime you resize the map\n * @example\n * Usage:\n *   <map MAP_OPTIONS_OR_MAP_EVENTS ..>\n *     ... Any children directives\n *   </map>\n *\n * Example:\n *   <map center=\"[40.74, -74.18]\" on-click=\"doThat()\">\n *   </map>\n *\n *   <map geo-fallback-center=\"[40.74, -74.18]\" zoom-to-inlude-markers=\"true\">\n *   </map>\n */\n(function () {\n  'use strict';\n\n  var mapDirective = function () {\n    return {\n      restrict: 'AE',\n      controller: '__MapController',\n      controllerAs: 'ngmap'\n    };\n  };\n\n  angular.module('ngMap').directive('map', [mapDirective]);\n  angular.module('ngMap').directive('ngMap', [mapDirective]);\n})();\n\n/**\n * @ngdoc directive\n * @name maps-engine-layer\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *  <map zoom=\"14\" center=\"[59.322506, 18.010025]\">\n *    <maps-engine-layer layer-id=\"06673056454046135537-08896501997766553811\">\n *    </maps-engine-layer>\n *  </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('mapsEngineLayer', ['Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getMapsEngineLayer = function(options, events) {\n      var layer = new google.maps.visualization.MapsEngineLayer(options);\n\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered, events);\n        void 0;\n\n        var layer = getMapsEngineLayer(options, events);\n        mapController.addObject('mapsEngineLayers', layer);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name marker\n * @param Attr2Options {service} convert html attribute to Google map api options\n * @param NavigatorGeolocation It is used to find the current location\n * @description\n *  Draw a Google map marker on a map with given options and register events\n *\n *  Requires:  map directive\n *\n *  Restrict To:  Element\n *\n * @attr {String} position address, 'current', or [latitude, longitude]\n *  example:\n *    '1600 Pennsylvania Ave, 20500  Washingtion DC',\n *    'current position',\n *    '[40.74, -74.18]'\n * @attr {Boolean} centered if set, map will be centered with this marker\n * @attr {Expression} geo-callback if position is an address,\n *   the expression is will be performed when geo-lookup is successful.\n *   e.g., geo-callback=\"showStoreInfo()\"\n * @attr {Boolean} no-watcher if true, no attribute observer is added.\n *   Useful for many ng-repeat\n * @attr {String} &lt;MarkerOption>\n *   [Any Marker options](https://developers.google.com/maps/documentation/javascript/reference?csw=1#MarkerOptions)\n * @attr {String} &lt;MapEvent>\n *   [Any Marker events](https://developers.google.com/maps/documentation/javascript/reference)\n * @example\n * Usage:\n *   <map MAP_ATTRIBUTES>\n *    <marker ANY_MARKER_OPTIONS ANY_MARKER_EVENTS\"></MARKER>\n *   </map>\n *\n * Example:\n *   <map center=\"[40.74, -74.18]\">\n *    <marker position=\"[40.74, -74.18]\" on-click=\"myfunc()\"></div>\n *   </map>\n *\n *   <map center=\"the cn tower\">\n *    <marker position=\"the cn tower\" on-click=\"myfunc()\"></div>\n *   </map>\n */\n/* global google */\n(function() {\n  'use strict';\n  var parser, $parse, NgMap;\n\n  var getMarker = function(options, events) {\n    var marker;\n\n    if (NgMap.defaultOptions.marker) {\n      for (var key in NgMap.defaultOptions.marker) {\n        if (typeof options[key] == 'undefined') {\n          void 0;\n          options[key] = NgMap.defaultOptions.marker[key];\n        }\n      }\n    }\n\n    if (!(options.position instanceof google.maps.LatLng)) {\n      options.position = new google.maps.LatLng(0,0);\n    }\n    marker = new google.maps.Marker(options);\n\n    /**\n     * set events\n     */\n    if (Object.keys(events).length > 0) {\n      void 0;\n    }\n    for (var eventName in events) {\n      if (eventName) {\n        google.maps.event.addListener(marker, eventName, events[eventName]);\n      }\n    }\n\n    return marker;\n  };\n\n  var linkFunc = function(scope, element, attrs, mapController) {\n    mapController = mapController[0]||mapController[1];\n\n    var orgAttrs = parser.orgAttributes(element);\n    var filtered = parser.filter(attrs);\n    var markerOptions = parser.getOptions(filtered, scope, {scope: scope});\n    var markerEvents = parser.getEvents(scope, filtered);\n    void 0;\n\n    var address;\n    if (!(markerOptions.position instanceof google.maps.LatLng)) {\n      address = markerOptions.position;\n    }\n    var marker = getMarker(markerOptions, markerEvents);\n    mapController.addObject('markers', marker);\n    if (address) {\n      NgMap.getGeoLocation(address).then(function(latlng) {\n        marker.setPosition(latlng);\n        markerOptions.centered && marker.map.setCenter(latlng);\n        var geoCallback = attrs.geoCallback;\n        geoCallback && $parse(geoCallback)(scope);\n      });\n    }\n\n    //set observers\n    mapController.observeAttrSetObj(orgAttrs, attrs, marker); /* observers */\n\n    element.bind('$destroy', function() {\n      mapController.deleteObject('markers', marker);\n    });\n  };\n\n  var marker = function(Attr2MapOptions, _$parse_, _NgMap_) {\n    parser = Attr2MapOptions;\n    $parse = _$parse_;\n    NgMap = _NgMap_;\n\n    return {\n      restrict: 'E',\n      require: ['^?map','?^ngMap'],\n      link: linkFunc\n    };\n  };\n\n  marker.$inject = ['Attr2MapOptions', '$parse', 'NgMap'];\n  angular.module('ngMap').directive('marker', marker);\n\n})();\n\n/**\n * @ngdoc directive\n * @name overlay-map-type\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @param $window {service}\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n * <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *   <overlay-map-type index=\"0\" object=\"coordinateMapType\"></map-type>\n * </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('overlayMapType', [\n    'NgMap', function(NgMap) {\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var initMethod = attrs.initMethod || \"insertAt\";\n        var overlayMapTypeObject = scope[attrs.object];\n\n        NgMap.getMap().then(function(map) {\n          if (initMethod == \"insertAt\") {\n            var index = parseInt(attrs.index, 10);\n            map.overlayMapTypes.insertAt(index, overlayMapTypeObject);\n          } else if (initMethod == \"push\") {\n            map.overlayMapTypes.push(overlayMapTypeObject);\n          }\n        });\n        mapController.addObject('overlayMapTypes', overlayMapTypeObject);\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name places-auto-complete\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Provides address auto complete feature to an input element\n *   Requires: input tag\n *   Restrict To: Attribute\n *\n * @attr {AutoCompleteOptions}\n *   [Any AutocompleteOptions](https://developers.google.com/maps/documentation/javascript/3.exp/reference#AutocompleteOptions)\n *\n * @example\n * Example:\n *   <script src=\"https://maps.googleapis.com/maps/api/js?libraries=places\"></script>\n *   <input places-auto-complete types=\"['geocode']\" on-place-changed=\"myCallback(place)\" component-restrictions=\"{country:'au'}\"/>\n */\n/* global google */\n(function() {\n  'use strict';\n\n  var placesAutoComplete = function(Attr2MapOptions, $timeout) {\n    var parser = Attr2MapOptions;\n\n    var linkFunc = function(scope, element, attrs, ngModelCtrl) {\n      if (attrs.placesAutoComplete ==='false') {\n        return false;\n      }\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var events = parser.getEvents(scope, filtered);\n      var autocomplete = new google.maps.places.Autocomplete(element[0], options);\n      for (var eventName in events) {\n        google.maps.event.addListener(autocomplete, eventName, events[eventName]);\n      }\n\n      var updateModel = function() {\n        $timeout(function(){\n          ngModelCtrl && ngModelCtrl.$setViewValue(element.val());\n        },100);\n      };\n      google.maps.event.addListener(autocomplete, 'place_changed', updateModel);\n      element[0].addEventListener('change', updateModel);\n\n      attrs.$observe('types', function(val) {\n        if (val) {\n          var optionValue = parser.toOptionValue(val, {key: 'types'});\n          autocomplete.setTypes(optionValue);\n        }\n      });\n\t  \n\t  attrs.$observe('componentRestrictions', function (val) {\n\t\t if (val) {\n\t\t   autocomplete.setComponentRestrictions(scope.$eval(val));\n\t\t }\n\t   });\n    };\n\t\n    return {\n      restrict: 'A',\n      require: '?ngModel',\n      link: linkFunc\n    };\n  };\n\n  placesAutoComplete.$inject = ['Attr2MapOptions', '$timeout'];\n  angular.module('ngMap').directive('placesAutoComplete', placesAutoComplete);\n})();\n\n/**\n * @ngdoc directive\n * @name shape\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Initialize a Google map shape in map with given options and register events\n *   The shapes are:\n *     . circle\n *     . polygon\n *     . polyline\n *     . rectangle\n *     . groundOverlay(or image)\n *\n *   Requires:  map directive\n *\n *   Restrict To:  Element\n *\n * @attr {Boolean} centered if set, map will be centered with this marker\n * @attr {Expression} geo-callback if shape is a circle and the center is\n *   an address, the expression is will be performed when geo-lookup\n *   is successful. e.g., geo-callback=\"showDetail()\"\n * @attr {String} &lt;OPTIONS>\n *   For circle, [any circle options](https://developers.google.com/maps/documentation/javascript/reference#CircleOptions)\n *   For polygon, [any polygon options](https://developers.google.com/maps/documentation/javascript/reference#PolygonOptions)\n *   For polyline, [any polyline options](https://developers.google.com/maps/documentation/javascript/reference#PolylineOptions)\n *   For rectangle, [any rectangle options](https://developers.google.com/maps/documentation/javascript/reference#RectangleOptions)\n *   For image, [any groundOverlay options](https://developers.google.com/maps/documentation/javascript/reference#GroundOverlayOptions)\n * @attr {String} &lt;MapEvent> [Any Shape events](https://developers.google.com/maps/documentation/javascript/reference)\n * @example\n * Usage:\n *   <map MAP_ATTRIBUTES>\n *    <shape name=SHAPE_NAME ANY_SHAPE_OPTIONS ANY_SHAPE_EVENTS\"></MARKER>\n *   </map>\n *\n * Example:\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"polyline\" name=\"polyline\" geodesic=\"true\"\n *       stroke-color=\"#FF0000\" stroke-opacity=\"1.0\" stroke-weight=\"2\"\n *       path=\"[[40.74,-74.18],[40.64,-74.10],[40.54,-74.05],[40.44,-74]]\" >\n *     </shape>\n *   </map>\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"polygon\" name=\"polygon\" stroke-color=\"#FF0000\"\n *       stroke-opacity=\"1.0\" stroke-weight=\"2\"\n *       paths=\"[[40.74,-74.18],[40.64,-74.18],[40.84,-74.08],[40.74,-74.18]]\" >\n *     </shape>\n *   </map>\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"rectangle\" name=\"rectangle\" stroke-color='#FF0000'\n *       stroke-opacity=\"0.8\" stroke-weight=\"2\"\n *       bounds=\"[[40.74,-74.18], [40.78,-74.14]]\" editable=\"true\" >\n *     </shape>\n *   </map>\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"circle\" name=\"circle\" stroke-color='#FF0000'\n *       stroke-opacity=\"0.8\"stroke-weight=\"2\"\n *       center=\"[40.70,-74.14]\" radius=\"4000\" editable=\"true\" >\n *     </shape>\n *   </map>\n *\n *   <map zoom=\"11\" center=\"[40.74, -74.18]\">\n *     <shape id=\"image\" name=\"image\"\n *       url=\"https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg\"\n *       bounds=\"[[40.71,-74.22],[40.77,-74.12]]\" opacity=\"0.7\"\n *       clickable=\"true\">\n *     </shape>\n *   </map>\n *\n *  For full-working example, please visit\n *    [shape example](https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/shape.html)\n */\n/* global google */\n(function() {\n  'use strict';\n\n  var getShape = function(options, events) {\n    var shape;\n\n    var shapeName = options.name;\n    delete options.name;  //remove name bcoz it's not for options\n    void 0;\n\n    /**\n     * set options\n     */\n    switch(shapeName) {\n      case \"circle\":\n        if (!(options.center instanceof google.maps.LatLng)) {\n          options.center = new google.maps.LatLng(0,0);\n        } \n        shape = new google.maps.Circle(options);\n        break;\n      case \"polygon\":\n        shape = new google.maps.Polygon(options);\n        break;\n      case \"polyline\":\n        shape = new google.maps.Polyline(options);\n        break;\n      case \"rectangle\":\n        shape = new google.maps.Rectangle(options);\n        break;\n      case \"groundOverlay\":\n      case \"image\":\n        var url = options.url;\n        var opts = {opacity: options.opacity, clickable: options.clickable, id:options.id};\n        shape = new google.maps.GroundOverlay(url, options.bounds, opts);\n        break;\n    }\n\n    /**\n     * set events\n     */\n    for (var eventName in events) {\n      if (events[eventName]) {\n        google.maps.event.addListener(shape, eventName, events[eventName]);\n      }\n    }\n    return shape;\n  };\n\n  var shape = function(Attr2MapOptions, $parse, NgMap) {\n    var parser = Attr2MapOptions;\n\n    var linkFunc = function(scope, element, attrs, mapController) {\n      mapController = mapController[0]||mapController[1];\n\n      var orgAttrs = parser.orgAttributes(element);\n      var filtered = parser.filter(attrs);\n      var shapeOptions = parser.getOptions(filtered, {scope: scope});\n      var shapeEvents = parser.getEvents(scope, filtered);\n\n      var address, shapeType;\n      shapeType = shapeOptions.name;\n      if (!(shapeOptions.center instanceof google.maps.LatLng)) {\n        address = shapeOptions.center;\n      }\n      var shape = getShape(shapeOptions, shapeEvents);\n      mapController.addObject('shapes', shape);\n\n      if (address && shapeType == 'circle') {\n        NgMap.getGeoLocation(address).then(function(latlng) {\n          shape.setCenter(latlng);\n          shape.centered && shape.map.setCenter(latlng);\n          var geoCallback = attrs.geoCallback;\n          geoCallback && $parse(geoCallback)(scope);\n        });\n      }\n\n      //set observers\n      mapController.observeAttrSetObj(orgAttrs, attrs, shape);\n      element.bind('$destroy', function() {\n        mapController.deleteObject('shapes', shape);\n      });\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n     }; // return\n  };\n  shape.$inject = ['Attr2MapOptions', '$parse', 'NgMap'];\n\n  angular.module('ngMap').directive('shape', shape);\n\n})();\n\n/**\n * @ngdoc directive\n * @name streetview-panorama\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @attr container Optional, id or css selector, if given, streetview will be in the given html element\n * @attr {String} &lt;StreetViewPanoramaOption>\n *   [Any Google StreetViewPanorama options](https://developers.google.com/maps/documentation/javascript/reference?csw=1#StreetViewPanoramaOptions)\n * @attr {String} &lt;StreetViewPanoramaEvent>\n *   [Any Google StreetViewPanorama events](https://developers.google.com/maps/documentation/javascript/reference#StreetViewPanorama)\n *\n * @example\n *   <map zoom=\"11\" center=\"[40.688738,-74.043871]\" >\n *     <street-view-panorama\n *       click-to-go=\"true\"\n *       disable-default-ui=\"true\"\n *       disable-double-click-zoom=\"true\"\n *       enable-close-button=\"true\"\n *       pano=\"my-pano\"\n *       position=\"40.688738,-74.043871\"\n *       pov=\"{heading:0, pitch: 90}\"\n *       scrollwheel=\"false\"\n *       visible=\"true\">\n *     </street-view-panorama>\n *   </map>\n */\n/* global google, document */\n(function() {\n  'use strict';\n\n  var streetViewPanorama = function(Attr2MapOptions, NgMap) {\n    var parser = Attr2MapOptions;\n\n    var getStreetViewPanorama = function(map, options, events) {\n      var svp, container;\n      if (options.container) {\n        container = document.getElementById(options.container);\n        container = container || document.querySelector(options.container);\n      }\n      if (container) {\n        svp = new google.maps.StreetViewPanorama(container, options);\n      } else {\n        svp = map.getStreetView();\n        svp.setOptions(options);\n      }\n\n      for (var eventName in events) {\n        eventName &&\n          google.maps.event.addListener(svp, eventName, events[eventName]);\n      }\n      return svp;\n    };\n\n    var linkFunc = function(scope, element, attrs) {\n      var filtered = parser.filter(attrs);\n      var options = parser.getOptions(filtered, {scope: scope});\n      var controlOptions = parser.getControlOptions(filtered);\n      var svpOptions = angular.extend(options, controlOptions);\n\n      var svpEvents = parser.getEvents(scope, filtered);\n      void 0;\n\n      NgMap.getMap().then(function(map) {\n        var svp = getStreetViewPanorama(map, svpOptions, svpEvents);\n\n        map.setStreetView(svp);\n        (!svp.getPosition()) && svp.setPosition(map.getCenter());\n        google.maps.event.addListener(svp, 'position_changed', function() {\n          if (svp.getPosition() !== map.getCenter()) {\n            map.setCenter(svp.getPosition());\n          }\n        });\n        //needed for geo-callback\n        var listener =\n          google.maps.event.addListener(map, 'center_changed', function() {\n            svp.setPosition(map.getCenter());\n            google.maps.event.removeListener(listener);\n          });\n      });\n\n    }; //link\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n      link: linkFunc\n    };\n\n  };\n  streetViewPanorama.$inject = ['Attr2MapOptions', 'NgMap'];\n\n  angular.module('ngMap').directive('streetViewPanorama', streetViewPanorama);\n})();\n\n/**\n * @ngdoc directive\n * @name traffic-layer\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n *   <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *     <traffic-layer></traffic-layer>\n *    </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('trafficLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getLayer = function(options, events) {\n      var layer = new google.maps.TrafficLayer(options);\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var orgAttrs = parser.orgAttributes(element);\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered);\n        void 0;\n\n        var layer = getLayer(options, events);\n        mapController.addObject('trafficLayers', layer);\n        mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers\n        element.bind('$destroy', function() {\n          mapController.deleteObject('trafficLayers', layer);\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc directive\n * @name transit-layer\n * @param Attr2MapOptions {service} convert html attribute to Google map api options\n * @description\n *   Requires:  map directive\n *   Restrict To:  Element\n *\n * @example\n * Example:\n *\n *  <map zoom=\"13\" center=\"34.04924594193164, -118.24104309082031\">\n *    <transit-layer></transit-layer>\n *  </map>\n */\n(function() {\n  'use strict';\n\n  angular.module('ngMap').directive('transitLayer', [\n    'Attr2MapOptions', function(Attr2MapOptions) {\n    var parser = Attr2MapOptions;\n\n    var getLayer = function(options, events) {\n      var layer = new google.maps.TransitLayer(options);\n      for (var eventName in events) {\n        google.maps.event.addListener(layer, eventName, events[eventName]);\n      }\n      return layer;\n    };\n\n    return {\n      restrict: 'E',\n      require: ['?^map','?^ngMap'],\n\n      link: function(scope, element, attrs, mapController) {\n        mapController = mapController[0]||mapController[1];\n\n        var orgAttrs = parser.orgAttributes(element);\n        var filtered = parser.filter(attrs);\n        var options = parser.getOptions(filtered, {scope: scope});\n        var events = parser.getEvents(scope, filtered);\n        void 0;\n\n        var layer = getLayer(options, events);\n        mapController.addObject('transitLayers', layer);\n        mapController.observeAttrSetObj(orgAttrs, attrs, layer);  //observers\n        element.bind('$destroy', function() {\n          mapController.deleteObject('transitLayers', layer);\n        });\n      }\n     }; // return\n  }]);\n})();\n\n/**\n * @ngdoc filter\n * @name camel-case\n * @description\n *   Converts string to camel cased\n */\n(function() {\n  'use strict';\n\n  var SPECIAL_CHARS_REGEXP = /([\\:\\-\\_]+(.))/g;\n  var MOZ_HACK_REGEXP = /^moz([A-Z])/;\n\n  var camelCaseFilter = function() {\n    return function(name) {\n      return name.\n        replace(SPECIAL_CHARS_REGEXP,\n          function(_, separator, letter, offset) {\n            return offset ? letter.toUpperCase() : letter;\n        }).\n        replace(MOZ_HACK_REGEXP, 'Moz$1');\n    };\n  };\n\n  angular.module('ngMap').filter('camelCase', camelCaseFilter);\n})();\n\n/**\n * @ngdoc filter\n * @name escape-regex\n * @description\n *   Escapes all regex special characters in a string\n */\n(function() {\n  'use strict';\n\n\n\n  var escapeRegexpFilter = function() {\n    return function(string) {\n\t\t\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n\t\t};\n  };\n\n  angular.module('ngMap').filter('escapeRegexp', escapeRegexpFilter);\n})();\n\n/**\n * @ngdoc filter\n * @name jsonize\n * @description\n *   Converts json-like string to json string\n */\n(function() {\n  'use strict';\n\n  var jsonizeFilter = function() {\n    return function(str) {\n      try {       // if parsable already, return as it is\n        JSON.parse(str);\n        return str;\n      } catch(e) { // if not parsable, change little\n        return str\n          // wrap keys without quote with valid double quote\n          .replace(/([\\$\\w]+)\\s*:/g,\n            function(_, $1) {\n              return '\"'+$1+'\":';\n            }\n          )\n          // replacing single quote wrapped ones to double quote\n          .replace(/'([^']+)'/g,\n            function(_, $1) {\n              return '\"'+$1+'\"';\n            }\n          )\n          .replace(/''/g, '\"\"');\n      }\n    };\n  };\n\n  angular.module('ngMap').filter('jsonize', jsonizeFilter);\n})();\n\n/**\n * @ngdoc service\n * @name Attr2MapOptions\n * @description\n *   Converts tag attributes to options used by google api v3 objects\n */\n/* global google */\n(function() {\n  'use strict';\n\n  //i.e. \"2015-08-12T06:12:40.858Z\"\n  var isoDateRE =\n    /^(\\d{4}\\-\\d\\d\\-\\d\\d([tT][\\d:\\.]*)?)([zZ]|([+\\-])(\\d\\d):?(\\d\\d))?$/;\n\n  var Attr2MapOptions = function(\n      $parse, $timeout, $log, $interpolate, NavigatorGeolocation, GeoCoder,\n      camelCaseFilter, jsonizeFilter, escapeRegExp\n    ) {\n\n    var exprStartSymbol = $interpolate.startSymbol();\n    var exprEndSymbol = $interpolate.endSymbol();\n\n    /**\n     * Returns the attributes of an element as hash\n     * @memberof Attr2MapOptions\n     * @param {HTMLElement} el html element\n     * @returns {Hash} attributes\n     */\n    var orgAttributes = function(el) {\n      (el.length > 0) && (el = el[0]);\n      var orgAttributes = {};\n      for (var i=0; i<el.attributes.length; i++) {\n        var attr = el.attributes[i];\n        orgAttributes[attr.name] = attr.value;\n      }\n      return orgAttributes;\n    };\n\n    var getJSON = function(input) {\n      var re =/^[\\+\\-]?[0-9\\.]+,[ ]*\\ ?[\\+\\-]?[0-9\\.]+$/; //lat,lng\n      if (input.match(re)) {\n        input = \"[\"+input+\"]\";\n      }\n      return JSON.parse(jsonizeFilter(input));\n    };\n    \n    var getLatLng = function(input) {\n      var output = input;\n      if (input[0].constructor == Array) { \n        if ((input[0][0].constructor == Array && input[0][0].length == 2) || input[0][0].constructor == Object) {\n            var preoutput;\n            var outputArray = [];\n            for (var i = 0; i < input.length; i++) {\n                preoutput = input[i].map(function(el){\n                    return new google.maps.LatLng(el[0], el[1]);\n                });\n                outputArray.push(preoutput);\n            }\n            output = outputArray;\n        } else {\n            output = input.map(function(el) {\n                return new google.maps.LatLng(el[0], el[1]);\n            });\n        }\n      } else if (!isNaN(parseFloat(input[0])) && isFinite(input[0])) {\n        output = new google.maps.LatLng(output[0], output[1]);\n      }\n      return output;\n    };\n\n    var toOptionValue = function(input, options) {\n      var output;\n      try { // 1. Number?\n        output = getNumber(input);\n      } catch(err) {\n        try { // 2. JSON?\n          var output = getJSON(input);\n          if (output instanceof Array) {\n            if (output[0].constructor == Object) {\n              output = output;\n            } else if (output[0] instanceof Array) {\n              if (output[0][0].constructor == Object) {\n                output = output;\n              } else {\n                output = getLatLng(output);\n              }\n            } else {\n                output = getLatLng(output);\n            }\n          }\n          // JSON is an object (not array or null)\n          else if (output === Object(output)) {\n            // check for nested hashes and convert to Google API options\n            var newOptions = options;\n            newOptions.doNotConverStringToNumber = true;\n            output = getOptions(output, newOptions);\n          }\n        } catch(err2) {\n          // 3. Google Map Object function Expression. i.e. LatLng(80,-49)\n          if (input.match(/^[A-Z][a-zA-Z0-9]+\\(.*\\)$/)) {\n            try {\n              var exp = \"new google.maps.\"+input;\n              output = eval(exp); /* jshint ignore:line */\n            } catch(e) {\n              output = input;\n            }\n          // 4. Google Map Object constant Expression. i.e. MayTypeId.HYBRID\n          } else if (input.match(/^([A-Z][a-zA-Z0-9]+)\\.([A-Z]+)$/)) {\n            try {\n              var matches = input.match(/^([A-Z][a-zA-Z0-9]+)\\.([A-Z]+)$/);\n              output = google.maps[matches[1]][matches[2]];\n            } catch(e) {\n              output = input;\n            }\n          // 5. Google Map Object constant Expression. i.e. HYBRID\n          } else if (input.match(/^[A-Z]+$/)) {\n            try {\n              var capitalizedKey = options.key.charAt(0).toUpperCase() +\n                options.key.slice(1);\n              if (options.key.match(/temperatureUnit|windSpeedUnit|labelColor/)) {\n                capitalizedKey = capitalizedKey.replace(/s$/,\"\");\n                output = google.maps.weather[capitalizedKey][input];\n              } else {\n                output = google.maps[capitalizedKey][input];\n              }\n            } catch(e) {\n              output = input;\n            }\n          // 6. Date Object as ISO String\n          } else if (input.match(isoDateRE)) {\n            try {\n              output = new Date(input);\n            } catch(e) {\n              output = input;\n            }\n          // 7. evaluate dynamically bound values\n        } else if (input.match(new RegExp('^' + escapeRegExp(exprStartSymbol))) && options.scope) {\n            try {\n              var expr = input.replace(new RegExp(escapeRegExp(exprStartSymbol)),'').replace(new RegExp(escapeRegExp(exprEndSymbol), 'g'),'');\n              output = options.scope.$eval(expr);\n            } catch (err) {\n              output = input;\n            }\n          } else {\n            output = input;\n          }\n        } // catch(err2)\n      } // catch(err)\n\n      // convert output more for center and position\n      if (\n        (options.key == 'center' || options.key == 'position') &&\n        output instanceof Array\n      ) {\n        output = new google.maps.LatLng(output[0], output[1]);\n      }\n\n      // convert output more for shape bounds\n      if (options.key == 'bounds' && output instanceof Array) {\n        output = new google.maps.LatLngBounds(output[0], output[1]);\n      }\n\n      // convert output more for shape icons\n      if (options.key == 'icons' && output instanceof Array) {\n\n        for (var i=0; i<output.length; i++) {\n          var el = output[i];\n          if (el.icon.path.match(/^[A-Z_]+$/)) {\n            el.icon.path =  google.maps.SymbolPath[el.icon.path];\n          }\n        }\n      }\n\n      // convert output more for marker icon\n      if (options.key == 'icon' && output instanceof Object) {\n        if ((\"\"+output.path).match(/^[A-Z_]+$/)) {\n          output.path = google.maps.SymbolPath[output.path];\n        }\n        for (var key in output) { //jshint ignore:line\n          var arr = output[key];\n          if (key == \"anchor\" || key == \"origin\" || key == \"labelOrigin\") {\n            output[key] = new google.maps.Point(arr[0], arr[1]);\n          } else if (key == \"size\" || key == \"scaledSize\") {\n            output[key] = new google.maps.Size(arr[0], arr[1]);\n          }\n        }\n      }\n\n      return output;\n    };\n\n    var getAttrsToObserve = function(attrs) {\n      var attrsToObserve = [];\n      var exprRegExp = new RegExp(escapeRegExp(exprStartSymbol) + '.*' + escapeRegExp(exprEndSymbol), 'g');\n\n      if (!attrs.noWatcher) {\n        for (var attrName in attrs) { //jshint ignore:line\n          var attrValue = attrs[attrName];\n          if (attrValue && attrValue.match(exprRegExp)) { // if attr value is {{..}}\n            attrsToObserve.push(camelCaseFilter(attrName));\n          }\n        }\n      }\n\n      return attrsToObserve;\n    };\n\n    /**\n     * filters attributes by skipping angularjs methods $.. $$..\n     * @memberof Attr2MapOptions\n     * @param {Hash} attrs tag attributes\n     * @returns {Hash} filterd attributes\n     */\n    var filter = function(attrs) {\n      var options = {};\n      for(var key in attrs) {\n        if (key.match(/^\\$/) || key.match(/^ng[A-Z]/)) {\n          void(0);\n        } else {\n          options[key] = attrs[key];\n        }\n      }\n      return options;\n    };\n\n    /**\n     * converts attributes hash to Google Maps API v3 options\n     * ```\n     *  . converts numbers to number\n     *  . converts class-like string to google maps instance\n     *    i.e. `LatLng(1,1)` to `new google.maps.LatLng(1,1)`\n     *  . converts constant-like string to google maps constant\n     *    i.e. `MapTypeId.HYBRID` to `google.maps.MapTypeId.HYBRID`\n     *    i.e. `HYBRID\"` to `google.maps.MapTypeId.HYBRID`\n     * ```\n     * @memberof Attr2MapOptions\n     * @param {Hash} attrs tag attributes\n     * @param {Hash} options\n     * @returns {Hash} options converted attributess\n     */\n    var getOptions = function(attrs, params) {\n      params = params || {};\n      var options = {};\n      for(var key in attrs) {\n        if (attrs[key] || attrs[key] === 0) {\n          if (key.match(/^on[A-Z]/)) { //skip events, i.e. on-click\n            continue;\n          } else if (key.match(/ControlOptions$/)) { // skip controlOptions\n            continue;\n          } else {\n            // nested conversions need to be typechecked\n            // (non-strings are fully converted)\n            if (typeof attrs[key] !== 'string') {\n              options[key] = attrs[key];\n            } else {\n              if (params.doNotConverStringToNumber &&\n                attrs[key].match(/^[0-9]+$/)\n              ) {\n                options[key] = attrs[key];\n              } else {\n                options[key] = toOptionValue(attrs[key], {key: key, scope: params.scope});\n              }\n            }\n          }\n        } // if (attrs[key])\n      } // for(var key in attrs)\n      return options;\n    };\n\n    /**\n     * converts attributes hash to scope-specific event function\n     * @memberof Attr2MapOptions\n     * @param {scope} scope angularjs scope\n     * @param {Hash} attrs tag attributes\n     * @returns {Hash} events converted events\n     */\n    var getEvents = function(scope, attrs) {\n      var events = {};\n      var toLowercaseFunc = function($1){\n        return \"_\"+$1.toLowerCase();\n      };\n      var EventFunc = function(attrValue) {\n        // funcName(argsStr)\n        var matches = attrValue.match(/([^\\(]+)\\(([^\\)]*)\\)/);\n        var funcName = matches[1];\n        var argsStr = matches[2].replace(/event[ ,]*/,'');  //remove string 'event'\n        var argsExpr = $parse(\"[\"+argsStr+\"]\"); //for perf when triggering event\n        return function(event) {\n          var args = argsExpr(scope); //get args here to pass updated model values\n          function index(obj,i) {return obj[i];}\n          var f = funcName.split('.').reduce(index, scope);\n          f && f.apply(this, [event].concat(args));\n          $timeout( function() {\n            scope.$apply();\n          });\n        };\n      };\n\n      for(var key in attrs) {\n        if (attrs[key]) {\n          if (!key.match(/^on[A-Z]/)) { //skip if not events\n            continue;\n          }\n\n          //get event name as underscored. i.e. zoom_changed\n          var eventName = key.replace(/^on/,'');\n          eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1);\n          eventName = eventName.replace(/([A-Z])/g, toLowercaseFunc);\n\n          var attrValue = attrs[key];\n          events[eventName] = new EventFunc(attrValue);\n        }\n      }\n      return events;\n    };\n\n    /**\n     * control means map controls, i.e streetview, pan, etc, not a general control\n     * @memberof Attr2MapOptions\n     * @param {Hash} filtered filtered tag attributes\n     * @returns {Hash} Google Map options\n     */\n    var getControlOptions = function(filtered) {\n      var controlOptions = {};\n      if (typeof filtered != 'object') {\n        return false;\n      }\n\n      for (var attr in filtered) {\n        if (filtered[attr]) {\n          if (!attr.match(/(.*)ControlOptions$/)) {\n            continue; // if not controlOptions, skip it\n          }\n\n          //change invalid json to valid one, i.e. {foo:1} to {\"foo\": 1}\n          var orgValue = filtered[attr];\n          var newValue = orgValue.replace(/'/g, '\"');\n          newValue = newValue.replace(/([^\"]+)|(\"[^\"]+\")/g, function($0, $1, $2) {\n            if ($1) {\n              return $1.replace(/([a-zA-Z0-9]+?):/g, '\"$1\":');\n            } else {\n              return $2;\n            }\n          });\n          try {\n            var options = JSON.parse(newValue);\n            for (var key in options) { //assign the right values\n              if (options[key]) {\n                var value = options[key];\n                if (typeof value === 'string') {\n                  value = value.toUpperCase();\n                } else if (key === \"mapTypeIds\") {\n                  value = value.map( function(str) {\n                    if (str.match(/^[A-Z]+$/)) { // if constant\n                      return google.maps.MapTypeId[str.toUpperCase()];\n                    } else { // else, custom map-type\n                      return str;\n                    }\n                  });\n                }\n\n                if (key === \"style\") {\n                  var str = attr.charAt(0).toUpperCase() + attr.slice(1);\n                  var objName = str.replace(/Options$/,'')+\"Style\";\n                  options[key] = google.maps[objName][value];\n                } else if (key === \"position\") {\n                  options[key] = google.maps.ControlPosition[value];\n                } else {\n                  options[key] = value;\n                }\n              }\n            }\n            controlOptions[attr] = options;\n          } catch (e) {\n            void 0;\n          }\n        }\n      } // for\n\n      return controlOptions;\n    };\n\n    return {\n      filter: filter,\n      getOptions: getOptions,\n      getEvents: getEvents,\n      getControlOptions: getControlOptions,\n      toOptionValue: toOptionValue,\n      getAttrsToObserve: getAttrsToObserve,\n      orgAttributes: orgAttributes\n    }; // return\n\n  };\n  Attr2MapOptions.$inject= [\n    '$parse', '$timeout', '$log', '$interpolate', 'NavigatorGeolocation', 'GeoCoder',\n    'camelCaseFilter', 'jsonizeFilter', 'escapeRegexpFilter'\n  ];\n\n  angular.module('ngMap').service('Attr2MapOptions', Attr2MapOptions);\n})();\n\n/**\n * @ngdoc service\n * @name GeoCoder\n * @description\n *   Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)\n *   service for Google Geocoder service\n */\n(function() {\n  'use strict';\n  var $q;\n  /**\n   * @memberof GeoCoder\n   * @param {Hash} options\n   *   https://developers.google.com/maps/documentation/geocoding/#geocoding\n   * @example\n   * ```\n   *   GeoCoder.geocode({address: 'the cn tower'}).then(function(result) {\n   *     //... do something with result\n   *   });\n   * ```\n   * @returns {HttpPromise} Future object\n   */\n  var geocodeFunc = function(options) {\n    var deferred = $q.defer();\n    var geocoder = new google.maps.Geocoder();\n    geocoder.geocode(options, function (results, status) {\n      if (status == google.maps.GeocoderStatus.OK) {\n        deferred.resolve(results);\n      } else {\n        deferred.reject(status);\n      }\n    });\n    return deferred.promise;\n  };\n\n  var GeoCoder = function(_$q_) {\n    $q = _$q_;\n    return {\n      geocode : geocodeFunc\n    };\n  };\n  GeoCoder.$inject = ['$q'];\n\n  angular.module('ngMap').service('GeoCoder', GeoCoder);\n})();\n\n/**\n * @ngdoc service\n * @name GoogleMapsApi\n * @description\n *   Load Google Maps API Service\n */\n(function() {\n  'use strict';\n  var $q;\n  var $timeout;\n\n  var GoogleMapsApi = function(_$q_, _$timeout_) {\n    $q = _$q_;\n    $timeout = _$timeout_;\n\n    return {\n\n      /**\n       * Load google maps into document by creating a script tag\n       * @memberof GoogleMapsApi\n       * @param {string} mapsUrl\n       * @example\n       *   GoogleMapsApi.load(myUrl).then(function() {\n       *     console.log('google map has been loaded')\n       *   });\n       */\n      load: function (mapsUrl) {\n\n        var deferred = $q.defer();\n\n        if (window.google === undefined || window.google.maps === undefined) {\n\n          window.lazyLoadCallback = function() {\n            $timeout(function() { /* give some time to load */\n              deferred.resolve(window.google)\n            }, 100);\n          };\n\n          var scriptEl = document.createElement('script');\n          scriptEl.src = mapsUrl +\n            (mapsUrl.indexOf('?') > -1 ? '&' : '?') +\n            'callback=lazyLoadCallback';\n\n          if (!document.querySelector('script[src=\"' + scriptEl.src + '\"]')) {\n            document.body.appendChild(scriptEl);\n          }\n        } else {\n          deferred.resolve(window.google)\n        }\n\n        return deferred.promise;\n      }\n\n    }\n  }\n  GoogleMapsApi.$inject = ['$q', '$timeout'];\n\n  angular.module('ngMap').service('GoogleMapsApi', GoogleMapsApi);\n})();\n\n\n\n/**\n * @ngdoc service\n * @name NavigatorGeolocation\n * @description\n *  Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)\n *  service for navigator.geolocation methods\n */\n/* global google */\n(function() {\n  'use strict';\n  var $q;\n\n  /**\n   * @memberof NavigatorGeolocation\n   * @param {Object} geoLocationOptions the navigator geolocations options.\n   *  i.e. { maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }.\n   *  If none specified, { timeout: 5000 }. \n   *  If timeout not specified, timeout: 5000 added\n   * @param {function} success success callback function\n   * @param {function} failure failure callback function\n   * @example\n   * ```\n   *  NavigatorGeolocation.getCurrentPosition()\n   *    .then(function(position) {\n   *      var lat = position.coords.latitude, lng = position.coords.longitude;\n   *      .. do something lat and lng\n   *    });\n   * ```\n   * @returns {HttpPromise} Future object\n   */\n  var getCurrentPosition = function(geoLocationOptions) {\n    var deferred = $q.defer();\n    if (navigator.geolocation) {\n\n      if (geoLocationOptions === undefined) {\n        geoLocationOptions = { timeout: 5000 };\n      }\n      else if (geoLocationOptions.timeout === undefined) {\n        geoLocationOptions.timeout = 5000;\n      }\n\n      navigator.geolocation.getCurrentPosition(\n        function(position) {\n          deferred.resolve(position);\n        }, function(evt) {\n          void 0;\n          deferred.reject(evt);\n        },\n        geoLocationOptions\n      );\n    } else {\n      deferred.reject(\"Browser Geolocation service failed.\");\n    }\n    return deferred.promise;\n  };\n\n  var NavigatorGeolocation = function(_$q_) {\n    $q = _$q_;\n    return {\n      getCurrentPosition: getCurrentPosition\n    };\n  };\n  NavigatorGeolocation.$inject = ['$q'];\n\n  angular.module('ngMap').\n    service('NavigatorGeolocation', NavigatorGeolocation);\n})();\n\n/**\n * @ngdoc factory\n * @name NgMapPool\n * @description\n *   Provide map instance to avoid memory leak\n */\n(function() {\n  'use strict';\n  /**\n   * @memberof NgMapPool\n   * @desc map instance pool\n   */\n  var mapInstances = [];\n  var $window, $document, $timeout;\n\n  var add = function(el) {\n    var mapDiv = $document.createElement(\"div\");\n    mapDiv.style.width = \"100%\";\n    mapDiv.style.height = \"100%\";\n    el.appendChild(mapDiv);\n    var map = new $window.google.maps.Map(mapDiv, {});\n    mapInstances.push(map);\n    return map;\n  };\n\n  var findById = function(el, id) {\n    var notInUseMap;\n    for (var i=0; i<mapInstances.length; i++) {\n      var map = mapInstances[i];\n      if (map.id == id && !map.inUse) {\n        var mapDiv = map.getDiv();\n        el.appendChild(mapDiv);\n        notInUseMap = map;\n        break;\n      }\n    }\n    return notInUseMap;\n  };\n\n  var findUnused = function(el) { //jshint ignore:line\n    var notInUseMap;\n    for (var i=0; i<mapInstances.length; i++) {\n      var map = mapInstances[i];\n      if (map.id) {\n        continue;\n      }\n      if (!map.inUse) {\n        var mapDiv = map.getDiv();\n        el.appendChild(mapDiv);\n        notInUseMap = map;\n        break;\n      }\n    }\n    return notInUseMap;\n  };\n\n  /**\n   * @memberof NgMapPool\n   * @function getMapInstance\n   * @param {HtmlElement} el map container element\n   * @return map instance for the given element\n   */\n  var getMapInstance = function(el) {\n    var map = findById(el, el.id) || findUnused(el);\n    if (!map) {\n      map = add(el);\n    } else {\n      /* firing map idle event, which is used by map controller */\n      $timeout(function() {\n        google.maps.event.trigger(map, 'idle');\n      }, 100);\n    }\n    map.inUse = true;\n    return map;\n  };\n\n  /**\n   * @memberof NgMapPool\n   * @function returnMapInstance\n   * @param {Map} an instance of google.maps.Map\n   * @desc sets the flag inUse of the given map instance to false, so that it \n   * can be reused later\n   */\n  var returnMapInstance = function(map) {\n    map.inUse = false;\n  };\n  \n  /**\n   * @memberof NgMapPool\n   * @function resetMapInstances\n   * @desc resets mapInstance array\n   */\n  var resetMapInstances = function() {\n    for(var i = 0;i < mapInstances.length;i++) {\n        mapInstances[i] = null;\n    }\n    mapInstances = [];\n  };\n  \n  /**\n   * @memberof NgMapPool\n   * @function deleteMapInstance\n   * @desc delete a mapInstance\n   */\n  var deleteMapInstance= function(mapId) {\n\t  for( var i=0; i<mapInstances.length; i++ ) {\n\t\t  if( (mapInstances[i] !== null) && (mapInstances[i].id == mapId)) {\n\t\t\t  mapInstances[i]= null;\n\t\t\t  mapInstances.splice( i, 1 );\n\t\t  }\n\t  }\n  };\n\n  var NgMapPool = function(_$document_, _$window_, _$timeout_) {\n    $document = _$document_[0], $window = _$window_, $timeout = _$timeout_;\n\n    return {\n\t  mapInstances: mapInstances,\n      resetMapInstances: resetMapInstances,\n      getMapInstance: getMapInstance,\n      returnMapInstance: returnMapInstance,\n      deleteMapInstance: deleteMapInstance\n    };\n  };\n\n  NgMapPool.$inject = [ '$document', '$window', '$timeout'];\n\n  angular.module('ngMap').factory('NgMapPool', NgMapPool);\n\n})();\n\n/**\n * @ngdoc provider\n * @name NgMap\n * @description\n *  common utility service for ng-map\n */\n(function() {\n  'use strict';\n  var $window, $document, $q;\n  var NavigatorGeolocation, Attr2MapOptions, GeoCoder, camelCaseFilter, NgMapPool;\n\n  var mapControllers = {};\n\n  var getStyle = function(el, styleProp) {\n    var y;\n    if (el.currentStyle) {\n      y = el.currentStyle[styleProp];\n    } else if ($window.getComputedStyle) {\n      y = $document.defaultView.\n        getComputedStyle(el, null).\n        getPropertyValue(styleProp);\n    }\n    return y;\n  };\n\n  /**\n   * @memberof NgMap\n   * @function initMap\n   * @param id optional, id of the map. default 0\n   */\n  var initMap = function(id) {\n    var ctrl = mapControllers[id || 0];\n    if (!(ctrl.map instanceof google.maps.Map)) {\n      ctrl.initializeMap();\n      return ctrl.map;\n    } else {\n      void 0;\n    }\n  };\n\n  /**\n   * @memberof NgMap\n   * @function getMap\n   * @param {String} optional, id e.g., 'foo'\n   * @returns promise\n   */\n  var getMap = function(id, options) {\n    options = options || {};\n    id = typeof id === 'object' ? id.id : id;\n\n    var deferred = $q.defer();\n    var timeout = options.timeout || 10000;\n\n    function waitForMap(timeElapsed){\n      var keys = Object.keys(mapControllers);\n      var theFirstController = mapControllers[keys[0]];\n      if(id && mapControllers[id]){\n        deferred.resolve(mapControllers[id].map);\n      } else if (!id && theFirstController && theFirstController.map) {\n        deferred.resolve(theFirstController.map);\n      } else if (timeElapsed > timeout) {\n        deferred.reject('could not find map');\n      } else {\n        $window.setTimeout( function(){\n          waitForMap(timeElapsed+100);\n        }, 100);\n      }\n    }\n    waitForMap(0);\n\n    return deferred.promise;\n  };\n\n  /**\n   * @memberof NgMap\n   * @function addMap\n   * @param mapController {__MapContoller} a map controller\n   * @returns promise\n   */\n  var addMap = function(mapCtrl) {\n    if (mapCtrl.map) {\n      var len = Object.keys(mapControllers).length;\n      mapControllers[mapCtrl.map.id || len] = mapCtrl;\n    }\n  };\n\n  /**\n   * @memberof NgMap\n   * @function deleteMap\n   * @param mapController {__MapContoller} a map controller\n   */\n  var deleteMap = function(mapCtrl) {\n    var len = Object.keys(mapControllers).length - 1;\n    var mapId = mapCtrl.map.id || len;\n    if (mapCtrl.map) {\n      for (var eventName in mapCtrl.eventListeners) {\n        void 0;\n        var listener = mapCtrl.eventListeners[eventName];\n        google.maps.event.removeListener(listener);\n      }\n      if (mapCtrl.map.controls) {\n        mapCtrl.map.controls.forEach(function(ctrl) {\n          ctrl.clear();\n        });\n      }\n    }\n\n    //Remove Heatmap Layers\n    if (mapCtrl.map.heatmapLayers) {\n      Object.keys(mapCtrl.map.heatmapLayers).forEach(function (layer) {\n        mapCtrl.deleteObject('heatmapLayers', mapCtrl.map.heatmapLayers[layer]);\n      });\n    }\n\n    NgMapPool.deleteMapInstance(mapId);\n\n    delete mapControllers[mapId];\n  };\n\n  /**\n   * @memberof NgMap\n   * @function getGeoLocation\n   * @param {String} address\n   * @param {Hash} options geo options\n   * @returns promise\n   */\n  var getGeoLocation = function(string, options) {\n    var deferred = $q.defer();\n    if (!string || string.match(/^current/i)) { // current location\n      NavigatorGeolocation.getCurrentPosition(options).then(\n        function(position) {\n          var lat = position.coords.latitude;\n          var lng = position.coords.longitude;\n          var latLng = new google.maps.LatLng(lat,lng);\n          deferred.resolve(latLng);\n        },\n        function(error) {\n          deferred.reject(error);\n        }\n      );\n    } else {\n      GeoCoder.geocode({address: string}).then(\n        function(results) {\n          deferred.resolve(results[0].geometry.location);\n        },\n        function(error) {\n          deferred.reject(error);\n        }\n      );\n      // var geocoder = new google.maps.Geocoder();\n      // geocoder.geocode(options, function (results, status) {\n      //   if (status == google.maps.GeocoderStatus.OK) {\n      //     deferred.resolve(results);\n      //   } else {\n      //     deferred.reject(status);\n      //   }\n      // });\n    }\n\n    return deferred.promise;\n  };\n\n  /**\n   * @memberof NgMap\n   * @function observeAndSet\n   * @param {String} attrName attribute name\n   * @param {Object} object A Google maps object to be changed\n   * @returns attribue observe function\n   */\n  var observeAndSet = function(attrName, object) {\n    void 0;\n    return function(val) {\n      if (val) {\n        var setMethod = camelCaseFilter('set-'+attrName);\n        var optionValue = Attr2MapOptions.toOptionValue(val, {key: attrName});\n        if (object[setMethod]) { //if set method does exist\n          void 0;\n          /* if an location is being observed */\n          if (attrName.match(/center|position/) &&\n            typeof optionValue == 'string') {\n            getGeoLocation(optionValue).then(function(latlng) {\n              object[setMethod](latlng);\n            });\n          } else {\n            object[setMethod](optionValue);\n          }\n        }\n      }\n    };\n  };\n\n  /**\n   * @memberof NgMap\n   * @function setStyle\n   * @param {HtmlElement} map contriner element\n   * @desc set display, width, height of map container element\n   */\n  var setStyle = function(el) {\n    //if style is not given to the map element, set display and height\n    var defaultStyle = el.getAttribute('default-style');\n    if (defaultStyle == \"true\") {\n      el.style.display = 'block';\n      el.style.height = '300px';\n    } else {\n      if (getStyle(el, 'display') != \"block\") {\n        el.style.display = 'block';\n      }\n      if (getStyle(el, 'height').match(/^(0|auto)/)) {\n        el.style.height = '300px';\n      }\n    }\n  };\n\n  angular.module('ngMap').provider('NgMap', function() {\n    var defaultOptions = {};\n\n    /**\n     * @memberof NgMap\n     * @function setDefaultOptions\n     * @param {Hash} options\n     * @example\n     *  app.config(function(NgMapProvider) {\n     *    NgMapProvider.setDefaultOptions({\n     *      marker: {\n     *        optimized: false\n     *      }\n     *    });\n     *  });\n     */\n    this.setDefaultOptions = function(options) {\n      defaultOptions = options;\n    };\n\n    var NgMap = function(\n        _$window_, _$document_, _$q_,\n        _NavigatorGeolocation_, _Attr2MapOptions_,\n        _GeoCoder_, _camelCaseFilter_, _NgMapPool_\n      ) {\n      $window = _$window_;\n      $document = _$document_[0];\n      $q = _$q_;\n      NavigatorGeolocation = _NavigatorGeolocation_;\n      Attr2MapOptions = _Attr2MapOptions_;\n      GeoCoder = _GeoCoder_;\n      camelCaseFilter = _camelCaseFilter_;\n      NgMapPool = _NgMapPool_;\n\n      return {\n        defaultOptions: defaultOptions,\n        addMap: addMap,\n        deleteMap: deleteMap,\n        getMap: getMap,\n        initMap: initMap,\n        setStyle: setStyle,\n        getGeoLocation: getGeoLocation,\n        observeAndSet: observeAndSet\n      };\n    };\n    NgMap.$inject = [\n      '$window', '$document', '$q',\n      'NavigatorGeolocation', 'Attr2MapOptions',\n      'GeoCoder', 'camelCaseFilter', 'NgMapPool'\n    ];\n\n    this.$get = NgMap;\n  });\n})();\n\n/**\n * @ngdoc service\n * @name StreetView\n * @description\n *  Provides [defered/promise API](https://docs.angularjs.org/api/ng/service/$q)\n *  service for [Google StreetViewService]\n *  (https://developers.google.com/maps/documentation/javascript/streetview)\n */\n(function() {\n  'use strict';\n  var $q;\n\n  /**\n   * Retrieves panorama id from the given map (and or position)\n   * @memberof StreetView\n   * @param {map} map Google map instance\n   * @param {LatLng} latlng Google LatLng instance\n   *   default: the center of the map\n   * @example\n   *   StreetView.getPanorama(map).then(function(panoId) {\n   *     $scope.panoId = panoId;\n   *   });\n   * @returns {HttpPromise} Future object\n   */\n  var getPanorama = function(map, latlng) {\n    latlng = latlng || map.getCenter();\n    var deferred = $q.defer();\n    var svs = new google.maps.StreetViewService();\n    svs.getPanoramaByLocation( (latlng||map.getCenter), 100,\n      function (data, status) {\n        // if streetView available\n        if (status === google.maps.StreetViewStatus.OK) {\n          deferred.resolve(data.location.pano);\n        } else {\n          // no street view available in this range, or some error occurred\n          deferred.resolve(false);\n          //deferred.reject('Geocoder failed due to: '+ status);\n        }\n      }\n    );\n    return deferred.promise;\n  };\n\n  /**\n   * Set panorama view on the given map with the panorama id\n   * @memberof StreetView\n   * @param {map} map Google map instance\n   * @param {String} panoId Panorama id fro getPanorama method\n   * @example\n   *   StreetView.setPanorama(map, panoId);\n   */\n  var setPanorama = function(map, panoId) {\n    var svp = new google.maps.StreetViewPanorama(\n      map.getDiv(), {enableCloseButton: true}\n    );\n    svp.setPano(panoId);\n  };\n\n  var StreetView = function(_$q_) {\n    $q = _$q_;\n\n    return {\n      getPanorama: getPanorama,\n      setPanorama: setPanorama\n    };\n  };\n  StreetView.$inject = ['$q'];\n\n  angular.module('ngMap').service('StreetView', StreetView);\n})();\n\r\nreturn 'ngMap';\r\n}));\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/ngmap/build/scripts/ng-map.js\n// module id = 7\n// module chunks = 0","/**\n * @license AngularJS v1.6.3\n * (c) 2010-2017 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window, angular) {'use strict';\n\n/**\n * @ngdoc module\n * @name ngCookies\n * @description\n *\n * # ngCookies\n *\n * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.\n *\n *\n * <div doc-module-components=\"ngCookies\"></div>\n *\n * See {@link ngCookies.$cookies `$cookies`} for usage.\n */\n\n\nangular.module('ngCookies', ['ng']).\n  info({ angularVersion: '1.6.3' }).\n  /**\n   * @ngdoc provider\n   * @name $cookiesProvider\n   * @description\n   * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service.\n   * */\n   provider('$cookies', [/** @this */function $CookiesProvider() {\n    /**\n     * @ngdoc property\n     * @name $cookiesProvider#defaults\n     * @description\n     *\n     * Object containing default options to pass when setting cookies.\n     *\n     * The object may have following properties:\n     *\n     * - **path** - `{string}` - The cookie will be available only for this path and its\n     *   sub-paths. By default, this is the URL that appears in your `<base>` tag.\n     * - **domain** - `{string}` - The cookie will be available only for this domain and\n     *   its sub-domains. For security reasons the user agent will not accept the cookie\n     *   if the current domain is not a sub-domain of this domain or equal to it.\n     * - **expires** - `{string|Date}` - String of the form \"Wdy, DD Mon YYYY HH:MM:SS GMT\"\n     *   or a Date object indicating the exact date/time this cookie will expire.\n     * - **secure** - `{boolean}` - If `true`, then the cookie will only be available through a\n     *   secured connection.\n     *\n     * Note: By default, the address that appears in your `<base>` tag will be used as the path.\n     * This is important so that cookies will be visible for all routes when html5mode is enabled.\n     *\n     * @example\n     *\n     * ```js\n     * angular.module('cookiesProviderExample', ['ngCookies'])\n     *   .config(['$cookiesProvider', function($cookiesProvider) {\n     *     // Setting default options\n     *     $cookiesProvider.defaults.domain = 'foo.com';\n     *     $cookiesProvider.defaults.secure = true;\n     *   }]);\n     * ```\n     **/\n    var defaults = this.defaults = {};\n\n    function calcOptions(options) {\n      return options ? angular.extend({}, defaults, options) : defaults;\n    }\n\n    /**\n     * @ngdoc service\n     * @name $cookies\n     *\n     * @description\n     * Provides read/write access to browser's cookies.\n     *\n     * <div class=\"alert alert-info\">\n     * Up until Angular 1.3, `$cookies` exposed properties that represented the\n     * current browser cookie values. In version 1.4, this behavior has changed, and\n     * `$cookies` now provides a standard api of getters, setters etc.\n     * </div>\n     *\n     * Requires the {@link ngCookies `ngCookies`} module to be installed.\n     *\n     * @example\n     *\n     * ```js\n     * angular.module('cookiesExample', ['ngCookies'])\n     *   .controller('ExampleController', ['$cookies', function($cookies) {\n     *     // Retrieving a cookie\n     *     var favoriteCookie = $cookies.get('myFavorite');\n     *     // Setting a cookie\n     *     $cookies.put('myFavorite', 'oatmeal');\n     *   }]);\n     * ```\n     */\n    this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {\n      return {\n        /**\n         * @ngdoc method\n         * @name $cookies#get\n         *\n         * @description\n         * Returns the value of given cookie key\n         *\n         * @param {string} key Id to use for lookup.\n         * @returns {string} Raw cookie value.\n         */\n        get: function(key) {\n          return $$cookieReader()[key];\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#getObject\n         *\n         * @description\n         * Returns the deserialized value of given cookie key\n         *\n         * @param {string} key Id to use for lookup.\n         * @returns {Object} Deserialized cookie value.\n         */\n        getObject: function(key) {\n          var value = this.get(key);\n          return value ? angular.fromJson(value) : value;\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#getAll\n         *\n         * @description\n         * Returns a key value object with all the cookies\n         *\n         * @returns {Object} All cookies\n         */\n        getAll: function() {\n          return $$cookieReader();\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#put\n         *\n         * @description\n         * Sets a value for given cookie key\n         *\n         * @param {string} key Id for the `value`.\n         * @param {string} value Raw value to be stored.\n         * @param {Object=} options Options object.\n         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}\n         */\n        put: function(key, value, options) {\n          $$cookieWriter(key, value, calcOptions(options));\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#putObject\n         *\n         * @description\n         * Serializes and sets a value for given cookie key\n         *\n         * @param {string} key Id for the `value`.\n         * @param {Object} value Value to be stored.\n         * @param {Object=} options Options object.\n         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}\n         */\n        putObject: function(key, value, options) {\n          this.put(key, angular.toJson(value), options);\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cookies#remove\n         *\n         * @description\n         * Remove given cookie\n         *\n         * @param {string} key Id of the key-value pair to delete.\n         * @param {Object=} options Options object.\n         *    See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}\n         */\n        remove: function(key, options) {\n          $$cookieWriter(key, undefined, calcOptions(options));\n        }\n      };\n    }];\n  }]);\n\nangular.module('ngCookies').\n/**\n * @ngdoc service\n * @name $cookieStore\n * @deprecated\n * sinceVersion=\"v1.4.0\"\n * Please use the {@link ngCookies.$cookies `$cookies`} service instead.\n *\n * @requires $cookies\n *\n * @description\n * Provides a key-value (string-object) storage, that is backed by session cookies.\n * Objects put or retrieved from this storage are automatically serialized or\n * deserialized by angular's toJson/fromJson.\n *\n * Requires the {@link ngCookies `ngCookies`} module to be installed.\n *\n * @example\n *\n * ```js\n * angular.module('cookieStoreExample', ['ngCookies'])\n *   .controller('ExampleController', ['$cookieStore', function($cookieStore) {\n *     // Put cookie\n *     $cookieStore.put('myFavorite','oatmeal');\n *     // Get cookie\n *     var favoriteCookie = $cookieStore.get('myFavorite');\n *     // Removing a cookie\n *     $cookieStore.remove('myFavorite');\n *   }]);\n * ```\n */\n factory('$cookieStore', ['$cookies', function($cookies) {\n\n    return {\n      /**\n       * @ngdoc method\n       * @name $cookieStore#get\n       *\n       * @description\n       * Returns the value of given cookie key\n       *\n       * @param {string} key Id to use for lookup.\n       * @returns {Object} Deserialized cookie value, undefined if the cookie does not exist.\n       */\n      get: function(key) {\n        return $cookies.getObject(key);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $cookieStore#put\n       *\n       * @description\n       * Sets a value for given cookie key\n       *\n       * @param {string} key Id for the `value`.\n       * @param {Object} value Value to be stored.\n       */\n      put: function(key, value) {\n        $cookies.putObject(key, value);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $cookieStore#remove\n       *\n       * @description\n       * Remove given cookie\n       *\n       * @param {string} key Id of the key-value pair to delete.\n       */\n      remove: function(key) {\n        $cookies.remove(key);\n      }\n    };\n\n  }]);\n\n/**\n * @name $$cookieWriter\n * @requires $document\n *\n * @description\n * This is a private service for writing cookies\n *\n * @param {string} name Cookie name\n * @param {string=} value Cookie value (if undefined, cookie will be deleted)\n * @param {Object=} options Object with options that need to be stored for the cookie.\n */\nfunction $$CookieWriter($document, $log, $browser) {\n  var cookiePath = $browser.baseHref();\n  var rawDocument = $document[0];\n\n  function buildCookieString(name, value, options) {\n    var path, expires;\n    options = options || {};\n    expires = options.expires;\n    path = angular.isDefined(options.path) ? options.path : cookiePath;\n    if (angular.isUndefined(value)) {\n      expires = 'Thu, 01 Jan 1970 00:00:00 GMT';\n      value = '';\n    }\n    if (angular.isString(expires)) {\n      expires = new Date(expires);\n    }\n\n    var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);\n    str += path ? ';path=' + path : '';\n    str += options.domain ? ';domain=' + options.domain : '';\n    str += expires ? ';expires=' + expires.toUTCString() : '';\n    str += options.secure ? ';secure' : '';\n\n    // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:\n    // - 300 cookies\n    // - 20 cookies per unique domain\n    // - 4096 bytes per cookie\n    var cookieLength = str.length + 1;\n    if (cookieLength > 4096) {\n      $log.warn('Cookie \\'' + name +\n        '\\' possibly not set or overflowed because it was too large (' +\n        cookieLength + ' > 4096 bytes)!');\n    }\n\n    return str;\n  }\n\n  return function(name, value, options) {\n    rawDocument.cookie = buildCookieString(name, value, options);\n  };\n}\n\n$$CookieWriter.$inject = ['$document', '$log', '$browser'];\n\nangular.module('ngCookies').provider('$$cookieWriter', /** @this */ function $$CookieWriterProvider() {\n  this.$get = $$CookieWriter;\n});\n\n\n})(window, window.angular);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-cookies/angular-cookies.js\n// module id = 8\n// module chunks = 0","/**\n * @license AngularJS v1.6.3\n * (c) 2010-2017 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window, angular) {'use strict';\n\nvar $resourceMinErr = angular.$$minErr('$resource');\n\n// Helper functions and regex to lookup a dotted path on an object\n// stopping at undefined/null.  The path must be composed of ASCII\n// identifiers (just like $parse)\nvar MEMBER_NAME_REGEX = /^(\\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;\n\nfunction isValidDottedPath(path) {\n  return (path != null && path !== '' && path !== 'hasOwnProperty' &&\n      MEMBER_NAME_REGEX.test('.' + path));\n}\n\nfunction lookupDottedPath(obj, path) {\n  if (!isValidDottedPath(path)) {\n    throw $resourceMinErr('badmember', 'Dotted member path \"@{0}\" is invalid.', path);\n  }\n  var keys = path.split('.');\n  for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) {\n    var key = keys[i];\n    obj = (obj !== null) ? obj[key] : undefined;\n  }\n  return obj;\n}\n\n/**\n * Create a shallow copy of an object and clear other fields from the destination\n */\nfunction shallowClearAndCopy(src, dst) {\n  dst = dst || {};\n\n  angular.forEach(dst, function(value, key) {\n    delete dst[key];\n  });\n\n  for (var key in src) {\n    if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {\n      dst[key] = src[key];\n    }\n  }\n\n  return dst;\n}\n\n/**\n * @ngdoc module\n * @name ngResource\n * @description\n *\n * # ngResource\n *\n * The `ngResource` module provides interaction support with RESTful services\n * via the $resource service.\n *\n *\n * <div doc-module-components=\"ngResource\"></div>\n *\n * See {@link ngResource.$resourceProvider} and {@link ngResource.$resource} for usage.\n */\n\n/**\n * @ngdoc provider\n * @name $resourceProvider\n *\n * @description\n *\n * Use `$resourceProvider` to change the default behavior of the {@link ngResource.$resource}\n * service.\n *\n * ## Dependencies\n * Requires the {@link ngResource } module to be installed.\n *\n */\n\n/**\n * @ngdoc service\n * @name $resource\n * @requires $http\n * @requires ng.$log\n * @requires $q\n * @requires ng.$timeout\n *\n * @description\n * A factory which creates a resource object that lets you interact with\n * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.\n *\n * The returned resource object has action methods which provide high-level behaviors without\n * the need to interact with the low level {@link ng.$http $http} service.\n *\n * Requires the {@link ngResource `ngResource`} module to be installed.\n *\n * By default, trailing slashes will be stripped from the calculated URLs,\n * which can pose problems with server backends that do not expect that\n * behavior.  This can be disabled by configuring the `$resourceProvider` like\n * this:\n *\n * ```js\n     app.config(['$resourceProvider', function($resourceProvider) {\n       // Don't strip trailing slashes from calculated URLs\n       $resourceProvider.defaults.stripTrailingSlashes = false;\n     }]);\n * ```\n *\n * @param {string} url A parameterized URL template with parameters prefixed by `:` as in\n *   `/user/:username`. If you are using a URL with a port number (e.g.\n *   `http://example.com:8080/api`), it will be respected.\n *\n *   If you are using a url with a suffix, just add the suffix, like this:\n *   `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`\n *   or even `$resource('http://example.com/resource/:resource_id.:format')`\n *   If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be\n *   collapsed down to a single `.`.  If you need this sequence to appear and not collapse then you\n *   can escape it with `/\\.`.\n *\n * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in\n *   `actions` methods. If a parameter value is a function, it will be called every time\n *   a param value needs to be obtained for a request (unless the param was overridden). The function\n *   will be passed the current data value as an argument.\n *\n *   Each key value in the parameter object is first bound to url template if present and then any\n *   excess keys are appended to the url search query after the `?`.\n *\n *   Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in\n *   URL `/path/greet?salutation=Hello`.\n *\n *   If the parameter value is prefixed with `@`, then the value for that parameter will be\n *   extracted from the corresponding property on the `data` object (provided when calling a\n *   \"non-GET\" action method).\n *   For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of\n *   `someParam` will be `data.someProp`.\n *   Note that the parameter will be ignored, when calling a \"GET\" action method (i.e. an action\n *   method that does not accept a request body)\n *\n * @param {Object.<Object>=} actions Hash with declaration of custom actions that will be available\n *   in addition to the default set of resource actions (see below). If a custom action has the same\n *   key as a default action (e.g. `save`), then the default action will be *overwritten*, and not\n *   extended.\n *\n *   The declaration should be created in the format of {@link ng.$http#usage $http.config}:\n *\n *       {action1: {method:?, params:?, isArray:?, headers:?, ...},\n *        action2: {method:?, params:?, isArray:?, headers:?, ...},\n *        ...}\n *\n *   Where:\n *\n *   - **`action`** – {string} – The name of action. This name becomes the name of the method on\n *     your resource object.\n *   - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`,\n *     `DELETE`, `JSONP`, etc).\n *   - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of\n *     the parameter value is a function, it will be called every time when a param value needs to\n *     be obtained for a request (unless the param was overridden). The function will be passed the\n *     current data value as an argument.\n *   - **`url`** – {string} – action specific `url` override. The url templating is supported just\n *     like for the resource-level urls.\n *   - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,\n *     see `returns` section.\n *   - **`transformRequest`** –\n *     `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –\n *     transform function or an array of such functions. The transform function takes the http\n *     request body and headers and returns its transformed (typically serialized) version.\n *     By default, transformRequest will contain one function that checks if the request data is\n *     an object and serializes it using `angular.toJson`. To prevent this behavior, set\n *     `transformRequest` to an empty array: `transformRequest: []`\n *   - **`transformResponse`** –\n *     `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –\n *     transform function or an array of such functions. The transform function takes the http\n *     response body, headers and status and returns its transformed (typically deserialized)\n *     version.\n *     By default, transformResponse will contain one function that checks if the response looks\n *     like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior,\n *     set `transformResponse` to an empty array: `transformResponse: []`\n *   - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the\n *     GET request, otherwise if a cache instance built with\n *     {@link ng.$cacheFactory $cacheFactory} is supplied, this cache will be used for\n *     caching.\n *   - **`timeout`** – `{number}` – timeout in milliseconds.<br />\n *     **Note:** In contrast to {@link ng.$http#usage $http.config}, {@link ng.$q promises} are\n *     **not** supported in $resource, because the same value would be used for multiple requests.\n *     If you are looking for a way to cancel requests, you should use the `cancellable` option.\n *   - **`cancellable`** – `{boolean}` – if set to true, the request made by a \"non-instance\" call\n *     will be cancelled (if not already completed) by calling `$cancelRequest()` on the call's\n *     return value. Calling `$cancelRequest()` for a non-cancellable or an already\n *     completed/cancelled request will have no effect.<br />\n *   - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the\n *     XHR object. See\n *     [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5)\n *     for more information.\n *   - **`responseType`** - `{string}` - see\n *     [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).\n *   - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -\n *     `response` and `responseError`. Both `response` and `responseError` interceptors get called\n *     with `http response` object. See {@link ng.$http $http interceptors}.\n *\n * @param {Object} options Hash with custom settings that should extend the\n *   default `$resourceProvider` behavior.  The supported options are:\n *\n *   - **`stripTrailingSlashes`** – {boolean} – If true then the trailing\n *   slashes from any calculated URL will be stripped. (Defaults to true.)\n *   - **`cancellable`** – {boolean} – If true, the request made by a \"non-instance\" call will be\n *   cancelled (if not already completed) by calling `$cancelRequest()` on the call's return value.\n *   This can be overwritten per action. (Defaults to false.)\n *\n * @returns {Object} A resource \"class\" object with methods for the default set of resource actions\n *   optionally extended with custom `actions`. The default set contains these actions:\n *   ```js\n *   { 'get':    {method:'GET'},\n *     'save':   {method:'POST'},\n *     'query':  {method:'GET', isArray:true},\n *     'remove': {method:'DELETE'},\n *     'delete': {method:'DELETE'} };\n *   ```\n *\n *   Calling these methods invoke an {@link ng.$http} with the specified http method,\n *   destination and parameters. When the data is returned from the server then the object is an\n *   instance of the resource class. The actions `save`, `remove` and `delete` are available on it\n *   as  methods with the `$` prefix. This allows you to easily perform CRUD operations (create,\n *   read, update, delete) on server-side data like this:\n *   ```js\n *   var User = $resource('/user/:userId', {userId:'@id'});\n *   var user = User.get({userId:123}, function() {\n *     user.abc = true;\n *     user.$save();\n *   });\n *   ```\n *\n *   It is important to realize that invoking a $resource object method immediately returns an\n *   empty reference (object or array depending on `isArray`). Once the data is returned from the\n *   server the existing reference is populated with the actual data. This is a useful trick since\n *   usually the resource is assigned to a model which is then rendered by the view. Having an empty\n *   object results in no rendering, once the data arrives from the server then the object is\n *   populated with the data and the view automatically re-renders itself showing the new data. This\n *   means that in most cases one never has to write a callback function for the action methods.\n *\n *   The action methods on the class object or instance object can be invoked with the following\n *   parameters:\n *\n *   - HTTP GET \"class\" actions: `Resource.action([parameters], [success], [error])`\n *   - non-GET \"class\" actions: `Resource.action([parameters], postData, [success], [error])`\n *   - non-GET instance actions:  `instance.$action([parameters], [success], [error])`\n *\n *\n *   Success callback is called with (value (Object|Array), responseHeaders (Function),\n *   status (number), statusText (string)) arguments, where the value is the populated resource\n *   instance or collection object. The error callback is called with (httpResponse) argument.\n *\n *   Class actions return empty instance (with additional properties below).\n *   Instance actions return promise of the action.\n *\n *   The Resource instances and collections have these additional properties:\n *\n *   - `$promise`: the {@link ng.$q promise} of the original server interaction that created this\n *     instance or collection.\n *\n *     On success, the promise is resolved with the same resource instance or collection object,\n *     updated with data from server. This makes it easy to use in\n *     {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view\n *     rendering until the resource(s) are loaded.\n *\n *     On failure, the promise is rejected with the {@link ng.$http http response} object, without\n *     the `resource` property.\n *\n *     If an interceptor object was provided, the promise will instead be resolved with the value\n *     returned by the interceptor.\n *\n *   - `$resolved`: `true` after first server interaction is completed (either with success or\n *      rejection), `false` before that. Knowing if the Resource has been resolved is useful in\n *      data-binding.\n *\n *   The Resource instances and collections have these additional methods:\n *\n *   - `$cancelRequest`: If there is a cancellable, pending request related to the instance or\n *      collection, calling this method will abort the request.\n *\n *   The Resource instances have these additional methods:\n *\n *   - `toJSON`: It returns a simple object without any of the extra properties added as part of\n *     the Resource API. This object can be serialized through {@link angular.toJson} safely\n *     without attaching Angular-specific fields. Notice that `JSON.stringify` (and\n *     `angular.toJson`) automatically use this method when serializing a Resource instance\n *     (see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior)).\n *\n * @example\n *\n * # Credit card resource\n *\n * ```js\n     // Define CreditCard class\n     var CreditCard = $resource('/user/:userId/card/:cardId',\n      {userId:123, cardId:'@id'}, {\n       charge: {method:'POST', params:{charge:true}}\n      });\n\n     // We can retrieve a collection from the server\n     var cards = CreditCard.query(function() {\n       // GET: /user/123/card\n       // server returns: [ {id:456, number:'1234', name:'Smith'} ];\n\n       var card = cards[0];\n       // each item is an instance of CreditCard\n       expect(card instanceof CreditCard).toEqual(true);\n       card.name = \"J. Smith\";\n       // non GET methods are mapped onto the instances\n       card.$save();\n       // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}\n       // server returns: {id:456, number:'1234', name: 'J. Smith'};\n\n       // our custom method is mapped as well.\n       card.$charge({amount:9.99});\n       // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}\n     });\n\n     // we can create an instance as well\n     var newCard = new CreditCard({number:'0123'});\n     newCard.name = \"Mike Smith\";\n     newCard.$save();\n     // POST: /user/123/card {number:'0123', name:'Mike Smith'}\n     // server returns: {id:789, number:'0123', name: 'Mike Smith'};\n     expect(newCard.id).toEqual(789);\n * ```\n *\n * The object returned from this function execution is a resource \"class\" which has \"static\" method\n * for each action in the definition.\n *\n * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and\n * `headers`.\n *\n * @example\n *\n * # User resource\n *\n * When the data is returned from the server then the object is an instance of the resource type and\n * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD\n * operations (create, read, update, delete) on server-side data.\n\n   ```js\n     var User = $resource('/user/:userId', {userId:'@id'});\n     User.get({userId:123}, function(user) {\n       user.abc = true;\n       user.$save();\n     });\n   ```\n *\n * It's worth noting that the success callback for `get`, `query` and other methods gets passed\n * in the response that came from the server as well as $http header getter function, so one\n * could rewrite the above example and get access to http headers as:\n *\n   ```js\n     var User = $resource('/user/:userId', {userId:'@id'});\n     User.get({userId:123}, function(user, getResponseHeaders){\n       user.abc = true;\n       user.$save(function(user, putResponseHeaders) {\n         //user => saved user object\n         //putResponseHeaders => $http header getter\n       });\n     });\n   ```\n *\n * You can also access the raw `$http` promise via the `$promise` property on the object returned\n *\n   ```\n     var User = $resource('/user/:userId', {userId:'@id'});\n     User.get({userId:123})\n         .$promise.then(function(user) {\n           $scope.user = user;\n         });\n   ```\n *\n * @example\n *\n * # Creating a custom 'PUT' request\n *\n * In this example we create a custom method on our resource to make a PUT request\n * ```js\n *    var app = angular.module('app', ['ngResource', 'ngRoute']);\n *\n *    // Some APIs expect a PUT request in the format URL/object/ID\n *    // Here we are creating an 'update' method\n *    app.factory('Notes', ['$resource', function($resource) {\n *    return $resource('/notes/:id', null,\n *        {\n *            'update': { method:'PUT' }\n *        });\n *    }]);\n *\n *    // In our controller we get the ID from the URL using ngRoute and $routeParams\n *    // We pass in $routeParams and our Notes factory along with $scope\n *    app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',\n                                      function($scope, $routeParams, Notes) {\n *    // First get a note object from the factory\n *    var note = Notes.get({ id:$routeParams.id });\n *    $id = note.id;\n *\n *    // Now call update passing in the ID first then the object you are updating\n *    Notes.update({ id:$id }, note);\n *\n *    // This will PUT /notes/ID with the note object in the request payload\n *    }]);\n * ```\n *\n * @example\n *\n * # Cancelling requests\n *\n * If an action's configuration specifies that it is cancellable, you can cancel the request related\n * to an instance or collection (as long as it is a result of a \"non-instance\" call):\n *\n   ```js\n     // ...defining the `Hotel` resource...\n     var Hotel = $resource('/api/hotel/:id', {id: '@id'}, {\n       // Let's make the `query()` method cancellable\n       query: {method: 'get', isArray: true, cancellable: true}\n     });\n\n     // ...somewhere in the PlanVacationController...\n     ...\n     this.onDestinationChanged = function onDestinationChanged(destination) {\n       // We don't care about any pending request for hotels\n       // in a different destination any more\n       this.availableHotels.$cancelRequest();\n\n       // Let's query for hotels in '<destination>'\n       // (calls: /api/hotel?location=<destination>)\n       this.availableHotels = Hotel.query({location: destination});\n     };\n   ```\n *\n */\nangular.module('ngResource', ['ng']).\n  info({ angularVersion: '1.6.3' }).\n  provider('$resource', function ResourceProvider() {\n    var PROTOCOL_AND_IPV6_REGEX = /^https?:\\/\\/\\[[^\\]]*][^/]*/;\n\n    var provider = this;\n\n    /**\n     * @ngdoc property\n     * @name $resourceProvider#defaults\n     * @description\n     * Object containing default options used when creating `$resource` instances.\n     *\n     * The default values satisfy a wide range of usecases, but you may choose to overwrite any of\n     * them to further customize your instances. The available properties are:\n     *\n     * - **stripTrailingSlashes** – `{boolean}` – If true, then the trailing slashes from any\n     *   calculated URL will be stripped.<br />\n     *   (Defaults to true.)\n     * - **cancellable** – `{boolean}` – If true, the request made by a \"non-instance\" call will be\n     *   cancelled (if not already completed) by calling `$cancelRequest()` on the call's return\n     *   value. For more details, see {@link ngResource.$resource}. This can be overwritten per\n     *   resource class or action.<br />\n     *   (Defaults to false.)\n     * - **actions** - `{Object.<Object>}` - A hash with default actions declarations. Actions are\n     *   high-level methods corresponding to RESTful actions/methods on resources. An action may\n     *   specify what HTTP method to use, what URL to hit, if the return value will be a single\n     *   object or a collection (array) of objects etc. For more details, see\n     *   {@link ngResource.$resource}. The actions can also be enhanced or overwritten per resource\n     *   class.<br />\n     *   The default actions are:\n     *   ```js\n     *   {\n     *     get: {method: 'GET'},\n     *     save: {method: 'POST'},\n     *     query: {method: 'GET', isArray: true},\n     *     remove: {method: 'DELETE'},\n     *     delete: {method: 'DELETE'}\n     *   }\n     *   ```\n     *\n     * #### Example\n     *\n     * For example, you can specify a new `update` action that uses the `PUT` HTTP verb:\n     *\n     * ```js\n     *   angular.\n     *     module('myApp').\n     *     config(['$resourceProvider', function ($resourceProvider) {\n     *       $resourceProvider.defaults.actions.update = {\n     *         method: 'PUT'\n     *       };\n     *     });\n     * ```\n     *\n     * Or you can even overwrite the whole `actions` list and specify your own:\n     *\n     * ```js\n     *   angular.\n     *     module('myApp').\n     *     config(['$resourceProvider', function ($resourceProvider) {\n     *       $resourceProvider.defaults.actions = {\n     *         create: {method: 'POST'},\n     *         get:    {method: 'GET'},\n     *         getAll: {method: 'GET', isArray:true},\n     *         update: {method: 'PUT'},\n     *         delete: {method: 'DELETE'}\n     *       };\n     *     });\n     * ```\n     *\n     */\n    this.defaults = {\n      // Strip slashes by default\n      stripTrailingSlashes: true,\n\n      // Make non-instance requests cancellable (via `$cancelRequest()`)\n      cancellable: false,\n\n      // Default actions configuration\n      actions: {\n        'get': {method: 'GET'},\n        'save': {method: 'POST'},\n        'query': {method: 'GET', isArray: true},\n        'remove': {method: 'DELETE'},\n        'delete': {method: 'DELETE'}\n      }\n    };\n\n    this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) {\n\n      var noop = angular.noop,\n          forEach = angular.forEach,\n          extend = angular.extend,\n          copy = angular.copy,\n          isArray = angular.isArray,\n          isDefined = angular.isDefined,\n          isFunction = angular.isFunction,\n          isNumber = angular.isNumber,\n          encodeUriQuery = angular.$$encodeUriQuery,\n          encodeUriSegment = angular.$$encodeUriSegment;\n\n      function Route(template, defaults) {\n        this.template = template;\n        this.defaults = extend({}, provider.defaults, defaults);\n        this.urlParams = {};\n      }\n\n      Route.prototype = {\n        setUrlParams: function(config, params, actionUrl) {\n          var self = this,\n            url = actionUrl || self.template,\n            val,\n            encodedVal,\n            protocolAndIpv6 = '';\n\n          var urlParams = self.urlParams = Object.create(null);\n          forEach(url.split(/\\W/), function(param) {\n            if (param === 'hasOwnProperty') {\n              throw $resourceMinErr('badname', 'hasOwnProperty is not a valid parameter name.');\n            }\n            if (!(new RegExp('^\\\\d+$').test(param)) && param &&\n              (new RegExp('(^|[^\\\\\\\\]):' + param + '(\\\\W|$)').test(url))) {\n              urlParams[param] = {\n                isQueryParamValue: (new RegExp('\\\\?.*=:' + param + '(?:\\\\W|$)')).test(url)\n              };\n            }\n          });\n          url = url.replace(/\\\\:/g, ':');\n          url = url.replace(PROTOCOL_AND_IPV6_REGEX, function(match) {\n            protocolAndIpv6 = match;\n            return '';\n          });\n\n          params = params || {};\n          forEach(self.urlParams, function(paramInfo, urlParam) {\n            val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];\n            if (isDefined(val) && val !== null) {\n              if (paramInfo.isQueryParamValue) {\n                encodedVal = encodeUriQuery(val, true);\n              } else {\n                encodedVal = encodeUriSegment(val);\n              }\n              url = url.replace(new RegExp(':' + urlParam + '(\\\\W|$)', 'g'), function(match, p1) {\n                return encodedVal + p1;\n              });\n            } else {\n              url = url.replace(new RegExp('(/?):' + urlParam + '(\\\\W|$)', 'g'), function(match,\n                  leadingSlashes, tail) {\n                if (tail.charAt(0) === '/') {\n                  return tail;\n                } else {\n                  return leadingSlashes + tail;\n                }\n              });\n            }\n          });\n\n          // strip trailing slashes and set the url (unless this behavior is specifically disabled)\n          if (self.defaults.stripTrailingSlashes) {\n            url = url.replace(/\\/+$/, '') || '/';\n          }\n\n          // Collapse `/.` if found in the last URL path segment before the query.\n          // E.g. `http://url.com/id/.format?q=x` becomes `http://url.com/id.format?q=x`.\n          url = url.replace(/\\/\\.(?=\\w+($|\\?))/, '.');\n          // Replace escaped `/\\.` with `/.`.\n          // (If `\\.` comes from a param value, it will be encoded as `%5C.`.)\n          config.url = protocolAndIpv6 + url.replace(/\\/(\\\\|%5C)\\./, '/.');\n\n\n          // set params - delegate param encoding to $http\n          forEach(params, function(value, key) {\n            if (!self.urlParams[key]) {\n              config.params = config.params || {};\n              config.params[key] = value;\n            }\n          });\n        }\n      };\n\n\n      function resourceFactory(url, paramDefaults, actions, options) {\n        var route = new Route(url, options);\n\n        actions = extend({}, provider.defaults.actions, actions);\n\n        function extractParams(data, actionParams) {\n          var ids = {};\n          actionParams = extend({}, paramDefaults, actionParams);\n          forEach(actionParams, function(value, key) {\n            if (isFunction(value)) { value = value(data); }\n            ids[key] = value && value.charAt && value.charAt(0) === '@' ?\n              lookupDottedPath(data, value.substr(1)) : value;\n          });\n          return ids;\n        }\n\n        function defaultResponseInterceptor(response) {\n          return response.resource;\n        }\n\n        function Resource(value) {\n          shallowClearAndCopy(value || {}, this);\n        }\n\n        Resource.prototype.toJSON = function() {\n          var data = extend({}, this);\n          delete data.$promise;\n          delete data.$resolved;\n          delete data.$cancelRequest;\n          return data;\n        };\n\n        forEach(actions, function(action, name) {\n          var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);\n          var numericTimeout = action.timeout;\n          var cancellable = isDefined(action.cancellable) ?\n              action.cancellable : route.defaults.cancellable;\n\n          if (numericTimeout && !isNumber(numericTimeout)) {\n            $log.debug('ngResource:\\n' +\n                       '  Only numeric values are allowed as `timeout`.\\n' +\n                       '  Promises are not supported in $resource, because the same value would ' +\n                       'be used for multiple requests. If you are looking for a way to cancel ' +\n                       'requests, you should use the `cancellable` option.');\n            delete action.timeout;\n            numericTimeout = null;\n          }\n\n          Resource[name] = function(a1, a2, a3, a4) {\n            var params = {}, data, success, error;\n\n            switch (arguments.length) {\n              case 4:\n                error = a4;\n                success = a3;\n                // falls through\n              case 3:\n              case 2:\n                if (isFunction(a2)) {\n                  if (isFunction(a1)) {\n                    success = a1;\n                    error = a2;\n                    break;\n                  }\n\n                  success = a2;\n                  error = a3;\n                  // falls through\n                } else {\n                  params = a1;\n                  data = a2;\n                  success = a3;\n                  break;\n                }\n                // falls through\n              case 1:\n                if (isFunction(a1)) success = a1;\n                else if (hasBody) data = a1;\n                else params = a1;\n                break;\n              case 0: break;\n              default:\n                throw $resourceMinErr('badargs',\n                  'Expected up to 4 arguments [params, data, success, error], got {0} arguments',\n                  arguments.length);\n            }\n\n            var isInstanceCall = this instanceof Resource;\n            var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));\n            var httpConfig = {};\n            var responseInterceptor = action.interceptor && action.interceptor.response ||\n              defaultResponseInterceptor;\n            var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||\n              undefined;\n            var hasError = !!error;\n            var hasResponseErrorInterceptor = !!responseErrorInterceptor;\n            var timeoutDeferred;\n            var numericTimeoutPromise;\n\n            forEach(action, function(value, key) {\n              switch (key) {\n                default:\n                  httpConfig[key] = copy(value);\n                  break;\n                case 'params':\n                case 'isArray':\n                case 'interceptor':\n                case 'cancellable':\n                  break;\n              }\n            });\n\n            if (!isInstanceCall && cancellable) {\n              timeoutDeferred = $q.defer();\n              httpConfig.timeout = timeoutDeferred.promise;\n\n              if (numericTimeout) {\n                numericTimeoutPromise = $timeout(timeoutDeferred.resolve, numericTimeout);\n              }\n            }\n\n            if (hasBody) httpConfig.data = data;\n            route.setUrlParams(httpConfig,\n              extend({}, extractParams(data, action.params || {}), params),\n              action.url);\n\n            var promise = $http(httpConfig).then(function(response) {\n              var data = response.data;\n\n              if (data) {\n                // Need to convert action.isArray to boolean in case it is undefined\n                if (isArray(data) !== (!!action.isArray)) {\n                  throw $resourceMinErr('badcfg',\n                      'Error in resource configuration for action `{0}`. Expected response to ' +\n                      'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',\n                    isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);\n                }\n                if (action.isArray) {\n                  value.length = 0;\n                  forEach(data, function(item) {\n                    if (typeof item === 'object') {\n                      value.push(new Resource(item));\n                    } else {\n                      // Valid JSON values may be string literals, and these should not be converted\n                      // into objects. These items will not have access to the Resource prototype\n                      // methods, but unfortunately there\n                      value.push(item);\n                    }\n                  });\n                } else {\n                  var promise = value.$promise;     // Save the promise\n                  shallowClearAndCopy(data, value);\n                  value.$promise = promise;         // Restore the promise\n                }\n              }\n              response.resource = value;\n\n              return response;\n            });\n\n            promise = promise['finally'](function() {\n              value.$resolved = true;\n              if (!isInstanceCall && cancellable) {\n                value.$cancelRequest = noop;\n                $timeout.cancel(numericTimeoutPromise);\n                timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null;\n              }\n            });\n\n            promise = promise.then(\n              function(response) {\n                var value = responseInterceptor(response);\n                (success || noop)(value, response.headers, response.status, response.statusText);\n                return value;\n              },\n              (hasError || hasResponseErrorInterceptor) ?\n                function(response) {\n                  if (hasError && !hasResponseErrorInterceptor) {\n                    // Avoid `Possibly Unhandled Rejection` error,\n                    // but still fulfill the returned promise with a rejection\n                    promise.catch(noop);\n                  }\n                  if (hasError) error(response);\n                  return hasResponseErrorInterceptor ?\n                    responseErrorInterceptor(response) :\n                    $q.reject(response);\n                } :\n                undefined);\n\n            if (!isInstanceCall) {\n              // we are creating instance / collection\n              // - set the initial promise\n              // - return the instance / collection\n              value.$promise = promise;\n              value.$resolved = false;\n              if (cancellable) value.$cancelRequest = cancelRequest;\n\n              return value;\n            }\n\n            // instance call\n            return promise;\n\n            function cancelRequest(value) {\n              promise.catch(noop);\n              timeoutDeferred.resolve(value);\n            }\n          };\n\n\n          Resource.prototype['$' + name] = function(params, success, error) {\n            if (isFunction(params)) {\n              error = success; success = params; params = {};\n            }\n            var result = Resource[name].call(this, params, this, success, error);\n            return result.$promise || result;\n          };\n        });\n\n        Resource.bind = function(additionalParamDefaults) {\n          var extendedParamDefaults = extend({}, paramDefaults, additionalParamDefaults);\n          return resourceFactory(url, extendedParamDefaults, actions, options);\n        };\n\n        return Resource;\n      }\n\n      return resourceFactory;\n    }];\n  });\n\n\n})(window, window.angular);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular-resource/angular-resource.js\n// module id = 9\n// module chunks = 0","/**\n * @license AngularJS v1.6.3\n * (c) 2010-2017 Google, Inc. http://angularjs.org\n * License: MIT\n */\n(function(window) {'use strict';\n\n/**\n * @description\n *\n * This object provides a utility for producing rich Error messages within\n * Angular. It can be called as follows:\n *\n * var exampleMinErr = minErr('example');\n * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);\n *\n * The above creates an instance of minErr in the example namespace. The\n * resulting error will have a namespaced error code of example.one.  The\n * resulting error will replace {0} with the value of foo, and {1} with the\n * value of bar. The object is not restricted in the number of arguments it can\n * take.\n *\n * If fewer arguments are specified than necessary for interpolation, the extra\n * interpolation markers will be preserved in the final string.\n *\n * Since data will be parsed statically during a build step, some restrictions\n * are applied with respect to how minErr instances are created and called.\n * Instances should have names of the form namespaceMinErr for a minErr created\n * using minErr('namespace') . Error codes, namespaces and template strings\n * should all be static strings, not variables or general expressions.\n *\n * @param {string} module The namespace to use for the new minErr instance.\n * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning\n *   error from returned function, for cases when a particular type of error is useful.\n * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance\n */\n\nfunction minErr(module, ErrorConstructor) {\n  ErrorConstructor = ErrorConstructor || Error;\n  return function() {\n    var code = arguments[0],\n      template = arguments[1],\n      message = '[' + (module ? module + ':' : '') + code + '] ',\n      templateArgs = sliceArgs(arguments, 2).map(function(arg) {\n        return toDebugString(arg, minErrConfig.objectMaxDepth);\n      }),\n      paramPrefix, i;\n\n    message += template.replace(/\\{\\d+\\}/g, function(match) {\n      var index = +match.slice(1, -1);\n\n      if (index < templateArgs.length) {\n        return templateArgs[index];\n      }\n\n      return match;\n    });\n\n    message += '\\nhttp://errors.angularjs.org/1.6.3/' +\n      (module ? module + '/' : '') + code;\n\n    for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {\n      message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]);\n    }\n\n    return new ErrorConstructor(message);\n  };\n}\n\n/* We need to tell ESLint what variables are being exported */\n/* exported\n  angular,\n  msie,\n  jqLite,\n  jQuery,\n  slice,\n  splice,\n  push,\n  toString,\n  minErrConfig,\n  errorHandlingConfig,\n  isValidObjectMaxDepth,\n  ngMinErr,\n  angularModule,\n  uid,\n  REGEX_STRING_REGEXP,\n  VALIDITY_STATE_PROPERTY,\n\n  lowercase,\n  uppercase,\n  manualLowercase,\n  manualUppercase,\n  nodeName_,\n  isArrayLike,\n  forEach,\n  forEachSorted,\n  reverseParams,\n  nextUid,\n  setHashKey,\n  extend,\n  toInt,\n  inherit,\n  merge,\n  noop,\n  identity,\n  valueFn,\n  isUndefined,\n  isDefined,\n  isObject,\n  isBlankObject,\n  isString,\n  isNumber,\n  isNumberNaN,\n  isDate,\n  isArray,\n  isFunction,\n  isRegExp,\n  isWindow,\n  isScope,\n  isFile,\n  isFormData,\n  isBlob,\n  isBoolean,\n  isPromiseLike,\n  trim,\n  escapeForRegexp,\n  isElement,\n  makeMap,\n  includes,\n  arrayRemove,\n  copy,\n  equals,\n  csp,\n  jq,\n  concat,\n  sliceArgs,\n  bind,\n  toJsonReplacer,\n  toJson,\n  fromJson,\n  convertTimezoneToLocal,\n  timezoneToOffset,\n  startingTag,\n  tryDecodeURIComponent,\n  parseKeyValue,\n  toKeyValue,\n  encodeUriSegment,\n  encodeUriQuery,\n  angularInit,\n  bootstrap,\n  getTestability,\n  snake_case,\n  bindJQuery,\n  assertArg,\n  assertArgFn,\n  assertNotHasOwnProperty,\n  getter,\n  getBlockNodes,\n  hasOwnProperty,\n  createMap,\n  stringify,\n\n  NODE_TYPE_ELEMENT,\n  NODE_TYPE_ATTRIBUTE,\n  NODE_TYPE_TEXT,\n  NODE_TYPE_COMMENT,\n  NODE_TYPE_DOCUMENT,\n  NODE_TYPE_DOCUMENT_FRAGMENT\n*/\n\n////////////////////////////////////\n\n/**\n * @ngdoc module\n * @name ng\n * @module ng\n * @installation\n * @description\n *\n * # ng (core module)\n * The ng module is loaded by default when an AngularJS application is started. The module itself\n * contains the essential components for an AngularJS application to function. The table below\n * lists a high level breakdown of each of the services/factories, filters, directives and testing\n * components available within this core module.\n *\n * <div doc-module-components=\"ng\"></div>\n */\n\nvar REGEX_STRING_REGEXP = /^\\/(.+)\\/([a-z]*)$/;\n\n// The name of a form control's ValidityState property.\n// This is used so that it's possible for internal tests to create mock ValidityStates.\nvar VALIDITY_STATE_PROPERTY = 'validity';\n\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar minErrConfig = {\n  objectMaxDepth: 5\n};\n\n /**\n * @ngdoc function\n * @name angular.errorHandlingConfig\n * @module ng\n * @kind function\n *\n * @description\n * Configure several aspects of error handling in AngularJS if used as a setter or return the\n * current configuration if used as a getter. The following options are supported:\n *\n * - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages.\n *\n * Omitted or undefined options will leave the corresponding configuration values unchanged.\n *\n * @param {Object=} config - The configuration object. May only contain the options that need to be\n *     updated. Supported keys:\n *\n * * `objectMaxDepth`  **{Number}** - The max depth for stringifying objects. Setting to a\n *   non-positive or non-numeric value, removes the max depth limit.\n *   Default: 5\n */\nfunction errorHandlingConfig(config) {\n  if (isObject(config)) {\n    if (isDefined(config.objectMaxDepth)) {\n      minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN;\n    }\n  } else {\n    return minErrConfig;\n  }\n}\n\n/**\n * @private\n * @param {Number} maxDepth\n * @return {boolean}\n */\nfunction isValidObjectMaxDepth(maxDepth) {\n  return isNumber(maxDepth) && maxDepth > 0;\n}\n\n/**\n * @ngdoc function\n * @name angular.lowercase\n * @module ng\n * @kind function\n *\n * @deprecated\n * sinceVersion=\"1.5.0\"\n * removeVersion=\"1.7.0\"\n * Use [String.prototype.toLowerCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) instead.\n *\n * @description Converts the specified string to lowercase.\n * @param {string} string String to be converted to lowercase.\n * @returns {string} Lowercased string.\n */\nvar lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};\n\n/**\n * @ngdoc function\n * @name angular.uppercase\n * @module ng\n * @kind function\n *\n * @deprecated\n * sinceVersion=\"1.5.0\"\n * removeVersion=\"1.7.0\"\n * Use [String.prototype.toUpperCase](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) instead.\n *\n * @description Converts the specified string to uppercase.\n * @param {string} string String to be converted to uppercase.\n * @returns {string} Uppercased string.\n */\nvar uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};\n\n\nvar manualLowercase = function(s) {\n  /* eslint-disable no-bitwise */\n  return isString(s)\n      ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})\n      : s;\n  /* eslint-enable */\n};\nvar manualUppercase = function(s) {\n  /* eslint-disable no-bitwise */\n  return isString(s)\n      ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})\n      : s;\n  /* eslint-enable */\n};\n\n\n// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish\n// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods\n// with correct but slower alternatives. See https://github.com/angular/angular.js/issues/11387\nif ('i' !== 'I'.toLowerCase()) {\n  lowercase = manualLowercase;\n  uppercase = manualUppercase;\n}\n\n\nvar\n    msie,             // holds major version number for IE, or NaN if UA is not IE.\n    jqLite,           // delay binding since jQuery could be loaded after us.\n    jQuery,           // delay binding\n    slice             = [].slice,\n    splice            = [].splice,\n    push              = [].push,\n    toString          = Object.prototype.toString,\n    getPrototypeOf    = Object.getPrototypeOf,\n    ngMinErr          = minErr('ng'),\n\n    /** @name angular */\n    angular           = window.angular || (window.angular = {}),\n    angularModule,\n    uid               = 0;\n\n// Support: IE 9-11 only\n/**\n * documentMode is an IE-only property\n * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx\n */\nmsie = window.document.documentMode;\n\n\n/**\n * @private\n * @param {*} obj\n * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,\n *                   String ...)\n */\nfunction isArrayLike(obj) {\n\n  // `null`, `undefined` and `window` are not array-like\n  if (obj == null || isWindow(obj)) return false;\n\n  // arrays, strings and jQuery/jqLite objects are array like\n  // * jqLite is either the jQuery or jqLite constructor function\n  // * we have to check the existence of jqLite first as this method is called\n  //   via the forEach method when constructing the jqLite object in the first place\n  if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;\n\n  // Support: iOS 8.2 (not reproducible in simulator)\n  // \"length\" in obj used to prevent JIT error (gh-11508)\n  var length = 'length' in Object(obj) && obj.length;\n\n  // NodeList objects (with `item` method) and\n  // other objects with suitable length characteristics are array-like\n  return isNumber(length) &&\n    (length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item === 'function');\n\n}\n\n/**\n * @ngdoc function\n * @name angular.forEach\n * @module ng\n * @kind function\n *\n * @description\n * Invokes the `iterator` function once for each item in `obj` collection, which can be either an\n * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`\n * is the value of an object property or an array element, `key` is the object property key or\n * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.\n *\n * It is worth noting that `.forEach` does not iterate over inherited properties because it filters\n * using the `hasOwnProperty` method.\n *\n * Unlike ES262's\n * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),\n * providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just\n * return the value provided.\n *\n   ```js\n     var values = {name: 'misko', gender: 'male'};\n     var log = [];\n     angular.forEach(values, function(value, key) {\n       this.push(key + ': ' + value);\n     }, log);\n     expect(log).toEqual(['name: misko', 'gender: male']);\n   ```\n *\n * @param {Object|Array} obj Object to iterate over.\n * @param {Function} iterator Iterator function.\n * @param {Object=} context Object to become context (`this`) for the iterator function.\n * @returns {Object|Array} Reference to `obj`.\n */\n\nfunction forEach(obj, iterator, context) {\n  var key, length;\n  if (obj) {\n    if (isFunction(obj)) {\n      for (key in obj) {\n        if (key !== 'prototype' && key !== 'length' && key !== 'name' && obj.hasOwnProperty(key)) {\n          iterator.call(context, obj[key], key, obj);\n        }\n      }\n    } else if (isArray(obj) || isArrayLike(obj)) {\n      var isPrimitive = typeof obj !== 'object';\n      for (key = 0, length = obj.length; key < length; key++) {\n        if (isPrimitive || key in obj) {\n          iterator.call(context, obj[key], key, obj);\n        }\n      }\n    } else if (obj.forEach && obj.forEach !== forEach) {\n        obj.forEach(iterator, context, obj);\n    } else if (isBlankObject(obj)) {\n      // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty\n      for (key in obj) {\n        iterator.call(context, obj[key], key, obj);\n      }\n    } else if (typeof obj.hasOwnProperty === 'function') {\n      // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed\n      for (key in obj) {\n        if (obj.hasOwnProperty(key)) {\n          iterator.call(context, obj[key], key, obj);\n        }\n      }\n    } else {\n      // Slow path for objects which do not have a method `hasOwnProperty`\n      for (key in obj) {\n        if (hasOwnProperty.call(obj, key)) {\n          iterator.call(context, obj[key], key, obj);\n        }\n      }\n    }\n  }\n  return obj;\n}\n\nfunction forEachSorted(obj, iterator, context) {\n  var keys = Object.keys(obj).sort();\n  for (var i = 0; i < keys.length; i++) {\n    iterator.call(context, obj[keys[i]], keys[i]);\n  }\n  return keys;\n}\n\n\n/**\n * when using forEach the params are value, key, but it is often useful to have key, value.\n * @param {function(string, *)} iteratorFn\n * @returns {function(*, string)}\n */\nfunction reverseParams(iteratorFn) {\n  return function(value, key) {iteratorFn(key, value);};\n}\n\n/**\n * A consistent way of creating unique IDs in angular.\n *\n * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before\n * we hit number precision issues in JavaScript.\n *\n * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M\n *\n * @returns {number} an unique alpha-numeric string\n */\nfunction nextUid() {\n  return ++uid;\n}\n\n\n/**\n * Set or clear the hashkey for an object.\n * @param obj object\n * @param h the hashkey (!truthy to delete the hashkey)\n */\nfunction setHashKey(obj, h) {\n  if (h) {\n    obj.$$hashKey = h;\n  } else {\n    delete obj.$$hashKey;\n  }\n}\n\n\nfunction baseExtend(dst, objs, deep) {\n  var h = dst.$$hashKey;\n\n  for (var i = 0, ii = objs.length; i < ii; ++i) {\n    var obj = objs[i];\n    if (!isObject(obj) && !isFunction(obj)) continue;\n    var keys = Object.keys(obj);\n    for (var j = 0, jj = keys.length; j < jj; j++) {\n      var key = keys[j];\n      var src = obj[key];\n\n      if (deep && isObject(src)) {\n        if (isDate(src)) {\n          dst[key] = new Date(src.valueOf());\n        } else if (isRegExp(src)) {\n          dst[key] = new RegExp(src);\n        } else if (src.nodeName) {\n          dst[key] = src.cloneNode(true);\n        } else if (isElement(src)) {\n          dst[key] = src.clone();\n        } else {\n          if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};\n          baseExtend(dst[key], [src], true);\n        }\n      } else {\n        dst[key] = src;\n      }\n    }\n  }\n\n  setHashKey(dst, h);\n  return dst;\n}\n\n/**\n * @ngdoc function\n * @name angular.extend\n * @module ng\n * @kind function\n *\n * @description\n * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)\n * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so\n * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.\n *\n * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use\n * {@link angular.merge} for this.\n *\n * @param {Object} dst Destination object.\n * @param {...Object} src Source object(s).\n * @returns {Object} Reference to `dst`.\n */\nfunction extend(dst) {\n  return baseExtend(dst, slice.call(arguments, 1), false);\n}\n\n\n/**\n* @ngdoc function\n* @name angular.merge\n* @module ng\n* @kind function\n*\n* @description\n* Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s)\n* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so\n* by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`.\n*\n* Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source\n* objects, performing a deep copy.\n*\n* @param {Object} dst Destination object.\n* @param {...Object} src Source object(s).\n* @returns {Object} Reference to `dst`.\n*/\nfunction merge(dst) {\n  return baseExtend(dst, slice.call(arguments, 1), true);\n}\n\n\n\nfunction toInt(str) {\n  return parseInt(str, 10);\n}\n\nvar isNumberNaN = Number.isNaN || function isNumberNaN(num) {\n  // eslint-disable-next-line no-self-compare\n  return num !== num;\n};\n\n\nfunction inherit(parent, extra) {\n  return extend(Object.create(parent), extra);\n}\n\n/**\n * @ngdoc function\n * @name angular.noop\n * @module ng\n * @kind function\n *\n * @description\n * A function that performs no operations. This function can be useful when writing code in the\n * functional style.\n   ```js\n     function foo(callback) {\n       var result = calculateResult();\n       (callback || angular.noop)(result);\n     }\n   ```\n */\nfunction noop() {}\nnoop.$inject = [];\n\n\n/**\n * @ngdoc function\n * @name angular.identity\n * @module ng\n * @kind function\n *\n * @description\n * A function that returns its first argument. This function is useful when writing code in the\n * functional style.\n *\n   ```js\n   function transformer(transformationFn, value) {\n     return (transformationFn || angular.identity)(value);\n   };\n\n   // E.g.\n   function getResult(fn, input) {\n     return (fn || angular.identity)(input);\n   };\n\n   getResult(function(n) { return n * 2; }, 21);   // returns 42\n   getResult(null, 21);                            // returns 21\n   getResult(undefined, 21);                       // returns 21\n   ```\n *\n * @param {*} value to be returned.\n * @returns {*} the value passed in.\n */\nfunction identity($) {return $;}\nidentity.$inject = [];\n\n\nfunction valueFn(value) {return function valueRef() {return value;};}\n\nfunction hasCustomToString(obj) {\n  return isFunction(obj.toString) && obj.toString !== toString;\n}\n\n\n/**\n * @ngdoc function\n * @name angular.isUndefined\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is undefined.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is undefined.\n */\nfunction isUndefined(value) {return typeof value === 'undefined';}\n\n\n/**\n * @ngdoc function\n * @name angular.isDefined\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is defined.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is defined.\n */\nfunction isDefined(value) {return typeof value !== 'undefined';}\n\n\n/**\n * @ngdoc function\n * @name angular.isObject\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not\n * considered to be objects. Note that JavaScript arrays are objects.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is an `Object` but not `null`.\n */\nfunction isObject(value) {\n  // http://jsperf.com/isobject4\n  return value !== null && typeof value === 'object';\n}\n\n\n/**\n * Determine if a value is an object with a null prototype\n *\n * @returns {boolean} True if `value` is an `Object` with a null prototype\n */\nfunction isBlankObject(value) {\n  return value !== null && typeof value === 'object' && !getPrototypeOf(value);\n}\n\n\n/**\n * @ngdoc function\n * @name angular.isString\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is a `String`.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `String`.\n */\nfunction isString(value) {return typeof value === 'string';}\n\n\n/**\n * @ngdoc function\n * @name angular.isNumber\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is a `Number`.\n *\n * This includes the \"special\" numbers `NaN`, `+Infinity` and `-Infinity`.\n *\n * If you wish to exclude these then you can use the native\n * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)\n * method.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `Number`.\n */\nfunction isNumber(value) {return typeof value === 'number';}\n\n\n/**\n * @ngdoc function\n * @name angular.isDate\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a value is a date.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `Date`.\n */\nfunction isDate(value) {\n  return toString.call(value) === '[object Date]';\n}\n\n\n/**\n * @ngdoc function\n * @name angular.isArray\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is an `Array`. Alias of Array.isArray.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is an `Array`.\n */\nvar isArray = Array.isArray;\n\n/**\n * @ngdoc function\n * @name angular.isFunction\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is a `Function`.\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `Function`.\n */\nfunction isFunction(value) {return typeof value === 'function';}\n\n\n/**\n * Determines if a value is a regular expression object.\n *\n * @private\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a `RegExp`.\n */\nfunction isRegExp(value) {\n  return toString.call(value) === '[object RegExp]';\n}\n\n\n/**\n * Checks if `obj` is a window object.\n *\n * @private\n * @param {*} obj Object to check\n * @returns {boolean} True if `obj` is a window obj.\n */\nfunction isWindow(obj) {\n  return obj && obj.window === obj;\n}\n\n\nfunction isScope(obj) {\n  return obj && obj.$evalAsync && obj.$watch;\n}\n\n\nfunction isFile(obj) {\n  return toString.call(obj) === '[object File]';\n}\n\n\nfunction isFormData(obj) {\n  return toString.call(obj) === '[object FormData]';\n}\n\n\nfunction isBlob(obj) {\n  return toString.call(obj) === '[object Blob]';\n}\n\n\nfunction isBoolean(value) {\n  return typeof value === 'boolean';\n}\n\n\nfunction isPromiseLike(obj) {\n  return obj && isFunction(obj.then);\n}\n\n\nvar TYPED_ARRAY_REGEXP = /^\\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array]$/;\nfunction isTypedArray(value) {\n  return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));\n}\n\nfunction isArrayBuffer(obj) {\n  return toString.call(obj) === '[object ArrayBuffer]';\n}\n\n\nvar trim = function(value) {\n  return isString(value) ? value.trim() : value;\n};\n\n// Copied from:\n// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021\n// Prereq: s is a string.\nvar escapeForRegexp = function(s) {\n  return s\n    .replace(/([-()[\\]{}+?*.$^|,:#<!\\\\])/g, '\\\\$1')\n    // eslint-disable-next-line no-control-regex\n    .replace(/\\x08/g, '\\\\x08');\n};\n\n\n/**\n * @ngdoc function\n * @name angular.isElement\n * @module ng\n * @kind function\n *\n * @description\n * Determines if a reference is a DOM element (or wrapped jQuery element).\n *\n * @param {*} value Reference to check.\n * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).\n */\nfunction isElement(node) {\n  return !!(node &&\n    (node.nodeName  // We are a direct element.\n    || (node.prop && node.attr && node.find)));  // We have an on and find method part of jQuery API.\n}\n\n/**\n * @param str 'key1,key2,...'\n * @returns {object} in the form of {key1:true, key2:true, ...}\n */\nfunction makeMap(str) {\n  var obj = {}, items = str.split(','), i;\n  for (i = 0; i < items.length; i++) {\n    obj[items[i]] = true;\n  }\n  return obj;\n}\n\n\nfunction nodeName_(element) {\n  return lowercase(element.nodeName || (element[0] && element[0].nodeName));\n}\n\nfunction includes(array, obj) {\n  return Array.prototype.indexOf.call(array, obj) !== -1;\n}\n\nfunction arrayRemove(array, value) {\n  var index = array.indexOf(value);\n  if (index >= 0) {\n    array.splice(index, 1);\n  }\n  return index;\n}\n\n/**\n * @ngdoc function\n * @name angular.copy\n * @module ng\n * @kind function\n *\n * @description\n * Creates a deep copy of `source`, which should be an object or an array.\n *\n * * If no destination is supplied, a copy of the object or array is created.\n * * If a destination is provided, all of its elements (for arrays) or properties (for objects)\n *   are deleted and then all elements/properties from the source are copied to it.\n * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.\n * * If `source` is identical to `destination` an exception will be thrown.\n *\n * <br />\n * <div class=\"alert alert-warning\">\n *   Only enumerable properties are taken into account. Non-enumerable properties (both on `source`\n *   and on `destination`) will be ignored.\n * </div>\n *\n * @param {*} source The source that will be used to make a copy.\n *                   Can be any type, including primitives, `null`, and `undefined`.\n * @param {(Object|Array)=} destination Destination into which the source is copied. If\n *     provided, must be of the same type as `source`.\n * @returns {*} The copy or updated `destination`, if `destination` was specified.\n *\n * @example\n  <example module=\"copyExample\" name=\"angular-copy\">\n    <file name=\"index.html\">\n      <div ng-controller=\"ExampleController\">\n        <form novalidate class=\"simple-form\">\n          <label>Name: <input type=\"text\" ng-model=\"user.name\" /></label><br />\n          <label>Age:  <input type=\"number\" ng-model=\"user.age\" /></label><br />\n          Gender: <label><input type=\"radio\" ng-model=\"user.gender\" value=\"male\" />male</label>\n                  <label><input type=\"radio\" ng-model=\"user.gender\" value=\"female\" />female</label><br />\n          <button ng-click=\"reset()\">RESET</button>\n          <button ng-click=\"update(user)\">SAVE</button>\n        </form>\n        <pre>form = {{user | json}}</pre>\n        <pre>master = {{master | json}}</pre>\n      </div>\n    </file>\n    <file name=\"script.js\">\n      // Module: copyExample\n      angular.\n        module('copyExample', []).\n        controller('ExampleController', ['$scope', function($scope) {\n          $scope.master = {};\n\n          $scope.reset = function() {\n            // Example with 1 argument\n            $scope.user = angular.copy($scope.master);\n          };\n\n          $scope.update = function(user) {\n            // Example with 2 arguments\n            angular.copy(user, $scope.master);\n          };\n\n          $scope.reset();\n        }]);\n    </file>\n  </example>\n */\nfunction copy(source, destination, maxDepth) {\n  var stackSource = [];\n  var stackDest = [];\n  maxDepth = isValidObjectMaxDepth(maxDepth) ? maxDepth : NaN;\n\n  if (destination) {\n    if (isTypedArray(destination) || isArrayBuffer(destination)) {\n      throw ngMinErr('cpta', 'Can\\'t copy! TypedArray destination cannot be mutated.');\n    }\n    if (source === destination) {\n      throw ngMinErr('cpi', 'Can\\'t copy! Source and destination are identical.');\n    }\n\n    // Empty the destination object\n    if (isArray(destination)) {\n      destination.length = 0;\n    } else {\n      forEach(destination, function(value, key) {\n        if (key !== '$$hashKey') {\n          delete destination[key];\n        }\n      });\n    }\n\n    stackSource.push(source);\n    stackDest.push(destination);\n    return copyRecurse(source, destination, maxDepth);\n  }\n\n  return copyElement(source, maxDepth);\n\n  function copyRecurse(source, destination, maxDepth) {\n    maxDepth--;\n    if (maxDepth < 0) {\n      return '...';\n    }\n    var h = destination.$$hashKey;\n    var key;\n    if (isArray(source)) {\n      for (var i = 0, ii = source.length; i < ii; i++) {\n        destination.push(copyElement(source[i], maxDepth));\n      }\n    } else if (isBlankObject(source)) {\n      // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty\n      for (key in source) {\n        destination[key] = copyElement(source[key], maxDepth);\n      }\n    } else if (source && typeof source.hasOwnProperty === 'function') {\n      // Slow path, which must rely on hasOwnProperty\n      for (key in source) {\n        if (source.hasOwnProperty(key)) {\n          destination[key] = copyElement(source[key], maxDepth);\n        }\n      }\n    } else {\n      // Slowest path --- hasOwnProperty can't be called as a method\n      for (key in source) {\n        if (hasOwnProperty.call(source, key)) {\n          destination[key] = copyElement(source[key], maxDepth);\n        }\n      }\n    }\n    setHashKey(destination, h);\n    return destination;\n  }\n\n  function copyElement(source, maxDepth) {\n    // Simple values\n    if (!isObject(source)) {\n      return source;\n    }\n\n    // Already copied values\n    var index = stackSource.indexOf(source);\n    if (index !== -1) {\n      return stackDest[index];\n    }\n\n    if (isWindow(source) || isScope(source)) {\n      throw ngMinErr('cpws',\n        'Can\\'t copy! Making copies of Window or Scope instances is not supported.');\n    }\n\n    var needsRecurse = false;\n    var destination = copyType(source);\n\n    if (destination === undefined) {\n      destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));\n      needsRecurse = true;\n    }\n\n    stackSource.push(source);\n    stackDest.push(destination);\n\n    return needsRecurse\n      ? copyRecurse(source, destination, maxDepth)\n      : destination;\n  }\n\n  function copyType(source) {\n    switch (toString.call(source)) {\n      case '[object Int8Array]':\n      case '[object Int16Array]':\n      case '[object Int32Array]':\n      case '[object Float32Array]':\n      case '[object Float64Array]':\n      case '[object Uint8Array]':\n      case '[object Uint8ClampedArray]':\n      case '[object Uint16Array]':\n      case '[object Uint32Array]':\n        return new source.constructor(copyElement(source.buffer), source.byteOffset, source.length);\n\n      case '[object ArrayBuffer]':\n        // Support: IE10\n        if (!source.slice) {\n          // If we're in this case we know the environment supports ArrayBuffer\n          /* eslint-disable no-undef */\n          var copied = new ArrayBuffer(source.byteLength);\n          new Uint8Array(copied).set(new Uint8Array(source));\n          /* eslint-enable */\n          return copied;\n        }\n        return source.slice(0);\n\n      case '[object Boolean]':\n      case '[object Number]':\n      case '[object String]':\n      case '[object Date]':\n        return new source.constructor(source.valueOf());\n\n      case '[object RegExp]':\n        var re = new RegExp(source.source, source.toString().match(/[^/]*$/)[0]);\n        re.lastIndex = source.lastIndex;\n        return re;\n\n      case '[object Blob]':\n        return new source.constructor([source], {type: source.type});\n    }\n\n    if (isFunction(source.cloneNode)) {\n      return source.cloneNode(true);\n    }\n  }\n}\n\n\n/**\n * @ngdoc function\n * @name angular.equals\n * @module ng\n * @kind function\n *\n * @description\n * Determines if two objects or two values are equivalent. Supports value types, regular\n * expressions, arrays and objects.\n *\n * Two objects or values are considered equivalent if at least one of the following is true:\n *\n * * Both objects or values pass `===` comparison.\n * * Both objects or values are of the same type and all of their properties are equal by\n *   comparing them with `angular.equals`.\n * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)\n * * Both values represent the same regular expression (In JavaScript,\n *   /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual\n *   representation matches).\n *\n * During a property comparison, properties of `function` type and properties with names\n * that begin with `$` are ignored.\n *\n * Scope and DOMWindow objects are being compared only by identify (`===`).\n *\n * @param {*} o1 Object or value to compare.\n * @param {*} o2 Object or value to compare.\n * @returns {boolean} True if arguments are equal.\n *\n * @example\n   <example module=\"equalsExample\" name=\"equalsExample\">\n     <file name=\"index.html\">\n      <div ng-controller=\"ExampleController\">\n        <form novalidate>\n          <h3>User 1</h3>\n          Name: <input type=\"text\" ng-model=\"user1.name\">\n          Age: <input type=\"number\" ng-model=\"user1.age\">\n\n          <h3>User 2</h3>\n          Name: <input type=\"text\" ng-model=\"user2.name\">\n          Age: <input type=\"number\" ng-model=\"user2.age\">\n\n          <div>\n            <br/>\n            <input type=\"button\" value=\"Compare\" ng-click=\"compare()\">\n          </div>\n          User 1: <pre>{{user1 | json}}</pre>\n          User 2: <pre>{{user2 | json}}</pre>\n          Equal: <pre>{{result}}</pre>\n        </form>\n      </div>\n    </file>\n    <file name=\"script.js\">\n        angular.module('equalsExample', []).controller('ExampleController', ['$scope', function($scope) {\n          $scope.user1 = {};\n          $scope.user2 = {};\n          $scope.compare = function() {\n            $scope.result = angular.equals($scope.user1, $scope.user2);\n          };\n        }]);\n    </file>\n  </example>\n */\nfunction equals(o1, o2) {\n  if (o1 === o2) return true;\n  if (o1 === null || o2 === null) return false;\n  // eslint-disable-next-line no-self-compare\n  if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN\n  var t1 = typeof o1, t2 = typeof o2, length, key, keySet;\n  if (t1 === t2 && t1 === 'object') {\n    if (isArray(o1)) {\n      if (!isArray(o2)) return false;\n      if ((length = o1.length) === o2.length) {\n        for (key = 0; key < length; key++) {\n          if (!equals(o1[key], o2[key])) return false;\n        }\n        return true;\n      }\n    } else if (isDate(o1)) {\n      if (!isDate(o2)) return false;\n      return equals(o1.getTime(), o2.getTime());\n    } else if (isRegExp(o1)) {\n      if (!isRegExp(o2)) return false;\n      return o1.toString() === o2.toString();\n    } else {\n      if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||\n        isArray(o2) || isDate(o2) || isRegExp(o2)) return false;\n      keySet = createMap();\n      for (key in o1) {\n        if (key.charAt(0) === '$' || isFunction(o1[key])) continue;\n        if (!equals(o1[key], o2[key])) return false;\n        keySet[key] = true;\n      }\n      for (key in o2) {\n        if (!(key in keySet) &&\n            key.charAt(0) !== '$' &&\n            isDefined(o2[key]) &&\n            !isFunction(o2[key])) return false;\n      }\n      return true;\n    }\n  }\n  return false;\n}\n\nvar csp = function() {\n  if (!isDefined(csp.rules)) {\n\n\n    var ngCspElement = (window.document.querySelector('[ng-csp]') ||\n                    window.document.querySelector('[data-ng-csp]'));\n\n    if (ngCspElement) {\n      var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||\n                    ngCspElement.getAttribute('data-ng-csp');\n      csp.rules = {\n        noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),\n        noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)\n      };\n    } else {\n      csp.rules = {\n        noUnsafeEval: noUnsafeEval(),\n        noInlineStyle: false\n      };\n    }\n  }\n\n  return csp.rules;\n\n  function noUnsafeEval() {\n    try {\n      // eslint-disable-next-line no-new, no-new-func\n      new Function('');\n      return false;\n    } catch (e) {\n      return true;\n    }\n  }\n};\n\n/**\n * @ngdoc directive\n * @module ng\n * @name ngJq\n *\n * @element ANY\n * @param {string=} ngJq the name of the library available under `window`\n * to be used for angular.element\n * @description\n * Use this directive to force the angular.element library.  This should be\n * used to force either jqLite by leaving ng-jq blank or setting the name of\n * the jquery variable under window (eg. jQuery).\n *\n * Since angular looks for this directive when it is loaded (doesn't wait for the\n * DOMContentLoaded event), it must be placed on an element that comes before the script\n * which loads angular. Also, only the first instance of `ng-jq` will be used and all\n * others ignored.\n *\n * @example\n * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.\n ```html\n <!doctype html>\n <html ng-app ng-jq>\n ...\n ...\n </html>\n ```\n * @example\n * This example shows how to use a jQuery based library of a different name.\n * The library name must be available at the top most 'window'.\n ```html\n <!doctype html>\n <html ng-app ng-jq=\"jQueryLib\">\n ...\n ...\n </html>\n ```\n */\nvar jq = function() {\n  if (isDefined(jq.name_)) return jq.name_;\n  var el;\n  var i, ii = ngAttrPrefixes.length, prefix, name;\n  for (i = 0; i < ii; ++i) {\n    prefix = ngAttrPrefixes[i];\n    el = window.document.querySelector('[' + prefix.replace(':', '\\\\:') + 'jq]');\n    if (el) {\n      name = el.getAttribute(prefix + 'jq');\n      break;\n    }\n  }\n\n  return (jq.name_ = name);\n};\n\nfunction concat(array1, array2, index) {\n  return array1.concat(slice.call(array2, index));\n}\n\nfunction sliceArgs(args, startIndex) {\n  return slice.call(args, startIndex || 0);\n}\n\n\n/**\n * @ngdoc function\n * @name angular.bind\n * @module ng\n * @kind function\n *\n * @description\n * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for\n * `fn`). You can supply optional `args` that are prebound to the function. This feature is also\n * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as\n * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).\n *\n * @param {Object} self Context which `fn` should be evaluated in.\n * @param {function()} fn Function to be bound.\n * @param {...*} args Optional arguments to be prebound to the `fn` function call.\n * @returns {function()} Function that wraps the `fn` with all the specified bindings.\n */\nfunction bind(self, fn) {\n  var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];\n  if (isFunction(fn) && !(fn instanceof RegExp)) {\n    return curryArgs.length\n      ? function() {\n          return arguments.length\n            ? fn.apply(self, concat(curryArgs, arguments, 0))\n            : fn.apply(self, curryArgs);\n        }\n      : function() {\n          return arguments.length\n            ? fn.apply(self, arguments)\n            : fn.call(self);\n        };\n  } else {\n    // In IE, native methods are not functions so they cannot be bound (note: they don't need to be).\n    return fn;\n  }\n}\n\n\nfunction toJsonReplacer(key, value) {\n  var val = value;\n\n  if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {\n    val = undefined;\n  } else if (isWindow(value)) {\n    val = '$WINDOW';\n  } else if (value &&  window.document === value) {\n    val = '$DOCUMENT';\n  } else if (isScope(value)) {\n    val = '$SCOPE';\n  }\n\n  return val;\n}\n\n\n/**\n * @ngdoc function\n * @name angular.toJson\n * @module ng\n * @kind function\n *\n * @description\n * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be\n * stripped since angular uses this notation internally.\n *\n * @param {Object|Array|Date|string|number|boolean} obj Input to be serialized into JSON.\n * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.\n *    If set to an integer, the JSON output will contain that many spaces per indentation.\n * @returns {string|undefined} JSON-ified string representing `obj`.\n * @knownIssue\n *\n * The Safari browser throws a `RangeError` instead of returning `null` when it tries to stringify a `Date`\n * object with an invalid date value. The only reliable way to prevent this is to monkeypatch the\n * `Date.prototype.toJSON` method as follows:\n *\n * ```\n * var _DatetoJSON = Date.prototype.toJSON;\n * Date.prototype.toJSON = function() {\n *   try {\n *     return _DatetoJSON.call(this);\n *   } catch(e) {\n *     if (e instanceof RangeError) {\n *       return null;\n *     }\n *     throw e;\n *   }\n * };\n * ```\n *\n * See https://github.com/angular/angular.js/pull/14221 for more information.\n */\nfunction toJson(obj, pretty) {\n  if (isUndefined(obj)) return undefined;\n  if (!isNumber(pretty)) {\n    pretty = pretty ? 2 : null;\n  }\n  return JSON.stringify(obj, toJsonReplacer, pretty);\n}\n\n\n/**\n * @ngdoc function\n * @name angular.fromJson\n * @module ng\n * @kind function\n *\n * @description\n * Deserializes a JSON string.\n *\n * @param {string} json JSON string to deserialize.\n * @returns {Object|Array|string|number} Deserialized JSON string.\n */\nfunction fromJson(json) {\n  return isString(json)\n      ? JSON.parse(json)\n      : json;\n}\n\n\nvar ALL_COLONS = /:/g;\nfunction timezoneToOffset(timezone, fallback) {\n  // Support: IE 9-11 only, Edge 13-14+\n  // IE/Edge do not \"understand\" colon (`:`) in timezone\n  timezone = timezone.replace(ALL_COLONS, '');\n  var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;\n  return isNumberNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;\n}\n\n\nfunction addDateMinutes(date, minutes) {\n  date = new Date(date.getTime());\n  date.setMinutes(date.getMinutes() + minutes);\n  return date;\n}\n\n\nfunction convertTimezoneToLocal(date, timezone, reverse) {\n  reverse = reverse ? -1 : 1;\n  var dateTimezoneOffset = date.getTimezoneOffset();\n  var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);\n  return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));\n}\n\n\n/**\n * @returns {string} Returns the string representation of the element.\n */\nfunction startingTag(element) {\n  element = jqLite(element).clone();\n  try {\n    // turns out IE does not let you set .html() on elements which\n    // are not allowed to have children. So we just ignore it.\n    element.empty();\n  } catch (e) { /* empty */ }\n  var elemHtml = jqLite('<div>').append(element).html();\n  try {\n    return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :\n        elemHtml.\n          match(/^(<[^>]+>)/)[1].\n          replace(/^<([\\w-]+)/, function(match, nodeName) {return '<' + lowercase(nodeName);});\n  } catch (e) {\n    return lowercase(elemHtml);\n  }\n\n}\n\n\n/////////////////////////////////////////////////\n\n/**\n * Tries to decode the URI component without throwing an exception.\n *\n * @private\n * @param str value potential URI component to check.\n * @returns {boolean} True if `value` can be decoded\n * with the decodeURIComponent function.\n */\nfunction tryDecodeURIComponent(value) {\n  try {\n    return decodeURIComponent(value);\n  } catch (e) {\n    // Ignore any invalid uri component.\n  }\n}\n\n\n/**\n * Parses an escaped url query string into key-value pairs.\n * @returns {Object.<string,boolean|Array>}\n */\nfunction parseKeyValue(/**string*/keyValue) {\n  var obj = {};\n  forEach((keyValue || '').split('&'), function(keyValue) {\n    var splitPoint, key, val;\n    if (keyValue) {\n      key = keyValue = keyValue.replace(/\\+/g,'%20');\n      splitPoint = keyValue.indexOf('=');\n      if (splitPoint !== -1) {\n        key = keyValue.substring(0, splitPoint);\n        val = keyValue.substring(splitPoint + 1);\n      }\n      key = tryDecodeURIComponent(key);\n      if (isDefined(key)) {\n        val = isDefined(val) ? tryDecodeURIComponent(val) : true;\n        if (!hasOwnProperty.call(obj, key)) {\n          obj[key] = val;\n        } else if (isArray(obj[key])) {\n          obj[key].push(val);\n        } else {\n          obj[key] = [obj[key],val];\n        }\n      }\n    }\n  });\n  return obj;\n}\n\nfunction toKeyValue(obj) {\n  var parts = [];\n  forEach(obj, function(value, key) {\n    if (isArray(value)) {\n      forEach(value, function(arrayValue) {\n        parts.push(encodeUriQuery(key, true) +\n                   (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));\n      });\n    } else {\n    parts.push(encodeUriQuery(key, true) +\n               (value === true ? '' : '=' + encodeUriQuery(value, true)));\n    }\n  });\n  return parts.length ? parts.join('&') : '';\n}\n\n\n/**\n * We need our custom method because encodeURIComponent is too aggressive and doesn't follow\n * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path\n * segments:\n *    segment       = *pchar\n *    pchar         = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n *    pct-encoded   = \"%\" HEXDIG HEXDIG\n *    unreserved    = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n *    sub-delims    = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n *                     / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n */\nfunction encodeUriSegment(val) {\n  return encodeUriQuery(val, true).\n             replace(/%26/gi, '&').\n             replace(/%3D/gi, '=').\n             replace(/%2B/gi, '+');\n}\n\n\n/**\n * This method is intended for encoding *key* or *value* parts of query component. We need a custom\n * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be\n * encoded per http://tools.ietf.org/html/rfc3986:\n *    query         = *( pchar / \"/\" / \"?\" )\n *    pchar         = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n *    unreserved    = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n *    pct-encoded   = \"%\" HEXDIG HEXDIG\n *    sub-delims    = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n *                     / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n */\nfunction encodeUriQuery(val, pctEncodeSpaces) {\n  return encodeURIComponent(val).\n             replace(/%40/gi, '@').\n             replace(/%3A/gi, ':').\n             replace(/%24/g, '$').\n             replace(/%2C/gi, ',').\n             replace(/%3B/gi, ';').\n             replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));\n}\n\nvar ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];\n\nfunction getNgAttribute(element, ngAttr) {\n  var attr, i, ii = ngAttrPrefixes.length;\n  for (i = 0; i < ii; ++i) {\n    attr = ngAttrPrefixes[i] + ngAttr;\n    if (isString(attr = element.getAttribute(attr))) {\n      return attr;\n    }\n  }\n  return null;\n}\n\nfunction allowAutoBootstrap(document) {\n  var script = document.currentScript;\n\n  if (!script) {\n    // IE does not have `document.currentScript`\n    return true;\n  }\n\n  // If the `currentScript` property has been clobbered just return false, since this indicates a probable attack\n  if (!(script instanceof window.HTMLScriptElement || script instanceof window.SVGScriptElement)) {\n    return false;\n  }\n\n  var attributes = script.attributes;\n  var srcs = [attributes.getNamedItem('src'), attributes.getNamedItem('href'), attributes.getNamedItem('xlink:href')];\n\n  return srcs.every(function(src) {\n    if (!src) {\n      return true;\n    }\n    if (!src.value) {\n      return false;\n    }\n\n    var link = document.createElement('a');\n    link.href = src.value;\n\n    if (document.location.origin === link.origin) {\n      // Same-origin resources are always allowed, even for non-whitelisted schemes.\n      return true;\n    }\n    // Disabled bootstrapping unless angular.js was loaded from a known scheme used on the web.\n    // This is to prevent angular.js bundled with browser extensions from being used to bypass the\n    // content security policy in web pages and other browser extensions.\n    switch (link.protocol) {\n      case 'http:':\n      case 'https:':\n      case 'ftp:':\n      case 'blob:':\n      case 'file:':\n      case 'data:':\n        return true;\n      default:\n        return false;\n    }\n  });\n}\n\n// Cached as it has to run during loading so that document.currentScript is available.\nvar isAutoBootstrapAllowed = allowAutoBootstrap(window.document);\n\n/**\n * @ngdoc directive\n * @name ngApp\n * @module ng\n *\n * @element ANY\n * @param {angular.Module} ngApp an optional application\n *   {@link angular.module module} name to load.\n * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be\n *   created in \"strict-di\" mode. This means that the application will fail to invoke functions which\n *   do not use explicit function annotation (and are thus unsuitable for minification), as described\n *   in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in\n *   tracking down the root of these bugs.\n *\n * @description\n *\n * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive\n * designates the **root element** of the application and is typically placed near the root element\n * of the page - e.g. on the `<body>` or `<html>` tags.\n *\n * There are a few things to keep in mind when using `ngApp`:\n * - only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`\n *   found in the document will be used to define the root element to auto-bootstrap as an\n *   application. To run multiple applications in an HTML document you must manually bootstrap them using\n *   {@link angular.bootstrap} instead.\n * - AngularJS applications cannot be nested within each other.\n * - Do not use a directive that uses {@link ng.$compile#transclusion transclusion} on the same element as `ngApp`.\n *   This includes directives such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and\n *   {@link ngRoute.ngView `ngView`}.\n *   Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},\n *   causing animations to stop working and making the injector inaccessible from outside the app.\n *\n * You can specify an **AngularJS module** to be used as the root module for the application.  This\n * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It\n * should contain the application code needed or have dependencies on other modules that will\n * contain the code. See {@link angular.module} for more information.\n *\n * In the example below if the `ngApp` directive were not placed on the `html` element then the\n * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`\n * would not be resolved to `3`.\n *\n * `ngApp` is the easiest, and most common way to bootstrap an application.\n *\n <example module=\"ngAppDemo\" name=\"ng-app\">\n   <file name=\"index.html\">\n   <div ng-controller=\"ngAppDemoController\">\n     I can add: {{a}} + {{b}} =  {{ a+b }}\n   </div>\n   </file>\n   <file name=\"script.js\">\n   angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {\n     $scope.a = 1;\n     $scope.b = 2;\n   });\n   </file>\n </example>\n *\n * Using `ngStrictDi`, you would see something like this:\n *\n <example ng-app-included=\"true\" name=\"strict-di\">\n   <file name=\"index.html\">\n   <div ng-app=\"ngAppStrictDemo\" ng-strict-di>\n       <div ng-controller=\"GoodController1\">\n           I can add: {{a}} + {{b}} =  {{ a+b }}\n\n           <p>This renders because the controller does not fail to\n              instantiate, by using explicit annotation style (see\n              script.js for details)\n           </p>\n       </div>\n\n       <div ng-controller=\"GoodController2\">\n           Name: <input ng-model=\"name\"><br />\n           Hello, {{name}}!\n\n           <p>This renders because the controller does not fail to\n              instantiate, by using explicit annotation style\n              (see script.js for details)\n           </p>\n       </div>\n\n       <div ng-controller=\"BadController\">\n           I can add: {{a}} + {{b}} =  {{ a+b }}\n\n           <p>The controller could not be instantiated, due to relying\n              on automatic function annotations (which are disabled in\n              strict mode). As such, the content of this section is not\n              interpolated, and there should be an error in your web console.\n           </p>\n       </div>\n   </div>\n   </file>\n   <file name=\"script.js\">\n   angular.module('ngAppStrictDemo', [])\n     // BadController will fail to instantiate, due to relying on automatic function annotation,\n     // rather than an explicit annotation\n     .controller('BadController', function($scope) {\n       $scope.a = 1;\n       $scope.b = 2;\n     })\n     // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,\n     // due to using explicit annotations using the array style and $inject property, respectively.\n     .controller('GoodController1', ['$scope', function($scope) {\n       $scope.a = 1;\n       $scope.b = 2;\n     }])\n     .controller('GoodController2', GoodController2);\n     function GoodController2($scope) {\n       $scope.name = 'World';\n     }\n     GoodController2.$inject = ['$scope'];\n   </file>\n   <file name=\"style.css\">\n   div[ng-controller] {\n       margin-bottom: 1em;\n       -webkit-border-radius: 4px;\n       border-radius: 4px;\n       border: 1px solid;\n       padding: .5em;\n   }\n   div[ng-controller^=Good] {\n       border-color: #d6e9c6;\n       background-color: #dff0d8;\n       color: #3c763d;\n   }\n   div[ng-controller^=Bad] {\n       border-color: #ebccd1;\n       background-color: #f2dede;\n       color: #a94442;\n       margin-bottom: 0;\n   }\n   </file>\n </example>\n */\nfunction angularInit(element, bootstrap) {\n  var appElement,\n      module,\n      config = {};\n\n  // The element `element` has priority over any other element.\n  forEach(ngAttrPrefixes, function(prefix) {\n    var name = prefix + 'app';\n\n    if (!appElement && element.hasAttribute && element.hasAttribute(name)) {\n      appElement = element;\n      module = element.getAttribute(name);\n    }\n  });\n  forEach(ngAttrPrefixes, function(prefix) {\n    var name = prefix + 'app';\n    var candidate;\n\n    if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\\\:') + ']'))) {\n      appElement = candidate;\n      module = candidate.getAttribute(name);\n    }\n  });\n  if (appElement) {\n    if (!isAutoBootstrapAllowed) {\n      window.console.error('Angular: disabling automatic bootstrap. <script> protocol indicates ' +\n          'an extension, document.location.href does not match.');\n      return;\n    }\n    config.strictDi = getNgAttribute(appElement, 'strict-di') !== null;\n    bootstrap(appElement, module ? [module] : [], config);\n  }\n}\n\n/**\n * @ngdoc function\n * @name angular.bootstrap\n * @module ng\n * @description\n * Use this function to manually start up angular application.\n *\n * For more information, see the {@link guide/bootstrap Bootstrap guide}.\n *\n * Angular will detect if it has been loaded into the browser more than once and only allow the\n * first loaded script to be bootstrapped and will report a warning to the browser console for\n * each of the subsequent scripts. This prevents strange results in applications, where otherwise\n * multiple instances of Angular try to work on the DOM.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Protractor based end-to-end tests cannot use this function to bootstrap manually.\n * They must use {@link ng.directive:ngApp ngApp}.\n * </div>\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion},\n * such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.\n * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},\n * causing animations to stop working and making the injector inaccessible from outside the app.\n * </div>\n *\n * ```html\n * <!doctype html>\n * <html>\n * <body>\n * <div ng-controller=\"WelcomeController\">\n *   {{greeting}}\n * </div>\n *\n * <script src=\"angular.js\"></script>\n * <script>\n *   var app = angular.module('demo', [])\n *   .controller('WelcomeController', function($scope) {\n *       $scope.greeting = 'Welcome!';\n *   });\n *   angular.bootstrap(document, ['demo']);\n * </script>\n * </body>\n * </html>\n * ```\n *\n * @param {DOMElement} element DOM element which is the root of angular application.\n * @param {Array<String|Function|Array>=} modules an array of modules to load into the application.\n *     Each item in the array should be the name of a predefined module or a (DI annotated)\n *     function that will be invoked by the injector as a `config` block.\n *     See: {@link angular.module modules}\n * @param {Object=} config an object for defining configuration options for the application. The\n *     following keys are supported:\n *\n * * `strictDi` - disable automatic function annotation for the application. This is meant to\n *   assist in finding bugs which break minified code. Defaults to `false`.\n *\n * @returns {auto.$injector} Returns the newly created injector for this app.\n */\nfunction bootstrap(element, modules, config) {\n  if (!isObject(config)) config = {};\n  var defaultConfig = {\n    strictDi: false\n  };\n  config = extend(defaultConfig, config);\n  var doBootstrap = function() {\n    element = jqLite(element);\n\n    if (element.injector()) {\n      var tag = (element[0] === window.document) ? 'document' : startingTag(element);\n      // Encode angle brackets to prevent input from being sanitized to empty string #8683.\n      throw ngMinErr(\n          'btstrpd',\n          'App already bootstrapped with this element \\'{0}\\'',\n          tag.replace(/</,'&lt;').replace(/>/,'&gt;'));\n    }\n\n    modules = modules || [];\n    modules.unshift(['$provide', function($provide) {\n      $provide.value('$rootElement', element);\n    }]);\n\n    if (config.debugInfoEnabled) {\n      // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.\n      modules.push(['$compileProvider', function($compileProvider) {\n        $compileProvider.debugInfoEnabled(true);\n      }]);\n    }\n\n    modules.unshift('ng');\n    var injector = createInjector(modules, config.strictDi);\n    injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',\n       function bootstrapApply(scope, element, compile, injector) {\n        scope.$apply(function() {\n          element.data('$injector', injector);\n          compile(element)(scope);\n        });\n      }]\n    );\n    return injector;\n  };\n\n  var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;\n  var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;\n\n  if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {\n    config.debugInfoEnabled = true;\n    window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');\n  }\n\n  if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {\n    return doBootstrap();\n  }\n\n  window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');\n  angular.resumeBootstrap = function(extraModules) {\n    forEach(extraModules, function(module) {\n      modules.push(module);\n    });\n    return doBootstrap();\n  };\n\n  if (isFunction(angular.resumeDeferredBootstrap)) {\n    angular.resumeDeferredBootstrap();\n  }\n}\n\n/**\n * @ngdoc function\n * @name angular.reloadWithDebugInfo\n * @module ng\n * @description\n * Use this function to reload the current application with debug information turned on.\n * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`.\n *\n * See {@link ng.$compileProvider#debugInfoEnabled} for more.\n */\nfunction reloadWithDebugInfo() {\n  window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;\n  window.location.reload();\n}\n\n/**\n * @name angular.getTestability\n * @module ng\n * @description\n * Get the testability service for the instance of Angular on the given\n * element.\n * @param {DOMElement} element DOM element which is the root of angular application.\n */\nfunction getTestability(rootElement) {\n  var injector = angular.element(rootElement).injector();\n  if (!injector) {\n    throw ngMinErr('test',\n      'no injector found for element argument to getTestability');\n  }\n  return injector.get('$$testability');\n}\n\nvar SNAKE_CASE_REGEXP = /[A-Z]/g;\nfunction snake_case(name, separator) {\n  separator = separator || '_';\n  return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {\n    return (pos ? separator : '') + letter.toLowerCase();\n  });\n}\n\nvar bindJQueryFired = false;\nfunction bindJQuery() {\n  var originalCleanData;\n\n  if (bindJQueryFired) {\n    return;\n  }\n\n  // bind to jQuery if present;\n  var jqName = jq();\n  jQuery = isUndefined(jqName) ? window.jQuery :   // use jQuery (if present)\n           !jqName             ? undefined     :   // use jqLite\n                                 window[jqName];   // use jQuery specified by `ngJq`\n\n  // Use jQuery if it exists with proper functionality, otherwise default to us.\n  // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.\n  // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older\n  // versions. It will not work for sure with jQuery <1.7, though.\n  if (jQuery && jQuery.fn.on) {\n    jqLite = jQuery;\n    extend(jQuery.fn, {\n      scope: JQLitePrototype.scope,\n      isolateScope: JQLitePrototype.isolateScope,\n      controller: /** @type {?} */ (JQLitePrototype).controller,\n      injector: JQLitePrototype.injector,\n      inheritedData: JQLitePrototype.inheritedData\n    });\n\n    // All nodes removed from the DOM via various jQuery APIs like .remove()\n    // are passed through jQuery.cleanData. Monkey-patch this method to fire\n    // the $destroy event on all removed nodes.\n    originalCleanData = jQuery.cleanData;\n    jQuery.cleanData = function(elems) {\n      var events;\n      for (var i = 0, elem; (elem = elems[i]) != null; i++) {\n        events = jQuery._data(elem, 'events');\n        if (events && events.$destroy) {\n          jQuery(elem).triggerHandler('$destroy');\n        }\n      }\n      originalCleanData(elems);\n    };\n  } else {\n    jqLite = JQLite;\n  }\n\n  angular.element = jqLite;\n\n  // Prevent double-proxying.\n  bindJQueryFired = true;\n}\n\n/**\n * throw error if the argument is falsy.\n */\nfunction assertArg(arg, name, reason) {\n  if (!arg) {\n    throw ngMinErr('areq', 'Argument \\'{0}\\' is {1}', (name || '?'), (reason || 'required'));\n  }\n  return arg;\n}\n\nfunction assertArgFn(arg, name, acceptArrayAnnotation) {\n  if (acceptArrayAnnotation && isArray(arg)) {\n      arg = arg[arg.length - 1];\n  }\n\n  assertArg(isFunction(arg), name, 'not a function, got ' +\n      (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));\n  return arg;\n}\n\n/**\n * throw error if the name given is hasOwnProperty\n * @param  {String} name    the name to test\n * @param  {String} context the context in which the name is used, such as module or directive\n */\nfunction assertNotHasOwnProperty(name, context) {\n  if (name === 'hasOwnProperty') {\n    throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);\n  }\n}\n\n/**\n * Return the value accessible from the object by path. Any undefined traversals are ignored\n * @param {Object} obj starting object\n * @param {String} path path to traverse\n * @param {boolean} [bindFnToScope=true]\n * @returns {Object} value as accessible by path\n */\n//TODO(misko): this function needs to be removed\nfunction getter(obj, path, bindFnToScope) {\n  if (!path) return obj;\n  var keys = path.split('.');\n  var key;\n  var lastInstance = obj;\n  var len = keys.length;\n\n  for (var i = 0; i < len; i++) {\n    key = keys[i];\n    if (obj) {\n      obj = (lastInstance = obj)[key];\n    }\n  }\n  if (!bindFnToScope && isFunction(obj)) {\n    return bind(lastInstance, obj);\n  }\n  return obj;\n}\n\n/**\n * Return the DOM siblings between the first and last node in the given array.\n * @param {Array} array like object\n * @returns {Array} the inputted object or a jqLite collection containing the nodes\n */\nfunction getBlockNodes(nodes) {\n  // TODO(perf): update `nodes` instead of creating a new object?\n  var node = nodes[0];\n  var endNode = nodes[nodes.length - 1];\n  var blockNodes;\n\n  for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {\n    if (blockNodes || nodes[i] !== node) {\n      if (!blockNodes) {\n        blockNodes = jqLite(slice.call(nodes, 0, i));\n      }\n      blockNodes.push(node);\n    }\n  }\n\n  return blockNodes || nodes;\n}\n\n\n/**\n * Creates a new object without a prototype. This object is useful for lookup without having to\n * guard against prototypically inherited properties via hasOwnProperty.\n *\n * Related micro-benchmarks:\n * - http://jsperf.com/object-create2\n * - http://jsperf.com/proto-map-lookup/2\n * - http://jsperf.com/for-in-vs-object-keys2\n *\n * @returns {Object}\n */\nfunction createMap() {\n  return Object.create(null);\n}\n\nfunction stringify(value) {\n  if (value == null) { // null || undefined\n    return '';\n  }\n  switch (typeof value) {\n    case 'string':\n      break;\n    case 'number':\n      value = '' + value;\n      break;\n    default:\n      if (hasCustomToString(value) && !isArray(value) && !isDate(value)) {\n        value = value.toString();\n      } else {\n        value = toJson(value);\n      }\n  }\n\n  return value;\n}\n\nvar NODE_TYPE_ELEMENT = 1;\nvar NODE_TYPE_ATTRIBUTE = 2;\nvar NODE_TYPE_TEXT = 3;\nvar NODE_TYPE_COMMENT = 8;\nvar NODE_TYPE_DOCUMENT = 9;\nvar NODE_TYPE_DOCUMENT_FRAGMENT = 11;\n\n/**\n * @ngdoc type\n * @name angular.Module\n * @module ng\n * @description\n *\n * Interface for configuring angular {@link angular.module modules}.\n */\n\nfunction setupModuleLoader(window) {\n\n  var $injectorMinErr = minErr('$injector');\n  var ngMinErr = minErr('ng');\n\n  function ensure(obj, name, factory) {\n    return obj[name] || (obj[name] = factory());\n  }\n\n  var angular = ensure(window, 'angular', Object);\n\n  // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap\n  angular.$$minErr = angular.$$minErr || minErr;\n\n  return ensure(angular, 'module', function() {\n    /** @type {Object.<string, angular.Module>} */\n    var modules = {};\n\n    /**\n     * @ngdoc function\n     * @name angular.module\n     * @module ng\n     * @description\n     *\n     * The `angular.module` is a global place for creating, registering and retrieving Angular\n     * modules.\n     * All modules (angular core or 3rd party) that should be available to an application must be\n     * registered using this mechanism.\n     *\n     * Passing one argument retrieves an existing {@link angular.Module},\n     * whereas passing more than one argument creates a new {@link angular.Module}\n     *\n     *\n     * # Module\n     *\n     * A module is a collection of services, directives, controllers, filters, and configuration information.\n     * `angular.module` is used to configure the {@link auto.$injector $injector}.\n     *\n     * ```js\n     * // Create a new module\n     * var myModule = angular.module('myModule', []);\n     *\n     * // register a new service\n     * myModule.value('appName', 'MyCoolApp');\n     *\n     * // configure existing services inside initialization blocks.\n     * myModule.config(['$locationProvider', function($locationProvider) {\n     *   // Configure existing providers\n     *   $locationProvider.hashPrefix('!');\n     * }]);\n     * ```\n     *\n     * Then you can create an injector and load your modules like this:\n     *\n     * ```js\n     * var injector = angular.injector(['ng', 'myModule'])\n     * ```\n     *\n     * However it's more likely that you'll just use\n     * {@link ng.directive:ngApp ngApp} or\n     * {@link angular.bootstrap} to simplify this process for you.\n     *\n     * @param {!string} name The name of the module to create or retrieve.\n     * @param {!Array.<string>=} requires If specified then new module is being created. If\n     *        unspecified then the module is being retrieved for further configuration.\n     * @param {Function=} configFn Optional configuration function for the module. Same as\n     *        {@link angular.Module#config Module#config()}.\n     * @returns {angular.Module} new module with the {@link angular.Module} api.\n     */\n    return function module(name, requires, configFn) {\n\n      var info = {};\n\n      var assertNotHasOwnProperty = function(name, context) {\n        if (name === 'hasOwnProperty') {\n          throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);\n        }\n      };\n\n      assertNotHasOwnProperty(name, 'module');\n      if (requires && modules.hasOwnProperty(name)) {\n        modules[name] = null;\n      }\n      return ensure(modules, name, function() {\n        if (!requires) {\n          throw $injectorMinErr('nomod', 'Module \\'{0}\\' is not available! You either misspelled ' +\n             'the module name or forgot to load it. If registering a module ensure that you ' +\n             'specify the dependencies as the second argument.', name);\n        }\n\n        /** @type {!Array.<Array.<*>>} */\n        var invokeQueue = [];\n\n        /** @type {!Array.<Function>} */\n        var configBlocks = [];\n\n        /** @type {!Array.<Function>} */\n        var runBlocks = [];\n\n        var config = invokeLater('$injector', 'invoke', 'push', configBlocks);\n\n        /** @type {angular.Module} */\n        var moduleInstance = {\n          // Private state\n          _invokeQueue: invokeQueue,\n          _configBlocks: configBlocks,\n          _runBlocks: runBlocks,\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#info\n           * @module ng\n           *\n           * @param {Object=} info Information about the module\n           * @returns {Object|Module} The current info object for this module if called as a getter,\n           *                          or `this` if called as a setter.\n           *\n           * @description\n           * Read and write custom information about this module.\n           * For example you could put the version of the module in here.\n           *\n           * ```js\n           * angular.module('myModule', []).info({ version: '1.0.0' });\n           * ```\n           *\n           * The version could then be read back out by accessing the module elsewhere:\n           *\n           * ```\n           * var version = angular.module('myModule').info().version;\n           * ```\n           *\n           * You can also retrieve this information during runtime via the\n           * {@link $injector#modules `$injector.modules`} property:\n           *\n           * ```js\n           * var version = $injector.modules['myModule'].info().version;\n           * ```\n           */\n          info: function(value) {\n            if (isDefined(value)) {\n              if (!isObject(value)) throw ngMinErr('aobj', 'Argument \\'{0}\\' must be an object', 'value');\n              info = value;\n              return this;\n            }\n            return info;\n          },\n\n          /**\n           * @ngdoc property\n           * @name angular.Module#requires\n           * @module ng\n           *\n           * @description\n           * Holds the list of modules which the injector will load before the current module is\n           * loaded.\n           */\n          requires: requires,\n\n          /**\n           * @ngdoc property\n           * @name angular.Module#name\n           * @module ng\n           *\n           * @description\n           * Name of the module.\n           */\n          name: name,\n\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#provider\n           * @module ng\n           * @param {string} name service name\n           * @param {Function} providerType Construction function for creating new instance of the\n           *                                service.\n           * @description\n           * See {@link auto.$provide#provider $provide.provider()}.\n           */\n          provider: invokeLaterAndSetModuleName('$provide', 'provider'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#factory\n           * @module ng\n           * @param {string} name service name\n           * @param {Function} providerFunction Function for creating new instance of the service.\n           * @description\n           * See {@link auto.$provide#factory $provide.factory()}.\n           */\n          factory: invokeLaterAndSetModuleName('$provide', 'factory'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#service\n           * @module ng\n           * @param {string} name service name\n           * @param {Function} constructor A constructor function that will be instantiated.\n           * @description\n           * See {@link auto.$provide#service $provide.service()}.\n           */\n          service: invokeLaterAndSetModuleName('$provide', 'service'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#value\n           * @module ng\n           * @param {string} name service name\n           * @param {*} object Service instance object.\n           * @description\n           * See {@link auto.$provide#value $provide.value()}.\n           */\n          value: invokeLater('$provide', 'value'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#constant\n           * @module ng\n           * @param {string} name constant name\n           * @param {*} object Constant value.\n           * @description\n           * Because the constants are fixed, they get applied before other provide methods.\n           * See {@link auto.$provide#constant $provide.constant()}.\n           */\n          constant: invokeLater('$provide', 'constant', 'unshift'),\n\n           /**\n           * @ngdoc method\n           * @name angular.Module#decorator\n           * @module ng\n           * @param {string} name The name of the service to decorate.\n           * @param {Function} decorFn This function will be invoked when the service needs to be\n           *                           instantiated and should return the decorated service instance.\n           * @description\n           * See {@link auto.$provide#decorator $provide.decorator()}.\n           */\n          decorator: invokeLaterAndSetModuleName('$provide', 'decorator', configBlocks),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#animation\n           * @module ng\n           * @param {string} name animation name\n           * @param {Function} animationFactory Factory function for creating new instance of an\n           *                                    animation.\n           * @description\n           *\n           * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.\n           *\n           *\n           * Defines an animation hook that can be later used with\n           * {@link $animate $animate} service and directives that use this service.\n           *\n           * ```js\n           * module.animation('.animation-name', function($inject1, $inject2) {\n           *   return {\n           *     eventName : function(element, done) {\n           *       //code to run the animation\n           *       //once complete, then run done()\n           *       return function cancellationFunction(element) {\n           *         //code to cancel the animation\n           *       }\n           *     }\n           *   }\n           * })\n           * ```\n           *\n           * See {@link ng.$animateProvider#register $animateProvider.register()} and\n           * {@link ngAnimate ngAnimate module} for more information.\n           */\n          animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#filter\n           * @module ng\n           * @param {string} name Filter name - this must be a valid angular expression identifier\n           * @param {Function} filterFactory Factory function for creating new instance of filter.\n           * @description\n           * See {@link ng.$filterProvider#register $filterProvider.register()}.\n           *\n           * <div class=\"alert alert-warning\">\n           * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.\n           * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace\n           * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores\n           * (`myapp_subsection_filterx`).\n           * </div>\n           */\n          filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#controller\n           * @module ng\n           * @param {string|Object} name Controller name, or an object map of controllers where the\n           *    keys are the names and the values are the constructors.\n           * @param {Function} constructor Controller constructor function.\n           * @description\n           * See {@link ng.$controllerProvider#register $controllerProvider.register()}.\n           */\n          controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#directive\n           * @module ng\n           * @param {string|Object} name Directive name, or an object map of directives where the\n           *    keys are the names and the values are the factories.\n           * @param {Function} directiveFactory Factory function for creating new instance of\n           * directives.\n           * @description\n           * See {@link ng.$compileProvider#directive $compileProvider.directive()}.\n           */\n          directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#component\n           * @module ng\n           * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp)\n           * @param {Object} options Component definition object (a simplified\n           *    {@link ng.$compile#directive-definition-object directive definition object})\n           *\n           * @description\n           * See {@link ng.$compileProvider#component $compileProvider.component()}.\n           */\n          component: invokeLaterAndSetModuleName('$compileProvider', 'component'),\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#config\n           * @module ng\n           * @param {Function} configFn Execute this function on module load. Useful for service\n           *    configuration.\n           * @description\n           * Use this method to register work which needs to be performed on module loading.\n           * For more about how to configure services, see\n           * {@link providers#provider-recipe Provider Recipe}.\n           */\n          config: config,\n\n          /**\n           * @ngdoc method\n           * @name angular.Module#run\n           * @module ng\n           * @param {Function} initializationFn Execute this function after injector creation.\n           *    Useful for application initialization.\n           * @description\n           * Use this method to register work which should be performed when the injector is done\n           * loading all modules.\n           */\n          run: function(block) {\n            runBlocks.push(block);\n            return this;\n          }\n        };\n\n        if (configFn) {\n          config(configFn);\n        }\n\n        return moduleInstance;\n\n        /**\n         * @param {string} provider\n         * @param {string} method\n         * @param {String=} insertMethod\n         * @returns {angular.Module}\n         */\n        function invokeLater(provider, method, insertMethod, queue) {\n          if (!queue) queue = invokeQueue;\n          return function() {\n            queue[insertMethod || 'push']([provider, method, arguments]);\n            return moduleInstance;\n          };\n        }\n\n        /**\n         * @param {string} provider\n         * @param {string} method\n         * @returns {angular.Module}\n         */\n        function invokeLaterAndSetModuleName(provider, method, queue) {\n          if (!queue) queue = invokeQueue;\n          return function(recipeName, factoryFunction) {\n            if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;\n            queue.push([provider, method, arguments]);\n            return moduleInstance;\n          };\n        }\n      });\n    };\n  });\n\n}\n\n/* global shallowCopy: true */\n\n/**\n * Creates a shallow copy of an object, an array or a primitive.\n *\n * Assumes that there are no proto properties for objects.\n */\nfunction shallowCopy(src, dst) {\n  if (isArray(src)) {\n    dst = dst || [];\n\n    for (var i = 0, ii = src.length; i < ii; i++) {\n      dst[i] = src[i];\n    }\n  } else if (isObject(src)) {\n    dst = dst || {};\n\n    for (var key in src) {\n      if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {\n        dst[key] = src[key];\n      }\n    }\n  }\n\n  return dst || src;\n}\n\n/* global toDebugString: true */\n\nfunction serializeObject(obj, maxDepth) {\n  var seen = [];\n\n  // There is no direct way to stringify object until reaching a specific depth\n  // and a very deep object can cause a performance issue, so we copy the object\n  // based on this specific depth and then stringify it.\n  if (isValidObjectMaxDepth(maxDepth)) {\n    obj = copy(obj, null, maxDepth);\n  }\n  return JSON.stringify(obj, function(key, val) {\n    val = toJsonReplacer(key, val);\n    if (isObject(val)) {\n\n      if (seen.indexOf(val) >= 0) return '...';\n\n      seen.push(val);\n    }\n    return val;\n  });\n}\n\nfunction toDebugString(obj, maxDepth) {\n  if (typeof obj === 'function') {\n    return obj.toString().replace(/ \\{[\\s\\S]*$/, '');\n  } else if (isUndefined(obj)) {\n    return 'undefined';\n  } else if (typeof obj !== 'string') {\n    return serializeObject(obj, maxDepth);\n  }\n  return obj;\n}\n\n/* global angularModule: true,\n  version: true,\n\n  $CompileProvider,\n\n  htmlAnchorDirective,\n  inputDirective,\n  inputDirective,\n  formDirective,\n  scriptDirective,\n  selectDirective,\n  optionDirective,\n  ngBindDirective,\n  ngBindHtmlDirective,\n  ngBindTemplateDirective,\n  ngClassDirective,\n  ngClassEvenDirective,\n  ngClassOddDirective,\n  ngCloakDirective,\n  ngControllerDirective,\n  ngFormDirective,\n  ngHideDirective,\n  ngIfDirective,\n  ngIncludeDirective,\n  ngIncludeFillContentDirective,\n  ngInitDirective,\n  ngNonBindableDirective,\n  ngPluralizeDirective,\n  ngRepeatDirective,\n  ngShowDirective,\n  ngStyleDirective,\n  ngSwitchDirective,\n  ngSwitchWhenDirective,\n  ngSwitchDefaultDirective,\n  ngOptionsDirective,\n  ngTranscludeDirective,\n  ngModelDirective,\n  ngListDirective,\n  ngChangeDirective,\n  patternDirective,\n  patternDirective,\n  requiredDirective,\n  requiredDirective,\n  minlengthDirective,\n  minlengthDirective,\n  maxlengthDirective,\n  maxlengthDirective,\n  ngValueDirective,\n  ngModelOptionsDirective,\n  ngAttributeAliasDirectives,\n  ngEventDirectives,\n\n  $AnchorScrollProvider,\n  $AnimateProvider,\n  $CoreAnimateCssProvider,\n  $$CoreAnimateJsProvider,\n  $$CoreAnimateQueueProvider,\n  $$AnimateRunnerFactoryProvider,\n  $$AnimateAsyncRunFactoryProvider,\n  $BrowserProvider,\n  $CacheFactoryProvider,\n  $ControllerProvider,\n  $DateProvider,\n  $DocumentProvider,\n  $$IsDocumentHiddenProvider,\n  $ExceptionHandlerProvider,\n  $FilterProvider,\n  $$ForceReflowProvider,\n  $InterpolateProvider,\n  $IntervalProvider,\n  $HttpProvider,\n  $HttpParamSerializerProvider,\n  $HttpParamSerializerJQLikeProvider,\n  $HttpBackendProvider,\n  $xhrFactoryProvider,\n  $jsonpCallbacksProvider,\n  $LocationProvider,\n  $LogProvider,\n  $$MapProvider,\n  $ParseProvider,\n  $RootScopeProvider,\n  $QProvider,\n  $$QProvider,\n  $$SanitizeUriProvider,\n  $SceProvider,\n  $SceDelegateProvider,\n  $SnifferProvider,\n  $TemplateCacheProvider,\n  $TemplateRequestProvider,\n  $$TestabilityProvider,\n  $TimeoutProvider,\n  $$RAFProvider,\n  $WindowProvider,\n  $$jqLiteProvider,\n  $$CookieReaderProvider\n*/\n\n\n/**\n * @ngdoc object\n * @name angular.version\n * @module ng\n * @description\n * An object that contains information about the current AngularJS version.\n *\n * This object has the following properties:\n *\n * - `full` – `{string}` – Full version string, such as \"0.9.18\".\n * - `major` – `{number}` – Major version number, such as \"0\".\n * - `minor` – `{number}` – Minor version number, such as \"9\".\n * - `dot` – `{number}` – Dot version number, such as \"18\".\n * - `codeName` – `{string}` – Code name of the release, such as \"jiggling-armfat\".\n */\nvar version = {\n  // These placeholder strings will be replaced by grunt's `build` task.\n  // They need to be double- or single-quoted.\n  full: '1.6.3',\n  major: 1,\n  minor: 6,\n  dot: 3,\n  codeName: 'scriptalicious-bootstrapping'\n};\n\n\nfunction publishExternalAPI(angular) {\n  extend(angular, {\n    'errorHandlingConfig': errorHandlingConfig,\n    'bootstrap': bootstrap,\n    'copy': copy,\n    'extend': extend,\n    'merge': merge,\n    'equals': equals,\n    'element': jqLite,\n    'forEach': forEach,\n    'injector': createInjector,\n    'noop': noop,\n    'bind': bind,\n    'toJson': toJson,\n    'fromJson': fromJson,\n    'identity': identity,\n    'isUndefined': isUndefined,\n    'isDefined': isDefined,\n    'isString': isString,\n    'isFunction': isFunction,\n    'isObject': isObject,\n    'isNumber': isNumber,\n    'isElement': isElement,\n    'isArray': isArray,\n    'version': version,\n    'isDate': isDate,\n    'lowercase': lowercase,\n    'uppercase': uppercase,\n    'callbacks': {$$counter: 0},\n    'getTestability': getTestability,\n    'reloadWithDebugInfo': reloadWithDebugInfo,\n    '$$minErr': minErr,\n    '$$csp': csp,\n    '$$encodeUriSegment': encodeUriSegment,\n    '$$encodeUriQuery': encodeUriQuery,\n    '$$stringify': stringify\n  });\n\n  angularModule = setupModuleLoader(window);\n\n  angularModule('ng', ['ngLocale'], ['$provide',\n    function ngModule($provide) {\n      // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.\n      $provide.provider({\n        $$sanitizeUri: $$SanitizeUriProvider\n      });\n      $provide.provider('$compile', $CompileProvider).\n        directive({\n            a: htmlAnchorDirective,\n            input: inputDirective,\n            textarea: inputDirective,\n            form: formDirective,\n            script: scriptDirective,\n            select: selectDirective,\n            option: optionDirective,\n            ngBind: ngBindDirective,\n            ngBindHtml: ngBindHtmlDirective,\n            ngBindTemplate: ngBindTemplateDirective,\n            ngClass: ngClassDirective,\n            ngClassEven: ngClassEvenDirective,\n            ngClassOdd: ngClassOddDirective,\n            ngCloak: ngCloakDirective,\n            ngController: ngControllerDirective,\n            ngForm: ngFormDirective,\n            ngHide: ngHideDirective,\n            ngIf: ngIfDirective,\n            ngInclude: ngIncludeDirective,\n            ngInit: ngInitDirective,\n            ngNonBindable: ngNonBindableDirective,\n            ngPluralize: ngPluralizeDirective,\n            ngRepeat: ngRepeatDirective,\n            ngShow: ngShowDirective,\n            ngStyle: ngStyleDirective,\n            ngSwitch: ngSwitchDirective,\n            ngSwitchWhen: ngSwitchWhenDirective,\n            ngSwitchDefault: ngSwitchDefaultDirective,\n            ngOptions: ngOptionsDirective,\n            ngTransclude: ngTranscludeDirective,\n            ngModel: ngModelDirective,\n            ngList: ngListDirective,\n            ngChange: ngChangeDirective,\n            pattern: patternDirective,\n            ngPattern: patternDirective,\n            required: requiredDirective,\n            ngRequired: requiredDirective,\n            minlength: minlengthDirective,\n            ngMinlength: minlengthDirective,\n            maxlength: maxlengthDirective,\n            ngMaxlength: maxlengthDirective,\n            ngValue: ngValueDirective,\n            ngModelOptions: ngModelOptionsDirective\n        }).\n        directive({\n          ngInclude: ngIncludeFillContentDirective\n        }).\n        directive(ngAttributeAliasDirectives).\n        directive(ngEventDirectives);\n      $provide.provider({\n        $anchorScroll: $AnchorScrollProvider,\n        $animate: $AnimateProvider,\n        $animateCss: $CoreAnimateCssProvider,\n        $$animateJs: $$CoreAnimateJsProvider,\n        $$animateQueue: $$CoreAnimateQueueProvider,\n        $$AnimateRunner: $$AnimateRunnerFactoryProvider,\n        $$animateAsyncRun: $$AnimateAsyncRunFactoryProvider,\n        $browser: $BrowserProvider,\n        $cacheFactory: $CacheFactoryProvider,\n        $controller: $ControllerProvider,\n        $document: $DocumentProvider,\n        $$isDocumentHidden: $$IsDocumentHiddenProvider,\n        $exceptionHandler: $ExceptionHandlerProvider,\n        $filter: $FilterProvider,\n        $$forceReflow: $$ForceReflowProvider,\n        $interpolate: $InterpolateProvider,\n        $interval: $IntervalProvider,\n        $http: $HttpProvider,\n        $httpParamSerializer: $HttpParamSerializerProvider,\n        $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,\n        $httpBackend: $HttpBackendProvider,\n        $xhrFactory: $xhrFactoryProvider,\n        $jsonpCallbacks: $jsonpCallbacksProvider,\n        $location: $LocationProvider,\n        $log: $LogProvider,\n        $parse: $ParseProvider,\n        $rootScope: $RootScopeProvider,\n        $q: $QProvider,\n        $$q: $$QProvider,\n        $sce: $SceProvider,\n        $sceDelegate: $SceDelegateProvider,\n        $sniffer: $SnifferProvider,\n        $templateCache: $TemplateCacheProvider,\n        $templateRequest: $TemplateRequestProvider,\n        $$testability: $$TestabilityProvider,\n        $timeout: $TimeoutProvider,\n        $window: $WindowProvider,\n        $$rAF: $$RAFProvider,\n        $$jqLite: $$jqLiteProvider,\n        $$Map: $$MapProvider,\n        $$cookieReader: $$CookieReaderProvider\n      });\n    }\n  ])\n  .info({ angularVersion: '1.6.3' });\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *     Any commits to this file should be reviewed with security in mind.  *\n *   Changes to this file can potentially create security vulnerabilities. *\n *          An approval from 2 Core members with history of modifying      *\n *                         this file is required.                          *\n *                                                                         *\n *  Does the change somehow allow for arbitrary javascript to be executed? *\n *    Or allows for someone to change the prototype of built-in objects?   *\n *     Or gives undesired access to variables likes document or window?    *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/* global\n  JQLitePrototype: true,\n  BOOLEAN_ATTR: true,\n  ALIASED_ATTR: true\n*/\n\n//////////////////////////////////\n//JQLite\n//////////////////////////////////\n\n/**\n * @ngdoc function\n * @name angular.element\n * @module ng\n * @kind function\n *\n * @description\n * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.\n *\n * If jQuery is available, `angular.element` is an alias for the\n * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element`\n * delegates to Angular's built-in subset of jQuery, called \"jQuery lite\" or **jqLite**.\n *\n * jqLite is a tiny, API-compatible subset of jQuery that allows\n * Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most\n * commonly needed functionality with the goal of having a very small footprint.\n *\n * To use `jQuery`, simply ensure it is loaded before the `angular.js` file. You can also use the\n * {@link ngJq `ngJq`} directive to specify that jqlite should be used over jQuery, or to use a\n * specific version of jQuery if multiple versions exist on the page.\n *\n * <div class=\"alert alert-info\">**Note:** All element references in Angular are always wrapped with jQuery or\n * jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.</div>\n *\n * <div class=\"alert alert-warning\">**Note:** Keep in mind that this function will not find elements\n * by tag name / CSS selector. For lookups by tag name, try instead `angular.element(document).find(...)`\n * or `$document.find()`, or use the standard DOM APIs, e.g. `document.querySelectorAll()`.</div>\n *\n * ## Angular's jqLite\n * jqLite provides only the following jQuery methods:\n *\n * - [`addClass()`](http://api.jquery.com/addClass/) - Does not support a function as first argument\n * - [`after()`](http://api.jquery.com/after/)\n * - [`append()`](http://api.jquery.com/append/)\n * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters\n * - [`bind()`](http://api.jquery.com/bind/) (_deprecated_, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData\n * - [`children()`](http://api.jquery.com/children/) - Does not support selectors\n * - [`clone()`](http://api.jquery.com/clone/)\n * - [`contents()`](http://api.jquery.com/contents/)\n * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`.\n *   As a setter, does not convert numbers to strings or append 'px', and also does not have automatic property prefixing.\n * - [`data()`](http://api.jquery.com/data/)\n * - [`detach()`](http://api.jquery.com/detach/)\n * - [`empty()`](http://api.jquery.com/empty/)\n * - [`eq()`](http://api.jquery.com/eq/)\n * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name\n * - [`hasClass()`](http://api.jquery.com/hasClass/)\n * - [`html()`](http://api.jquery.com/html/)\n * - [`next()`](http://api.jquery.com/next/) - Does not support selectors\n * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData\n * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter\n * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors\n * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors\n * - [`prepend()`](http://api.jquery.com/prepend/)\n * - [`prop()`](http://api.jquery.com/prop/)\n * - [`ready()`](http://api.jquery.com/ready/) (_deprecated_, use `angular.element(callback)` instead of `angular.element(document).ready(callback)`)\n * - [`remove()`](http://api.jquery.com/remove/)\n * - [`removeAttr()`](http://api.jquery.com/removeAttr/) - Does not support multiple attributes\n * - [`removeClass()`](http://api.jquery.com/removeClass/) - Does not support a function as first argument\n * - [`removeData()`](http://api.jquery.com/removeData/)\n * - [`replaceWith()`](http://api.jquery.com/replaceWith/)\n * - [`text()`](http://api.jquery.com/text/)\n * - [`toggleClass()`](http://api.jquery.com/toggleClass/) - Does not support a function as first argument\n * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers\n * - [`unbind()`](http://api.jquery.com/unbind/) (_deprecated_, use [`off()`](http://api.jquery.com/off/)) - Does not support namespaces or event object as parameter\n * - [`val()`](http://api.jquery.com/val/)\n * - [`wrap()`](http://api.jquery.com/wrap/)\n *\n * ## jQuery/jqLite Extras\n * Angular also provides the following additional methods and events to both jQuery and jqLite:\n *\n * ### Events\n * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event\n *    on all DOM nodes being removed.  This can be used to clean up any 3rd party bindings to the DOM\n *    element before it is removed.\n *\n * ### Methods\n * - `controller(name)` - retrieves the controller of the current element or its parent. By default\n *   retrieves controller associated with the `ngController` directive. If `name` is provided as\n *   camelCase directive name, then the controller for this directive will be retrieved (e.g.\n *   `'ngModel'`).\n * - `injector()` - retrieves the injector of the current element or its parent.\n * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current\n *   element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to\n *   be enabled.\n * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the\n *   current element. This getter should be used only on elements that contain a directive which starts a new isolate\n *   scope. Calling `scope()` on this element always returns the original non-isolate scope.\n *   Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.\n * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top\n *   parent element is reached.\n *\n * @knownIssue You cannot spy on `angular.element` if you are using Jasmine version 1.x. See\n * https://github.com/angular/angular.js/issues/14251 for more information.\n *\n * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.\n * @returns {Object} jQuery object.\n */\n\nJQLite.expando = 'ng339';\n\nvar jqCache = JQLite.cache = {},\n    jqId = 1;\n\n/*\n * !!! This is an undocumented \"private\" function !!!\n */\nJQLite._data = function(node) {\n  //jQuery always returns an object on cache miss\n  return this.cache[node[this.expando]] || {};\n};\n\nfunction jqNextId() { return ++jqId; }\n\n\nvar DASH_LOWERCASE_REGEXP = /-([a-z])/g;\nvar MS_HACK_REGEXP = /^-ms-/;\nvar MOUSE_EVENT_MAP = { mouseleave: 'mouseout', mouseenter: 'mouseover' };\nvar jqLiteMinErr = minErr('jqLite');\n\n/**\n * Converts kebab-case to camelCase.\n * There is also a special case for the ms prefix starting with a lowercase letter.\n * @param name Name to normalize\n */\nfunction cssKebabToCamel(name) {\n    return kebabToCamel(name.replace(MS_HACK_REGEXP, 'ms-'));\n}\n\nfunction fnCamelCaseReplace(all, letter) {\n  return letter.toUpperCase();\n}\n\n/**\n * Converts kebab-case to camelCase.\n * @param name Name to normalize\n */\nfunction kebabToCamel(name) {\n  return name\n    .replace(DASH_LOWERCASE_REGEXP, fnCamelCaseReplace);\n}\n\nvar SINGLE_TAG_REGEXP = /^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/;\nvar HTML_REGEXP = /<|&#?\\w+;/;\nvar TAG_NAME_REGEXP = /<([\\w:-]+)/;\nvar XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi;\n\nvar wrapMap = {\n  'option': [1, '<select multiple=\"multiple\">', '</select>'],\n\n  'thead': [1, '<table>', '</table>'],\n  'col': [2, '<table><colgroup>', '</colgroup></table>'],\n  'tr': [2, '<table><tbody>', '</tbody></table>'],\n  'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],\n  '_default': [0, '', '']\n};\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction jqLiteIsTextNode(html) {\n  return !HTML_REGEXP.test(html);\n}\n\nfunction jqLiteAcceptsData(node) {\n  // The window object can accept data but has no nodeType\n  // Otherwise we are only interested in elements (1) and documents (9)\n  var nodeType = node.nodeType;\n  return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;\n}\n\nfunction jqLiteHasData(node) {\n  for (var key in jqCache[node.ng339]) {\n    return true;\n  }\n  return false;\n}\n\nfunction jqLiteCleanData(nodes) {\n  for (var i = 0, ii = nodes.length; i < ii; i++) {\n    jqLiteRemoveData(nodes[i]);\n  }\n}\n\nfunction jqLiteBuildFragment(html, context) {\n  var tmp, tag, wrap,\n      fragment = context.createDocumentFragment(),\n      nodes = [], i;\n\n  if (jqLiteIsTextNode(html)) {\n    // Convert non-html into a text node\n    nodes.push(context.createTextNode(html));\n  } else {\n    // Convert html into DOM nodes\n    tmp = fragment.appendChild(context.createElement('div'));\n    tag = (TAG_NAME_REGEXP.exec(html) || ['', ''])[1].toLowerCase();\n    wrap = wrapMap[tag] || wrapMap._default;\n    tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, '<$1></$2>') + wrap[2];\n\n    // Descend through wrappers to the right content\n    i = wrap[0];\n    while (i--) {\n      tmp = tmp.lastChild;\n    }\n\n    nodes = concat(nodes, tmp.childNodes);\n\n    tmp = fragment.firstChild;\n    tmp.textContent = '';\n  }\n\n  // Remove wrapper from fragment\n  fragment.textContent = '';\n  fragment.innerHTML = ''; // Clear inner HTML\n  forEach(nodes, function(node) {\n    fragment.appendChild(node);\n  });\n\n  return fragment;\n}\n\nfunction jqLiteParseHTML(html, context) {\n  context = context || window.document;\n  var parsed;\n\n  if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {\n    return [context.createElement(parsed[1])];\n  }\n\n  if ((parsed = jqLiteBuildFragment(html, context))) {\n    return parsed.childNodes;\n  }\n\n  return [];\n}\n\nfunction jqLiteWrapNode(node, wrapper) {\n  var parent = node.parentNode;\n\n  if (parent) {\n    parent.replaceChild(wrapper, node);\n  }\n\n  wrapper.appendChild(node);\n}\n\n\n// IE9-11 has no method \"contains\" in SVG element and in Node.prototype. Bug #10259.\nvar jqLiteContains = window.Node.prototype.contains || /** @this */ function(arg) {\n  // eslint-disable-next-line no-bitwise\n  return !!(this.compareDocumentPosition(arg) & 16);\n};\n\n/////////////////////////////////////////////\nfunction JQLite(element) {\n  if (element instanceof JQLite) {\n    return element;\n  }\n\n  var argIsString;\n\n  if (isString(element)) {\n    element = trim(element);\n    argIsString = true;\n  }\n  if (!(this instanceof JQLite)) {\n    if (argIsString && element.charAt(0) !== '<') {\n      throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');\n    }\n    return new JQLite(element);\n  }\n\n  if (argIsString) {\n    jqLiteAddNodes(this, jqLiteParseHTML(element));\n  } else if (isFunction(element)) {\n    jqLiteReady(element);\n  } else {\n    jqLiteAddNodes(this, element);\n  }\n}\n\nfunction jqLiteClone(element) {\n  return element.cloneNode(true);\n}\n\nfunction jqLiteDealoc(element, onlyDescendants) {\n  if (!onlyDescendants) jqLiteRemoveData(element);\n\n  if (element.querySelectorAll) {\n    var descendants = element.querySelectorAll('*');\n    for (var i = 0, l = descendants.length; i < l; i++) {\n      jqLiteRemoveData(descendants[i]);\n    }\n  }\n}\n\nfunction jqLiteOff(element, type, fn, unsupported) {\n  if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');\n\n  var expandoStore = jqLiteExpandoStore(element);\n  var events = expandoStore && expandoStore.events;\n  var handle = expandoStore && expandoStore.handle;\n\n  if (!handle) return; //no listeners registered\n\n  if (!type) {\n    for (type in events) {\n      if (type !== '$destroy') {\n        element.removeEventListener(type, handle);\n      }\n      delete events[type];\n    }\n  } else {\n\n    var removeHandler = function(type) {\n      var listenerFns = events[type];\n      if (isDefined(fn)) {\n        arrayRemove(listenerFns || [], fn);\n      }\n      if (!(isDefined(fn) && listenerFns && listenerFns.length > 0)) {\n        element.removeEventListener(type, handle);\n        delete events[type];\n      }\n    };\n\n    forEach(type.split(' '), function(type) {\n      removeHandler(type);\n      if (MOUSE_EVENT_MAP[type]) {\n        removeHandler(MOUSE_EVENT_MAP[type]);\n      }\n    });\n  }\n}\n\nfunction jqLiteRemoveData(element, name) {\n  var expandoId = element.ng339;\n  var expandoStore = expandoId && jqCache[expandoId];\n\n  if (expandoStore) {\n    if (name) {\n      delete expandoStore.data[name];\n      return;\n    }\n\n    if (expandoStore.handle) {\n      if (expandoStore.events.$destroy) {\n        expandoStore.handle({}, '$destroy');\n      }\n      jqLiteOff(element);\n    }\n    delete jqCache[expandoId];\n    element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it\n  }\n}\n\n\nfunction jqLiteExpandoStore(element, createIfNecessary) {\n  var expandoId = element.ng339,\n      expandoStore = expandoId && jqCache[expandoId];\n\n  if (createIfNecessary && !expandoStore) {\n    element.ng339 = expandoId = jqNextId();\n    expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined};\n  }\n\n  return expandoStore;\n}\n\n\nfunction jqLiteData(element, key, value) {\n  if (jqLiteAcceptsData(element)) {\n    var prop;\n\n    var isSimpleSetter = isDefined(value);\n    var isSimpleGetter = !isSimpleSetter && key && !isObject(key);\n    var massGetter = !key;\n    var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);\n    var data = expandoStore && expandoStore.data;\n\n    if (isSimpleSetter) { // data('key', value)\n      data[kebabToCamel(key)] = value;\n    } else {\n      if (massGetter) {  // data()\n        return data;\n      } else {\n        if (isSimpleGetter) { // data('key')\n          // don't force creation of expandoStore if it doesn't exist yet\n          return data && data[kebabToCamel(key)];\n        } else { // mass-setter: data({key1: val1, key2: val2})\n          for (prop in key) {\n            data[kebabToCamel(prop)] = key[prop];\n          }\n        }\n      }\n    }\n  }\n}\n\nfunction jqLiteHasClass(element, selector) {\n  if (!element.getAttribute) return false;\n  return ((' ' + (element.getAttribute('class') || '') + ' ').replace(/[\\n\\t]/g, ' ').\n      indexOf(' ' + selector + ' ') > -1);\n}\n\nfunction jqLiteRemoveClass(element, cssClasses) {\n  if (cssClasses && element.setAttribute) {\n    forEach(cssClasses.split(' '), function(cssClass) {\n      element.setAttribute('class', trim(\n          (' ' + (element.getAttribute('class') || '') + ' ')\n          .replace(/[\\n\\t]/g, ' ')\n          .replace(' ' + trim(cssClass) + ' ', ' '))\n      );\n    });\n  }\n}\n\nfunction jqLiteAddClass(element, cssClasses) {\n  if (cssClasses && element.setAttribute) {\n    var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')\n                            .replace(/[\\n\\t]/g, ' ');\n\n    forEach(cssClasses.split(' '), function(cssClass) {\n      cssClass = trim(cssClass);\n      if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {\n        existingClasses += cssClass + ' ';\n      }\n    });\n\n    element.setAttribute('class', trim(existingClasses));\n  }\n}\n\n\nfunction jqLiteAddNodes(root, elements) {\n  // THIS CODE IS VERY HOT. Don't make changes without benchmarking.\n\n  if (elements) {\n\n    // if a Node (the most common case)\n    if (elements.nodeType) {\n      root[root.length++] = elements;\n    } else {\n      var length = elements.length;\n\n      // if an Array or NodeList and not a Window\n      if (typeof length === 'number' && elements.window !== elements) {\n        if (length) {\n          for (var i = 0; i < length; i++) {\n            root[root.length++] = elements[i];\n          }\n        }\n      } else {\n        root[root.length++] = elements;\n      }\n    }\n  }\n}\n\n\nfunction jqLiteController(element, name) {\n  return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');\n}\n\nfunction jqLiteInheritedData(element, name, value) {\n  // if element is the document object work with the html element instead\n  // this makes $(document).scope() possible\n  if (element.nodeType === NODE_TYPE_DOCUMENT) {\n    element = element.documentElement;\n  }\n  var names = isArray(name) ? name : [name];\n\n  while (element) {\n    for (var i = 0, ii = names.length; i < ii; i++) {\n      if (isDefined(value = jqLite.data(element, names[i]))) return value;\n    }\n\n    // If dealing with a document fragment node with a host element, and no parent, use the host\n    // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM\n    // to lookup parent controllers.\n    element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host);\n  }\n}\n\nfunction jqLiteEmpty(element) {\n  jqLiteDealoc(element, true);\n  while (element.firstChild) {\n    element.removeChild(element.firstChild);\n  }\n}\n\nfunction jqLiteRemove(element, keepData) {\n  if (!keepData) jqLiteDealoc(element);\n  var parent = element.parentNode;\n  if (parent) parent.removeChild(element);\n}\n\n\nfunction jqLiteDocumentLoaded(action, win) {\n  win = win || window;\n  if (win.document.readyState === 'complete') {\n    // Force the action to be run async for consistent behavior\n    // from the action's point of view\n    // i.e. it will definitely not be in a $apply\n    win.setTimeout(action);\n  } else {\n    // No need to unbind this handler as load is only ever called once\n    jqLite(win).on('load', action);\n  }\n}\n\nfunction jqLiteReady(fn) {\n  function trigger() {\n    window.document.removeEventListener('DOMContentLoaded', trigger);\n    window.removeEventListener('load', trigger);\n    fn();\n  }\n\n  // check if document is already loaded\n  if (window.document.readyState === 'complete') {\n    window.setTimeout(fn);\n  } else {\n    // We can not use jqLite since we are not done loading and jQuery could be loaded later.\n\n    // Works for modern browsers and IE9\n    window.document.addEventListener('DOMContentLoaded', trigger);\n\n    // Fallback to window.onload for others\n    window.addEventListener('load', trigger);\n  }\n}\n\n//////////////////////////////////////////\n// Functions which are declared directly.\n//////////////////////////////////////////\nvar JQLitePrototype = JQLite.prototype = {\n  ready: jqLiteReady,\n  toString: function() {\n    var value = [];\n    forEach(this, function(e) { value.push('' + e);});\n    return '[' + value.join(', ') + ']';\n  },\n\n  eq: function(index) {\n      return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]);\n  },\n\n  length: 0,\n  push: push,\n  sort: [].sort,\n  splice: [].splice\n};\n\n//////////////////////////////////////////\n// Functions iterating getter/setters.\n// these functions return self on setter and\n// value on get.\n//////////////////////////////////////////\nvar BOOLEAN_ATTR = {};\nforEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {\n  BOOLEAN_ATTR[lowercase(value)] = value;\n});\nvar BOOLEAN_ELEMENTS = {};\nforEach('input,select,option,textarea,button,form,details'.split(','), function(value) {\n  BOOLEAN_ELEMENTS[value] = true;\n});\nvar ALIASED_ATTR = {\n  'ngMinlength': 'minlength',\n  'ngMaxlength': 'maxlength',\n  'ngMin': 'min',\n  'ngMax': 'max',\n  'ngPattern': 'pattern',\n  'ngStep': 'step'\n};\n\nfunction getBooleanAttrName(element, name) {\n  // check dom last since we will most likely fail on name\n  var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];\n\n  // booleanAttr is here twice to minimize DOM access\n  return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;\n}\n\nfunction getAliasedAttrName(name) {\n  return ALIASED_ATTR[name];\n}\n\nforEach({\n  data: jqLiteData,\n  removeData: jqLiteRemoveData,\n  hasData: jqLiteHasData,\n  cleanData: jqLiteCleanData\n}, function(fn, name) {\n  JQLite[name] = fn;\n});\n\nforEach({\n  data: jqLiteData,\n  inheritedData: jqLiteInheritedData,\n\n  scope: function(element) {\n    // Can't use jqLiteData here directly so we stay compatible with jQuery!\n    return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);\n  },\n\n  isolateScope: function(element) {\n    // Can't use jqLiteData here directly so we stay compatible with jQuery!\n    return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');\n  },\n\n  controller: jqLiteController,\n\n  injector: function(element) {\n    return jqLiteInheritedData(element, '$injector');\n  },\n\n  removeAttr: function(element, name) {\n    element.removeAttribute(name);\n  },\n\n  hasClass: jqLiteHasClass,\n\n  css: function(element, name, value) {\n    name = cssKebabToCamel(name);\n\n    if (isDefined(value)) {\n      element.style[name] = value;\n    } else {\n      return element.style[name];\n    }\n  },\n\n  attr: function(element, name, value) {\n    var ret;\n    var nodeType = element.nodeType;\n    if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT ||\n      !element.getAttribute) {\n      return;\n    }\n\n    var lowercasedName = lowercase(name);\n    var isBooleanAttr = BOOLEAN_ATTR[lowercasedName];\n\n    if (isDefined(value)) {\n      // setter\n\n      if (value === null || (value === false && isBooleanAttr)) {\n        element.removeAttribute(name);\n      } else {\n        element.setAttribute(name, isBooleanAttr ? lowercasedName : value);\n      }\n    } else {\n      // getter\n\n      ret = element.getAttribute(name);\n\n      if (isBooleanAttr && ret !== null) {\n        ret = lowercasedName;\n      }\n      // Normalize non-existing attributes to undefined (as jQuery).\n      return ret === null ? undefined : ret;\n    }\n  },\n\n  prop: function(element, name, value) {\n    if (isDefined(value)) {\n      element[name] = value;\n    } else {\n      return element[name];\n    }\n  },\n\n  text: (function() {\n    getText.$dv = '';\n    return getText;\n\n    function getText(element, value) {\n      if (isUndefined(value)) {\n        var nodeType = element.nodeType;\n        return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : '';\n      }\n      element.textContent = value;\n    }\n  })(),\n\n  val: function(element, value) {\n    if (isUndefined(value)) {\n      if (element.multiple && nodeName_(element) === 'select') {\n        var result = [];\n        forEach(element.options, function(option) {\n          if (option.selected) {\n            result.push(option.value || option.text);\n          }\n        });\n        return result;\n      }\n      return element.value;\n    }\n    element.value = value;\n  },\n\n  html: function(element, value) {\n    if (isUndefined(value)) {\n      return element.innerHTML;\n    }\n    jqLiteDealoc(element, true);\n    element.innerHTML = value;\n  },\n\n  empty: jqLiteEmpty\n}, function(fn, name) {\n  /**\n   * Properties: writes return selection, reads return first value\n   */\n  JQLite.prototype[name] = function(arg1, arg2) {\n    var i, key;\n    var nodeCount = this.length;\n\n    // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it\n    // in a way that survives minification.\n    // jqLiteEmpty takes no arguments but is a setter.\n    if (fn !== jqLiteEmpty &&\n        (isUndefined((fn.length === 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2))) {\n      if (isObject(arg1)) {\n\n        // we are a write, but the object properties are the key/values\n        for (i = 0; i < nodeCount; i++) {\n          if (fn === jqLiteData) {\n            // data() takes the whole object in jQuery\n            fn(this[i], arg1);\n          } else {\n            for (key in arg1) {\n              fn(this[i], key, arg1[key]);\n            }\n          }\n        }\n        // return self for chaining\n        return this;\n      } else {\n        // we are a read, so read the first child.\n        // TODO: do we still need this?\n        var value = fn.$dv;\n        // Only if we have $dv do we iterate over all, otherwise it is just the first element.\n        var jj = (isUndefined(value)) ? Math.min(nodeCount, 1) : nodeCount;\n        for (var j = 0; j < jj; j++) {\n          var nodeValue = fn(this[j], arg1, arg2);\n          value = value ? value + nodeValue : nodeValue;\n        }\n        return value;\n      }\n    } else {\n      // we are a write, so apply to all children\n      for (i = 0; i < nodeCount; i++) {\n        fn(this[i], arg1, arg2);\n      }\n      // return self for chaining\n      return this;\n    }\n  };\n});\n\nfunction createEventHandler(element, events) {\n  var eventHandler = function(event, type) {\n    // jQuery specific api\n    event.isDefaultPrevented = function() {\n      return event.defaultPrevented;\n    };\n\n    var eventFns = events[type || event.type];\n    var eventFnsLength = eventFns ? eventFns.length : 0;\n\n    if (!eventFnsLength) return;\n\n    if (isUndefined(event.immediatePropagationStopped)) {\n      var originalStopImmediatePropagation = event.stopImmediatePropagation;\n      event.stopImmediatePropagation = function() {\n        event.immediatePropagationStopped = true;\n\n        if (event.stopPropagation) {\n          event.stopPropagation();\n        }\n\n        if (originalStopImmediatePropagation) {\n          originalStopImmediatePropagation.call(event);\n        }\n      };\n    }\n\n    event.isImmediatePropagationStopped = function() {\n      return event.immediatePropagationStopped === true;\n    };\n\n    // Some events have special handlers that wrap the real handler\n    var handlerWrapper = eventFns.specialHandlerWrapper || defaultHandlerWrapper;\n\n    // Copy event handlers in case event handlers array is modified during execution.\n    if ((eventFnsLength > 1)) {\n      eventFns = shallowCopy(eventFns);\n    }\n\n    for (var i = 0; i < eventFnsLength; i++) {\n      if (!event.isImmediatePropagationStopped()) {\n        handlerWrapper(element, event, eventFns[i]);\n      }\n    }\n  };\n\n  // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all\n  //       events on `element`\n  eventHandler.elem = element;\n  return eventHandler;\n}\n\nfunction defaultHandlerWrapper(element, event, handler) {\n  handler.call(element, event);\n}\n\nfunction specialMouseHandlerWrapper(target, event, handler) {\n  // Refer to jQuery's implementation of mouseenter & mouseleave\n  // Read about mouseenter and mouseleave:\n  // http://www.quirksmode.org/js/events_mouse.html#link8\n  var related = event.relatedTarget;\n  // For mousenter/leave call the handler if related is outside the target.\n  // NB: No relatedTarget if the mouse left/entered the browser window\n  if (!related || (related !== target && !jqLiteContains.call(target, related))) {\n    handler.call(target, event);\n  }\n}\n\n//////////////////////////////////////////\n// Functions iterating traversal.\n// These functions chain results into a single\n// selector.\n//////////////////////////////////////////\nforEach({\n  removeData: jqLiteRemoveData,\n\n  on: function jqLiteOn(element, type, fn, unsupported) {\n    if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');\n\n    // Do not add event handlers to non-elements because they will not be cleaned up.\n    if (!jqLiteAcceptsData(element)) {\n      return;\n    }\n\n    var expandoStore = jqLiteExpandoStore(element, true);\n    var events = expandoStore.events;\n    var handle = expandoStore.handle;\n\n    if (!handle) {\n      handle = expandoStore.handle = createEventHandler(element, events);\n    }\n\n    // http://jsperf.com/string-indexof-vs-split\n    var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type];\n    var i = types.length;\n\n    var addHandler = function(type, specialHandlerWrapper, noEventListener) {\n      var eventFns = events[type];\n\n      if (!eventFns) {\n        eventFns = events[type] = [];\n        eventFns.specialHandlerWrapper = specialHandlerWrapper;\n        if (type !== '$destroy' && !noEventListener) {\n          element.addEventListener(type, handle);\n        }\n      }\n\n      eventFns.push(fn);\n    };\n\n    while (i--) {\n      type = types[i];\n      if (MOUSE_EVENT_MAP[type]) {\n        addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper);\n        addHandler(type, undefined, true);\n      } else {\n        addHandler(type);\n      }\n    }\n  },\n\n  off: jqLiteOff,\n\n  one: function(element, type, fn) {\n    element = jqLite(element);\n\n    //add the listener twice so that when it is called\n    //you can remove the original function and still be\n    //able to call element.off(ev, fn) normally\n    element.on(type, function onFn() {\n      element.off(type, fn);\n      element.off(type, onFn);\n    });\n    element.on(type, fn);\n  },\n\n  replaceWith: function(element, replaceNode) {\n    var index, parent = element.parentNode;\n    jqLiteDealoc(element);\n    forEach(new JQLite(replaceNode), function(node) {\n      if (index) {\n        parent.insertBefore(node, index.nextSibling);\n      } else {\n        parent.replaceChild(node, element);\n      }\n      index = node;\n    });\n  },\n\n  children: function(element) {\n    var children = [];\n    forEach(element.childNodes, function(element) {\n      if (element.nodeType === NODE_TYPE_ELEMENT) {\n        children.push(element);\n      }\n    });\n    return children;\n  },\n\n  contents: function(element) {\n    return element.contentDocument || element.childNodes || [];\n  },\n\n  append: function(element, node) {\n    var nodeType = element.nodeType;\n    if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return;\n\n    node = new JQLite(node);\n\n    for (var i = 0, ii = node.length; i < ii; i++) {\n      var child = node[i];\n      element.appendChild(child);\n    }\n  },\n\n  prepend: function(element, node) {\n    if (element.nodeType === NODE_TYPE_ELEMENT) {\n      var index = element.firstChild;\n      forEach(new JQLite(node), function(child) {\n        element.insertBefore(child, index);\n      });\n    }\n  },\n\n  wrap: function(element, wrapNode) {\n    jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]);\n  },\n\n  remove: jqLiteRemove,\n\n  detach: function(element) {\n    jqLiteRemove(element, true);\n  },\n\n  after: function(element, newElement) {\n    var index = element, parent = element.parentNode;\n\n    if (parent) {\n      newElement = new JQLite(newElement);\n\n      for (var i = 0, ii = newElement.length; i < ii; i++) {\n        var node = newElement[i];\n        parent.insertBefore(node, index.nextSibling);\n        index = node;\n      }\n    }\n  },\n\n  addClass: jqLiteAddClass,\n  removeClass: jqLiteRemoveClass,\n\n  toggleClass: function(element, selector, condition) {\n    if (selector) {\n      forEach(selector.split(' '), function(className) {\n        var classCondition = condition;\n        if (isUndefined(classCondition)) {\n          classCondition = !jqLiteHasClass(element, className);\n        }\n        (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className);\n      });\n    }\n  },\n\n  parent: function(element) {\n    var parent = element.parentNode;\n    return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null;\n  },\n\n  next: function(element) {\n    return element.nextElementSibling;\n  },\n\n  find: function(element, selector) {\n    if (element.getElementsByTagName) {\n      return element.getElementsByTagName(selector);\n    } else {\n      return [];\n    }\n  },\n\n  clone: jqLiteClone,\n\n  triggerHandler: function(element, event, extraParameters) {\n\n    var dummyEvent, eventFnsCopy, handlerArgs;\n    var eventName = event.type || event;\n    var expandoStore = jqLiteExpandoStore(element);\n    var events = expandoStore && expandoStore.events;\n    var eventFns = events && events[eventName];\n\n    if (eventFns) {\n      // Create a dummy event to pass to the handlers\n      dummyEvent = {\n        preventDefault: function() { this.defaultPrevented = true; },\n        isDefaultPrevented: function() { return this.defaultPrevented === true; },\n        stopImmediatePropagation: function() { this.immediatePropagationStopped = true; },\n        isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; },\n        stopPropagation: noop,\n        type: eventName,\n        target: element\n      };\n\n      // If a custom event was provided then extend our dummy event with it\n      if (event.type) {\n        dummyEvent = extend(dummyEvent, event);\n      }\n\n      // Copy event handlers in case event handlers array is modified during execution.\n      eventFnsCopy = shallowCopy(eventFns);\n      handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];\n\n      forEach(eventFnsCopy, function(fn) {\n        if (!dummyEvent.isImmediatePropagationStopped()) {\n          fn.apply(element, handlerArgs);\n        }\n      });\n    }\n  }\n}, function(fn, name) {\n  /**\n   * chaining functions\n   */\n  JQLite.prototype[name] = function(arg1, arg2, arg3) {\n    var value;\n\n    for (var i = 0, ii = this.length; i < ii; i++) {\n      if (isUndefined(value)) {\n        value = fn(this[i], arg1, arg2, arg3);\n        if (isDefined(value)) {\n          // any function which returns a value needs to be wrapped\n          value = jqLite(value);\n        }\n      } else {\n        jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));\n      }\n    }\n    return isDefined(value) ? value : this;\n  };\n});\n\n// bind legacy bind/unbind to on/off\nJQLite.prototype.bind = JQLite.prototype.on;\nJQLite.prototype.unbind = JQLite.prototype.off;\n\n\n// Provider for private $$jqLite service\n/** @this */\nfunction $$jqLiteProvider() {\n  this.$get = function $$jqLite() {\n    return extend(JQLite, {\n      hasClass: function(node, classes) {\n        if (node.attr) node = node[0];\n        return jqLiteHasClass(node, classes);\n      },\n      addClass: function(node, classes) {\n        if (node.attr) node = node[0];\n        return jqLiteAddClass(node, classes);\n      },\n      removeClass: function(node, classes) {\n        if (node.attr) node = node[0];\n        return jqLiteRemoveClass(node, classes);\n      }\n    });\n  };\n}\n\n/**\n * Computes a hash of an 'obj'.\n * Hash of a:\n *  string is string\n *  number is number as string\n *  object is either result of calling $$hashKey function on the object or uniquely generated id,\n *         that is also assigned to the $$hashKey property of the object.\n *\n * @param obj\n * @returns {string} hash string such that the same input will have the same hash string.\n *         The resulting string key is in 'type:hashKey' format.\n */\nfunction hashKey(obj, nextUidFn) {\n  var key = obj && obj.$$hashKey;\n\n  if (key) {\n    if (typeof key === 'function') {\n      key = obj.$$hashKey();\n    }\n    return key;\n  }\n\n  var objType = typeof obj;\n  if (objType === 'function' || (objType === 'object' && obj !== null)) {\n    key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)();\n  } else {\n    key = objType + ':' + obj;\n  }\n\n  return key;\n}\n\n// A minimal ES2015 Map implementation.\n// Should be bug/feature equivalent to the native implementations of supported browsers\n// (for the features required in Angular).\n// See https://kangax.github.io/compat-table/es6/#test-Map\nvar nanKey = Object.create(null);\nfunction NgMapShim() {\n  this._keys = [];\n  this._values = [];\n  this._lastKey = NaN;\n  this._lastIndex = -1;\n}\nNgMapShim.prototype = {\n  _idx: function(key) {\n    if (key === this._lastKey) {\n      return this._lastIndex;\n    }\n    this._lastKey = key;\n    this._lastIndex = this._keys.indexOf(key);\n    return this._lastIndex;\n  },\n  _transformKey: function(key) {\n    return isNumberNaN(key) ? nanKey : key;\n  },\n  get: function(key) {\n    key = this._transformKey(key);\n    var idx = this._idx(key);\n    if (idx !== -1) {\n      return this._values[idx];\n    }\n  },\n  set: function(key, value) {\n    key = this._transformKey(key);\n    var idx = this._idx(key);\n    if (idx === -1) {\n      idx = this._lastIndex = this._keys.length;\n    }\n    this._keys[idx] = key;\n    this._values[idx] = value;\n\n    // Support: IE11\n    // Do not `return this` to simulate the partial IE11 implementation\n  },\n  delete: function(key) {\n    key = this._transformKey(key);\n    var idx = this._idx(key);\n    if (idx === -1) {\n      return false;\n    }\n    this._keys.splice(idx, 1);\n    this._values.splice(idx, 1);\n    this._lastKey = NaN;\n    this._lastIndex = -1;\n    return true;\n  }\n};\n\n// For now, always use `NgMapShim`, even if `window.Map` is available. Some native implementations\n// are still buggy (often in subtle ways) and can cause hard-to-debug failures. When native `Map`\n// implementations get more stable, we can reconsider switching to `window.Map` (when available).\nvar NgMap = NgMapShim;\n\nvar $$MapProvider = [/** @this */function() {\n  this.$get = [function() {\n    return NgMap;\n  }];\n}];\n\n/**\n * @ngdoc function\n * @module ng\n * @name angular.injector\n * @kind function\n *\n * @description\n * Creates an injector object that can be used for retrieving services as well as for\n * dependency injection (see {@link guide/di dependency injection}).\n *\n * @param {Array.<string|Function>} modules A list of module functions or their aliases. See\n *     {@link angular.module}. The `ng` module must be explicitly added.\n * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which\n *     disallows argument name annotation inference.\n * @returns {injector} Injector object. See {@link auto.$injector $injector}.\n *\n * @example\n * Typical usage\n * ```js\n *   // create an injector\n *   var $injector = angular.injector(['ng']);\n *\n *   // use the injector to kick off your application\n *   // use the type inference to auto inject arguments, or use implicit injection\n *   $injector.invoke(function($rootScope, $compile, $document) {\n *     $compile($document)($rootScope);\n *     $rootScope.$digest();\n *   });\n * ```\n *\n * Sometimes you want to get access to the injector of a currently running Angular app\n * from outside Angular. Perhaps, you want to inject and compile some markup after the\n * application has been bootstrapped. You can do this using the extra `injector()` added\n * to JQuery/jqLite elements. See {@link angular.element}.\n *\n * *This is fairly rare but could be the case if a third party library is injecting the\n * markup.*\n *\n * In the following example a new block of HTML containing a `ng-controller`\n * directive is added to the end of the document body by JQuery. We then compile and link\n * it into the current AngularJS scope.\n *\n * ```js\n * var $div = $('<div ng-controller=\"MyCtrl\">{{content.label}}</div>');\n * $(document.body).append($div);\n *\n * angular.element(document).injector().invoke(function($compile) {\n *   var scope = angular.element($div).scope();\n *   $compile($div)(scope);\n * });\n * ```\n */\n\n\n/**\n * @ngdoc module\n * @name auto\n * @installation\n * @description\n *\n * Implicit module which gets automatically added to each {@link auto.$injector $injector}.\n */\n\nvar ARROW_ARG = /^([^(]+?)=>/;\nvar FN_ARGS = /^[^(]*\\(\\s*([^)]*)\\)/m;\nvar FN_ARG_SPLIT = /,/;\nvar FN_ARG = /^\\s*(_?)(\\S+?)\\1\\s*$/;\nvar STRIP_COMMENTS = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\nvar $injectorMinErr = minErr('$injector');\n\nfunction stringifyFn(fn) {\n  return Function.prototype.toString.call(fn);\n}\n\nfunction extractArgs(fn) {\n  var fnText = stringifyFn(fn).replace(STRIP_COMMENTS, ''),\n      args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);\n  return args;\n}\n\nfunction anonFn(fn) {\n  // For anonymous functions, showing at the very least the function signature can help in\n  // debugging.\n  var args = extractArgs(fn);\n  if (args) {\n    return 'function(' + (args[1] || '').replace(/[\\s\\r\\n]+/, ' ') + ')';\n  }\n  return 'fn';\n}\n\nfunction annotate(fn, strictDi, name) {\n  var $inject,\n      argDecl,\n      last;\n\n  if (typeof fn === 'function') {\n    if (!($inject = fn.$inject)) {\n      $inject = [];\n      if (fn.length) {\n        if (strictDi) {\n          if (!isString(name) || !name) {\n            name = fn.name || anonFn(fn);\n          }\n          throw $injectorMinErr('strictdi',\n            '{0} is not using explicit annotation and cannot be invoked in strict mode', name);\n        }\n        argDecl = extractArgs(fn);\n        forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {\n          arg.replace(FN_ARG, function(all, underscore, name) {\n            $inject.push(name);\n          });\n        });\n      }\n      fn.$inject = $inject;\n    }\n  } else if (isArray(fn)) {\n    last = fn.length - 1;\n    assertArgFn(fn[last], 'fn');\n    $inject = fn.slice(0, last);\n  } else {\n    assertArgFn(fn, 'fn', true);\n  }\n  return $inject;\n}\n\n///////////////////////////////////////\n\n/**\n * @ngdoc service\n * @name $injector\n *\n * @description\n *\n * `$injector` is used to retrieve object instances as defined by\n * {@link auto.$provide provider}, instantiate types, invoke methods,\n * and load modules.\n *\n * The following always holds true:\n *\n * ```js\n *   var $injector = angular.injector();\n *   expect($injector.get('$injector')).toBe($injector);\n *   expect($injector.invoke(function($injector) {\n *     return $injector;\n *   })).toBe($injector);\n * ```\n *\n * # Injection Function Annotation\n *\n * JavaScript does not have annotations, and annotations are needed for dependency injection. The\n * following are all valid ways of annotating function with injection arguments and are equivalent.\n *\n * ```js\n *   // inferred (only works if code not minified/obfuscated)\n *   $injector.invoke(function(serviceA){});\n *\n *   // annotated\n *   function explicit(serviceA) {};\n *   explicit.$inject = ['serviceA'];\n *   $injector.invoke(explicit);\n *\n *   // inline\n *   $injector.invoke(['serviceA', function(serviceA){}]);\n * ```\n *\n * ## Inference\n *\n * In JavaScript calling `toString()` on a function returns the function definition. The definition\n * can then be parsed and the function arguments can be extracted. This method of discovering\n * annotations is disallowed when the injector is in strict mode.\n * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the\n * argument names.\n *\n * ## `$inject` Annotation\n * By adding an `$inject` property onto a function the injection parameters can be specified.\n *\n * ## Inline\n * As an array of injection names, where the last item in the array is the function to call.\n */\n\n/**\n * @ngdoc property\n * @name $injector#modules\n * @type {Object}\n * @description\n * A hash containing all the modules that have been loaded into the\n * $injector.\n *\n * You can use this property to find out information about a module via the\n * {@link angular.Module#info `myModule.info(...)`} method.\n *\n * For example:\n *\n * ```\n * var info = $injector.modules['ngAnimate'].info();\n * ```\n *\n * **Do not use this property to attempt to modify the modules after the application\n * has been bootstrapped.**\n */\n\n\n/**\n * @ngdoc method\n * @name $injector#get\n *\n * @description\n * Return an instance of the service.\n *\n * @param {string} name The name of the instance to retrieve.\n * @param {string=} caller An optional string to provide the origin of the function call for error messages.\n * @return {*} The instance.\n */\n\n/**\n * @ngdoc method\n * @name $injector#invoke\n *\n * @description\n * Invoke the method and supply the method arguments from the `$injector`.\n *\n * @param {Function|Array.<string|Function>} fn The injectable function to invoke. Function parameters are\n *   injected according to the {@link guide/di $inject Annotation} rules.\n * @param {Object=} self The `this` for the invoked method.\n * @param {Object=} locals Optional object. If preset then any argument names are read from this\n *                         object first, before the `$injector` is consulted.\n * @returns {*} the value returned by the invoked `fn` function.\n */\n\n/**\n * @ngdoc method\n * @name $injector#has\n *\n * @description\n * Allows the user to query if the particular service exists.\n *\n * @param {string} name Name of the service to query.\n * @returns {boolean} `true` if injector has given service.\n */\n\n/**\n * @ngdoc method\n * @name $injector#instantiate\n * @description\n * Create a new instance of JS type. The method takes a constructor function, invokes the new\n * operator, and supplies all of the arguments to the constructor function as specified by the\n * constructor annotation.\n *\n * @param {Function} Type Annotated constructor function.\n * @param {Object=} locals Optional object. If preset then any argument names are read from this\n * object first, before the `$injector` is consulted.\n * @returns {Object} new instance of `Type`.\n */\n\n/**\n * @ngdoc method\n * @name $injector#annotate\n *\n * @description\n * Returns an array of service names which the function is requesting for injection. This API is\n * used by the injector to determine which services need to be injected into the function when the\n * function is invoked. There are three ways in which the function can be annotated with the needed\n * dependencies.\n *\n * # Argument names\n *\n * The simplest form is to extract the dependencies from the arguments of the function. This is done\n * by converting the function into a string using `toString()` method and extracting the argument\n * names.\n * ```js\n *   // Given\n *   function MyController($scope, $route) {\n *     // ...\n *   }\n *\n *   // Then\n *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);\n * ```\n *\n * You can disallow this method by using strict injection mode.\n *\n * This method does not work with code minification / obfuscation. For this reason the following\n * annotation strategies are supported.\n *\n * # The `$inject` property\n *\n * If a function has an `$inject` property and its value is an array of strings, then the strings\n * represent names of services to be injected into the function.\n * ```js\n *   // Given\n *   var MyController = function(obfuscatedScope, obfuscatedRoute) {\n *     // ...\n *   }\n *   // Define function dependencies\n *   MyController['$inject'] = ['$scope', '$route'];\n *\n *   // Then\n *   expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);\n * ```\n *\n * # The array notation\n *\n * It is often desirable to inline Injected functions and that's when setting the `$inject` property\n * is very inconvenient. In these situations using the array notation to specify the dependencies in\n * a way that survives minification is a better choice:\n *\n * ```js\n *   // We wish to write this (not minification / obfuscation safe)\n *   injector.invoke(function($compile, $rootScope) {\n *     // ...\n *   });\n *\n *   // We are forced to write break inlining\n *   var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) {\n *     // ...\n *   };\n *   tmpFn.$inject = ['$compile', '$rootScope'];\n *   injector.invoke(tmpFn);\n *\n *   // To better support inline function the inline annotation is supported\n *   injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {\n *     // ...\n *   }]);\n *\n *   // Therefore\n *   expect(injector.annotate(\n *      ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}])\n *    ).toEqual(['$compile', '$rootScope']);\n * ```\n *\n * @param {Function|Array.<string|Function>} fn Function for which dependent service names need to\n * be retrieved as described above.\n *\n * @param {boolean=} [strictDi=false] Disallow argument name annotation inference.\n *\n * @returns {Array.<string>} The names of the services which the function requires.\n */\n\n\n\n/**\n * @ngdoc service\n * @name $provide\n *\n * @description\n *\n * The {@link auto.$provide $provide} service has a number of methods for registering components\n * with the {@link auto.$injector $injector}. Many of these functions are also exposed on\n * {@link angular.Module}.\n *\n * An Angular **service** is a singleton object created by a **service factory**.  These **service\n * factories** are functions which, in turn, are created by a **service provider**.\n * The **service providers** are constructor functions. When instantiated they must contain a\n * property called `$get`, which holds the **service factory** function.\n *\n * When you request a service, the {@link auto.$injector $injector} is responsible for finding the\n * correct **service provider**, instantiating it and then calling its `$get` **service factory**\n * function to get the instance of the **service**.\n *\n * Often services have no configuration options and there is no need to add methods to the service\n * provider.  The provider will be no more than a constructor function with a `$get` property. For\n * these cases the {@link auto.$provide $provide} service has additional helper methods to register\n * services without specifying a provider.\n *\n * * {@link auto.$provide#provider provider(name, provider)} - registers a **service provider** with the\n *     {@link auto.$injector $injector}\n * * {@link auto.$provide#constant constant(name, obj)} - registers a value/object that can be accessed by\n *     providers and services.\n * * {@link auto.$provide#value value(name, obj)} - registers a value/object that can only be accessed by\n *     services, not providers.\n * * {@link auto.$provide#factory factory(name, fn)} - registers a service **factory function**\n *     that will be wrapped in a **service provider** object, whose `$get` property will contain the\n *     given factory function.\n * * {@link auto.$provide#service service(name, Fn)} - registers a **constructor function**\n *     that will be wrapped in a **service provider** object, whose `$get` property will instantiate\n *      a new object using the given constructor function.\n * * {@link auto.$provide#decorator decorator(name, decorFn)} - registers a **decorator function** that\n *      will be able to modify or replace the implementation of another service.\n *\n * See the individual methods for more information and examples.\n */\n\n/**\n * @ngdoc method\n * @name $provide#provider\n * @description\n *\n * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions\n * are constructor functions, whose instances are responsible for \"providing\" a factory for a\n * service.\n *\n * Service provider names start with the name of the service they provide followed by `Provider`.\n * For example, the {@link ng.$log $log} service has a provider called\n * {@link ng.$logProvider $logProvider}.\n *\n * Service provider objects can have additional methods which allow configuration of the provider\n * and its service. Importantly, you can configure what kind of service is created by the `$get`\n * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a\n * method {@link ng.$logProvider#debugEnabled debugEnabled}\n * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the\n * console or not.\n *\n * @param {string} name The name of the instance. NOTE: the provider will be available under `name +\n                        'Provider'` key.\n * @param {(Object|function())} provider If the provider is:\n *\n *   - `Object`: then it should have a `$get` method. The `$get` method will be invoked using\n *     {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created.\n *   - `Constructor`: a new instance of the provider will be created using\n *     {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`.\n *\n * @returns {Object} registered provider instance\n\n * @example\n *\n * The following example shows how to create a simple event tracking service and register it using\n * {@link auto.$provide#provider $provide.provider()}.\n *\n * ```js\n *  // Define the eventTracker provider\n *  function EventTrackerProvider() {\n *    var trackingUrl = '/track';\n *\n *    // A provider method for configuring where the tracked events should been saved\n *    this.setTrackingUrl = function(url) {\n *      trackingUrl = url;\n *    };\n *\n *    // The service factory function\n *    this.$get = ['$http', function($http) {\n *      var trackedEvents = {};\n *      return {\n *        // Call this to track an event\n *        event: function(event) {\n *          var count = trackedEvents[event] || 0;\n *          count += 1;\n *          trackedEvents[event] = count;\n *          return count;\n *        },\n *        // Call this to save the tracked events to the trackingUrl\n *        save: function() {\n *          $http.post(trackingUrl, trackedEvents);\n *        }\n *      };\n *    }];\n *  }\n *\n *  describe('eventTracker', function() {\n *    var postSpy;\n *\n *    beforeEach(module(function($provide) {\n *      // Register the eventTracker provider\n *      $provide.provider('eventTracker', EventTrackerProvider);\n *    }));\n *\n *    beforeEach(module(function(eventTrackerProvider) {\n *      // Configure eventTracker provider\n *      eventTrackerProvider.setTrackingUrl('/custom-track');\n *    }));\n *\n *    it('tracks events', inject(function(eventTracker) {\n *      expect(eventTracker.event('login')).toEqual(1);\n *      expect(eventTracker.event('login')).toEqual(2);\n *    }));\n *\n *    it('saves to the tracking url', inject(function(eventTracker, $http) {\n *      postSpy = spyOn($http, 'post');\n *      eventTracker.event('login');\n *      eventTracker.save();\n *      expect(postSpy).toHaveBeenCalled();\n *      expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track');\n *      expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track');\n *      expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });\n *    }));\n *  });\n * ```\n */\n\n/**\n * @ngdoc method\n * @name $provide#factory\n * @description\n *\n * Register a **service factory**, which will be called to return the service instance.\n * This is short for registering a service where its provider consists of only a `$get` property,\n * which is the given service factory function.\n * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to\n * configure your service in a provider.\n *\n * @param {string} name The name of the instance.\n * @param {Function|Array.<string|Function>} $getFn The injectable $getFn for the instance creation.\n *                      Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`.\n * @returns {Object} registered provider instance\n *\n * @example\n * Here is an example of registering a service\n * ```js\n *   $provide.factory('ping', ['$http', function($http) {\n *     return function ping() {\n *       return $http.send('/ping');\n *     };\n *   }]);\n * ```\n * You would then inject and use this service like this:\n * ```js\n *   someModule.controller('Ctrl', ['ping', function(ping) {\n *     ping();\n *   }]);\n * ```\n */\n\n\n/**\n * @ngdoc method\n * @name $provide#service\n * @description\n *\n * Register a **service constructor**, which will be invoked with `new` to create the service\n * instance.\n * This is short for registering a service where its provider's `$get` property is a factory\n * function that returns an instance instantiated by the injector from the service constructor\n * function.\n *\n * Internally it looks a bit like this:\n *\n * ```\n * {\n *   $get: function() {\n *     return $injector.instantiate(constructor);\n *   }\n * }\n * ```\n *\n *\n * You should use {@link auto.$provide#service $provide.service(class)} if you define your service\n * as a type/class.\n *\n * @param {string} name The name of the instance.\n * @param {Function|Array.<string|Function>} constructor An injectable class (constructor function)\n *     that will be instantiated.\n * @returns {Object} registered provider instance\n *\n * @example\n * Here is an example of registering a service using\n * {@link auto.$provide#service $provide.service(class)}.\n * ```js\n *   var Ping = function($http) {\n *     this.$http = $http;\n *   };\n *\n *   Ping.$inject = ['$http'];\n *\n *   Ping.prototype.send = function() {\n *     return this.$http.get('/ping');\n *   };\n *   $provide.service('ping', Ping);\n * ```\n * You would then inject and use this service like this:\n * ```js\n *   someModule.controller('Ctrl', ['ping', function(ping) {\n *     ping.send();\n *   }]);\n * ```\n */\n\n\n/**\n * @ngdoc method\n * @name $provide#value\n * @description\n *\n * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a\n * number, an array, an object or a function. This is short for registering a service where its\n * provider's `$get` property is a factory function that takes no arguments and returns the **value\n * service**. That also means it is not possible to inject other services into a value service.\n *\n * Value services are similar to constant services, except that they cannot be injected into a\n * module configuration function (see {@link angular.Module#config}) but they can be overridden by\n * an Angular {@link auto.$provide#decorator decorator}.\n *\n * @param {string} name The name of the instance.\n * @param {*} value The value.\n * @returns {Object} registered provider instance\n *\n * @example\n * Here are some examples of creating value services.\n * ```js\n *   $provide.value('ADMIN_USER', 'admin');\n *\n *   $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });\n *\n *   $provide.value('halfOf', function(value) {\n *     return value / 2;\n *   });\n * ```\n */\n\n\n/**\n * @ngdoc method\n * @name $provide#constant\n * @description\n *\n * Register a **constant service** with the {@link auto.$injector $injector}, such as a string,\n * a number, an array, an object or a function. Like the {@link auto.$provide#value value}, it is not\n * possible to inject other services into a constant.\n *\n * But unlike {@link auto.$provide#value value}, a constant can be\n * injected into a module configuration function (see {@link angular.Module#config}) and it cannot\n * be overridden by an Angular {@link auto.$provide#decorator decorator}.\n *\n * @param {string} name The name of the constant.\n * @param {*} value The constant value.\n * @returns {Object} registered instance\n *\n * @example\n * Here a some examples of creating constants:\n * ```js\n *   $provide.constant('SHARD_HEIGHT', 306);\n *\n *   $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);\n *\n *   $provide.constant('double', function(value) {\n *     return value * 2;\n *   });\n * ```\n */\n\n\n/**\n * @ngdoc method\n * @name $provide#decorator\n * @description\n *\n * Register a **decorator function** with the {@link auto.$injector $injector}. A decorator function\n * intercepts the creation of a service, allowing it to override or modify the behavior of the\n * service. The return value of the decorator function may be the original service, or a new service\n * that replaces (or wraps and delegates to) the original service.\n *\n * You can find out more about using decorators in the {@link guide/decorators} guide.\n *\n * @param {string} name The name of the service to decorate.\n * @param {Function|Array.<string|Function>} decorator This function will be invoked when the service needs to be\n *    provided and should return the decorated service instance. The function is called using\n *    the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.\n *    Local injection arguments:\n *\n *    * `$delegate` - The original service instance, which can be replaced, monkey patched, configured,\n *      decorated or delegated to.\n *\n * @example\n * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting\n * calls to {@link ng.$log#error $log.warn()}.\n * ```js\n *   $provide.decorator('$log', ['$delegate', function($delegate) {\n *     $delegate.warn = $delegate.error;\n *     return $delegate;\n *   }]);\n * ```\n */\n\n\nfunction createInjector(modulesToLoad, strictDi) {\n  strictDi = (strictDi === true);\n  var INSTANTIATING = {},\n      providerSuffix = 'Provider',\n      path = [],\n      loadedModules = new NgMap(),\n      providerCache = {\n        $provide: {\n            provider: supportObject(provider),\n            factory: supportObject(factory),\n            service: supportObject(service),\n            value: supportObject(value),\n            constant: supportObject(constant),\n            decorator: decorator\n          }\n      },\n      providerInjector = (providerCache.$injector =\n          createInternalInjector(providerCache, function(serviceName, caller) {\n            if (angular.isString(caller)) {\n              path.push(caller);\n            }\n            throw $injectorMinErr('unpr', 'Unknown provider: {0}', path.join(' <- '));\n          })),\n      instanceCache = {},\n      protoInstanceInjector =\n          createInternalInjector(instanceCache, function(serviceName, caller) {\n            var provider = providerInjector.get(serviceName + providerSuffix, caller);\n            return instanceInjector.invoke(\n                provider.$get, provider, undefined, serviceName);\n          }),\n      instanceInjector = protoInstanceInjector;\n\n  providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };\n  instanceInjector.modules = providerInjector.modules = createMap();\n  var runBlocks = loadModules(modulesToLoad);\n  instanceInjector = protoInstanceInjector.get('$injector');\n  instanceInjector.strictDi = strictDi;\n  forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); });\n\n  return instanceInjector;\n\n  ////////////////////////////////////\n  // $provider\n  ////////////////////////////////////\n\n  function supportObject(delegate) {\n    return function(key, value) {\n      if (isObject(key)) {\n        forEach(key, reverseParams(delegate));\n      } else {\n        return delegate(key, value);\n      }\n    };\n  }\n\n  function provider(name, provider_) {\n    assertNotHasOwnProperty(name, 'service');\n    if (isFunction(provider_) || isArray(provider_)) {\n      provider_ = providerInjector.instantiate(provider_);\n    }\n    if (!provider_.$get) {\n      throw $injectorMinErr('pget', 'Provider \\'{0}\\' must define $get factory method.', name);\n    }\n    return (providerCache[name + providerSuffix] = provider_);\n  }\n\n  function enforceReturnValue(name, factory) {\n    return /** @this */ function enforcedReturnValue() {\n      var result = instanceInjector.invoke(factory, this);\n      if (isUndefined(result)) {\n        throw $injectorMinErr('undef', 'Provider \\'{0}\\' must return a value from $get factory method.', name);\n      }\n      return result;\n    };\n  }\n\n  function factory(name, factoryFn, enforce) {\n    return provider(name, {\n      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn\n    });\n  }\n\n  function service(name, constructor) {\n    return factory(name, ['$injector', function($injector) {\n      return $injector.instantiate(constructor);\n    }]);\n  }\n\n  function value(name, val) { return factory(name, valueFn(val), false); }\n\n  function constant(name, value) {\n    assertNotHasOwnProperty(name, 'constant');\n    providerCache[name] = value;\n    instanceCache[name] = value;\n  }\n\n  function decorator(serviceName, decorFn) {\n    var origProvider = providerInjector.get(serviceName + providerSuffix),\n        orig$get = origProvider.$get;\n\n    origProvider.$get = function() {\n      var origInstance = instanceInjector.invoke(orig$get, origProvider);\n      return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});\n    };\n  }\n\n  ////////////////////////////////////\n  // Module Loading\n  ////////////////////////////////////\n  function loadModules(modulesToLoad) {\n    assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array');\n    var runBlocks = [], moduleFn;\n    forEach(modulesToLoad, function(module) {\n      if (loadedModules.get(module)) return;\n      loadedModules.set(module, true);\n\n      function runInvokeQueue(queue) {\n        var i, ii;\n        for (i = 0, ii = queue.length; i < ii; i++) {\n          var invokeArgs = queue[i],\n              provider = providerInjector.get(invokeArgs[0]);\n\n          provider[invokeArgs[1]].apply(provider, invokeArgs[2]);\n        }\n      }\n\n      try {\n        if (isString(module)) {\n          moduleFn = angularModule(module);\n          instanceInjector.modules[module] = moduleFn;\n          runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);\n          runInvokeQueue(moduleFn._invokeQueue);\n          runInvokeQueue(moduleFn._configBlocks);\n        } else if (isFunction(module)) {\n            runBlocks.push(providerInjector.invoke(module));\n        } else if (isArray(module)) {\n            runBlocks.push(providerInjector.invoke(module));\n        } else {\n          assertArgFn(module, 'module');\n        }\n      } catch (e) {\n        if (isArray(module)) {\n          module = module[module.length - 1];\n        }\n        if (e.message && e.stack && e.stack.indexOf(e.message) === -1) {\n          // Safari & FF's stack traces don't contain error.message content\n          // unlike those of Chrome and IE\n          // So if stack doesn't contain message, we create a new string that contains both.\n          // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here.\n          // eslint-disable-next-line no-ex-assign\n          e = e.message + '\\n' + e.stack;\n        }\n        throw $injectorMinErr('modulerr', 'Failed to instantiate module {0} due to:\\n{1}',\n                  module, e.stack || e.message || e);\n      }\n    });\n    return runBlocks;\n  }\n\n  ////////////////////////////////////\n  // internal Injector\n  ////////////////////////////////////\n\n  function createInternalInjector(cache, factory) {\n\n    function getService(serviceName, caller) {\n      if (cache.hasOwnProperty(serviceName)) {\n        if (cache[serviceName] === INSTANTIATING) {\n          throw $injectorMinErr('cdep', 'Circular dependency found: {0}',\n                    serviceName + ' <- ' + path.join(' <- '));\n        }\n        return cache[serviceName];\n      } else {\n        try {\n          path.unshift(serviceName);\n          cache[serviceName] = INSTANTIATING;\n          cache[serviceName] = factory(serviceName, caller);\n          return cache[serviceName];\n        } catch (err) {\n          if (cache[serviceName] === INSTANTIATING) {\n            delete cache[serviceName];\n          }\n          throw err;\n        } finally {\n          path.shift();\n        }\n      }\n    }\n\n\n    function injectionArgs(fn, locals, serviceName) {\n      var args = [],\n          $inject = createInjector.$$annotate(fn, strictDi, serviceName);\n\n      for (var i = 0, length = $inject.length; i < length; i++) {\n        var key = $inject[i];\n        if (typeof key !== 'string') {\n          throw $injectorMinErr('itkn',\n                  'Incorrect injection token! Expected service name as string, got {0}', key);\n        }\n        args.push(locals && locals.hasOwnProperty(key) ? locals[key] :\n                                                         getService(key, serviceName));\n      }\n      return args;\n    }\n\n    function isClass(func) {\n      // Support: IE 9-11 only\n      // IE 9-11 do not support classes and IE9 leaks with the code below.\n      if (msie || typeof func !== 'function') {\n        return false;\n      }\n      var result = func.$$ngIsClass;\n      if (!isBoolean(result)) {\n        // Support: Edge 12-13 only\n        // See: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6156135/\n        result = func.$$ngIsClass = /^(?:class\\b|constructor\\()/.test(stringifyFn(func));\n      }\n      return result;\n    }\n\n    function invoke(fn, self, locals, serviceName) {\n      if (typeof locals === 'string') {\n        serviceName = locals;\n        locals = null;\n      }\n\n      var args = injectionArgs(fn, locals, serviceName);\n      if (isArray(fn)) {\n        fn = fn[fn.length - 1];\n      }\n\n      if (!isClass(fn)) {\n        // http://jsperf.com/angularjs-invoke-apply-vs-switch\n        // #5388\n        return fn.apply(self, args);\n      } else {\n        args.unshift(null);\n        return new (Function.prototype.bind.apply(fn, args))();\n      }\n    }\n\n\n    function instantiate(Type, locals, serviceName) {\n      // Check if Type is annotated and use just the given function at n-1 as parameter\n      // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);\n      var ctor = (isArray(Type) ? Type[Type.length - 1] : Type);\n      var args = injectionArgs(Type, locals, serviceName);\n      // Empty object at position 0 is ignored for invocation with `new`, but required.\n      args.unshift(null);\n      return new (Function.prototype.bind.apply(ctor, args))();\n    }\n\n\n    return {\n      invoke: invoke,\n      instantiate: instantiate,\n      get: getService,\n      annotate: createInjector.$$annotate,\n      has: function(name) {\n        return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);\n      }\n    };\n  }\n}\n\ncreateInjector.$$annotate = annotate;\n\n/**\n * @ngdoc provider\n * @name $anchorScrollProvider\n * @this\n *\n * @description\n * Use `$anchorScrollProvider` to disable automatic scrolling whenever\n * {@link ng.$location#hash $location.hash()} changes.\n */\nfunction $AnchorScrollProvider() {\n\n  var autoScrollingEnabled = true;\n\n  /**\n   * @ngdoc method\n   * @name $anchorScrollProvider#disableAutoScrolling\n   *\n   * @description\n   * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to\n   * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.<br />\n   * Use this method to disable automatic scrolling.\n   *\n   * If automatic scrolling is disabled, one must explicitly call\n   * {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the\n   * current hash.\n   */\n  this.disableAutoScrolling = function() {\n    autoScrollingEnabled = false;\n  };\n\n  /**\n   * @ngdoc service\n   * @name $anchorScroll\n   * @kind function\n   * @requires $window\n   * @requires $location\n   * @requires $rootScope\n   *\n   * @description\n   * When called, it scrolls to the element related to the specified `hash` or (if omitted) to the\n   * current value of {@link ng.$location#hash $location.hash()}, according to the rules specified\n   * in the\n   * [HTML5 spec](http://www.w3.org/html/wg/drafts/html/master/browsers.html#an-indicated-part-of-the-document).\n   *\n   * It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to\n   * match any anchor whenever it changes. This can be disabled by calling\n   * {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}.\n   *\n   * Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a\n   * vertical scroll-offset (either fixed or dynamic).\n   *\n   * @param {string=} hash The hash specifying the element to scroll to. If omitted, the value of\n   *                       {@link ng.$location#hash $location.hash()} will be used.\n   *\n   * @property {(number|function|jqLite)} yOffset\n   * If set, specifies a vertical scroll-offset. This is often useful when there are fixed\n   * positioned elements at the top of the page, such as navbars, headers etc.\n   *\n   * `yOffset` can be specified in various ways:\n   * - **number**: A fixed number of pixels to be used as offset.<br /><br />\n   * - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return\n   *   a number representing the offset (in pixels).<br /><br />\n   * - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from\n   *   the top of the page to the element's bottom will be used as offset.<br />\n   *   **Note**: The element will be taken into account only as long as its `position` is set to\n   *   `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust\n   *   their height and/or positioning according to the viewport's size.\n   *\n   * <br />\n   * <div class=\"alert alert-warning\">\n   * In order for `yOffset` to work properly, scrolling should take place on the document's root and\n   * not some child element.\n   * </div>\n   *\n   * @example\n     <example module=\"anchorScrollExample\" name=\"anchor-scroll\">\n       <file name=\"index.html\">\n         <div id=\"scrollArea\" ng-controller=\"ScrollController\">\n           <a ng-click=\"gotoBottom()\">Go to bottom</a>\n           <a id=\"bottom\"></a> You're at the bottom!\n         </div>\n       </file>\n       <file name=\"script.js\">\n         angular.module('anchorScrollExample', [])\n           .controller('ScrollController', ['$scope', '$location', '$anchorScroll',\n             function($scope, $location, $anchorScroll) {\n               $scope.gotoBottom = function() {\n                 // set the location.hash to the id of\n                 // the element you wish to scroll to.\n                 $location.hash('bottom');\n\n                 // call $anchorScroll()\n                 $anchorScroll();\n               };\n             }]);\n       </file>\n       <file name=\"style.css\">\n         #scrollArea {\n           height: 280px;\n           overflow: auto;\n         }\n\n         #bottom {\n           display: block;\n           margin-top: 2000px;\n         }\n       </file>\n     </example>\n   *\n   * <hr />\n   * The example below illustrates the use of a vertical scroll-offset (specified as a fixed value).\n   * See {@link ng.$anchorScroll#yOffset $anchorScroll.yOffset} for more details.\n   *\n   * @example\n     <example module=\"anchorScrollOffsetExample\" name=\"anchor-scroll-offset\">\n       <file name=\"index.html\">\n         <div class=\"fixed-header\" ng-controller=\"headerCtrl\">\n           <a href=\"\" ng-click=\"gotoAnchor(x)\" ng-repeat=\"x in [1,2,3,4,5]\">\n             Go to anchor {{x}}\n           </a>\n         </div>\n         <div id=\"anchor{{x}}\" class=\"anchor\" ng-repeat=\"x in [1,2,3,4,5]\">\n           Anchor {{x}} of 5\n         </div>\n       </file>\n       <file name=\"script.js\">\n         angular.module('anchorScrollOffsetExample', [])\n           .run(['$anchorScroll', function($anchorScroll) {\n             $anchorScroll.yOffset = 50;   // always scroll by 50 extra pixels\n           }])\n           .controller('headerCtrl', ['$anchorScroll', '$location', '$scope',\n             function($anchorScroll, $location, $scope) {\n               $scope.gotoAnchor = function(x) {\n                 var newHash = 'anchor' + x;\n                 if ($location.hash() !== newHash) {\n                   // set the $location.hash to `newHash` and\n                   // $anchorScroll will automatically scroll to it\n                   $location.hash('anchor' + x);\n                 } else {\n                   // call $anchorScroll() explicitly,\n                   // since $location.hash hasn't changed\n                   $anchorScroll();\n                 }\n               };\n             }\n           ]);\n       </file>\n       <file name=\"style.css\">\n         body {\n           padding-top: 50px;\n         }\n\n         .anchor {\n           border: 2px dashed DarkOrchid;\n           padding: 10px 10px 200px 10px;\n         }\n\n         .fixed-header {\n           background-color: rgba(0, 0, 0, 0.2);\n           height: 50px;\n           position: fixed;\n           top: 0; left: 0; right: 0;\n         }\n\n         .fixed-header > a {\n           display: inline-block;\n           margin: 5px 15px;\n         }\n       </file>\n     </example>\n   */\n  this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {\n    var document = $window.document;\n\n    // Helper function to get first anchor from a NodeList\n    // (using `Array#some()` instead of `angular#forEach()` since it's more performant\n    //  and working in all supported browsers.)\n    function getFirstAnchor(list) {\n      var result = null;\n      Array.prototype.some.call(list, function(element) {\n        if (nodeName_(element) === 'a') {\n          result = element;\n          return true;\n        }\n      });\n      return result;\n    }\n\n    function getYOffset() {\n\n      var offset = scroll.yOffset;\n\n      if (isFunction(offset)) {\n        offset = offset();\n      } else if (isElement(offset)) {\n        var elem = offset[0];\n        var style = $window.getComputedStyle(elem);\n        if (style.position !== 'fixed') {\n          offset = 0;\n        } else {\n          offset = elem.getBoundingClientRect().bottom;\n        }\n      } else if (!isNumber(offset)) {\n        offset = 0;\n      }\n\n      return offset;\n    }\n\n    function scrollTo(elem) {\n      if (elem) {\n        elem.scrollIntoView();\n\n        var offset = getYOffset();\n\n        if (offset) {\n          // `offset` is the number of pixels we should scroll UP in order to align `elem` properly.\n          // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the\n          // top of the viewport.\n          //\n          // IF the number of pixels from the top of `elem` to the end of the page's content is less\n          // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some\n          // way down the page.\n          //\n          // This is often the case for elements near the bottom of the page.\n          //\n          // In such cases we do not need to scroll the whole `offset` up, just the difference between\n          // the top of the element and the offset, which is enough to align the top of `elem` at the\n          // desired position.\n          var elemTop = elem.getBoundingClientRect().top;\n          $window.scrollBy(0, elemTop - offset);\n        }\n      } else {\n        $window.scrollTo(0, 0);\n      }\n    }\n\n    function scroll(hash) {\n      // Allow numeric hashes\n      hash = isString(hash) ? hash : isNumber(hash) ? hash.toString() : $location.hash();\n      var elm;\n\n      // empty hash, scroll to the top of the page\n      if (!hash) scrollTo(null);\n\n      // element with given id\n      else if ((elm = document.getElementById(hash))) scrollTo(elm);\n\n      // first anchor with given name :-D\n      else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);\n\n      // no element and hash === 'top', scroll to the top of the page\n      else if (hash === 'top') scrollTo(null);\n    }\n\n    // does not scroll when user clicks on anchor link that is currently on\n    // (no url change, no $location.hash() change), browser native does scroll\n    if (autoScrollingEnabled) {\n      $rootScope.$watch(function autoScrollWatch() {return $location.hash();},\n        function autoScrollWatchAction(newVal, oldVal) {\n          // skip the initial scroll if $location.hash is empty\n          if (newVal === oldVal && newVal === '') return;\n\n          jqLiteDocumentLoaded(function() {\n            $rootScope.$evalAsync(scroll);\n          });\n        });\n    }\n\n    return scroll;\n  }];\n}\n\nvar $animateMinErr = minErr('$animate');\nvar ELEMENT_NODE = 1;\nvar NG_ANIMATE_CLASSNAME = 'ng-animate';\n\nfunction mergeClasses(a,b) {\n  if (!a && !b) return '';\n  if (!a) return b;\n  if (!b) return a;\n  if (isArray(a)) a = a.join(' ');\n  if (isArray(b)) b = b.join(' ');\n  return a + ' ' + b;\n}\n\nfunction extractElementNode(element) {\n  for (var i = 0; i < element.length; i++) {\n    var elm = element[i];\n    if (elm.nodeType === ELEMENT_NODE) {\n      return elm;\n    }\n  }\n}\n\nfunction splitClasses(classes) {\n  if (isString(classes)) {\n    classes = classes.split(' ');\n  }\n\n  // Use createMap() to prevent class assumptions involving property names in\n  // Object.prototype\n  var obj = createMap();\n  forEach(classes, function(klass) {\n    // sometimes the split leaves empty string values\n    // incase extra spaces were applied to the options\n    if (klass.length) {\n      obj[klass] = true;\n    }\n  });\n  return obj;\n}\n\n// if any other type of options value besides an Object value is\n// passed into the $animate.method() animation then this helper code\n// will be run which will ignore it. While this patch is not the\n// greatest solution to this, a lot of existing plugins depend on\n// $animate to either call the callback (< 1.2) or return a promise\n// that can be changed. This helper function ensures that the options\n// are wiped clean incase a callback function is provided.\nfunction prepareAnimateOptions(options) {\n  return isObject(options)\n      ? options\n      : {};\n}\n\nvar $$CoreAnimateJsProvider = /** @this */ function() {\n  this.$get = noop;\n};\n\n// this is prefixed with Core since it conflicts with\n// the animateQueueProvider defined in ngAnimate/animateQueue.js\nvar $$CoreAnimateQueueProvider = /** @this */ function() {\n  var postDigestQueue = new NgMap();\n  var postDigestElements = [];\n\n  this.$get = ['$$AnimateRunner', '$rootScope',\n       function($$AnimateRunner,   $rootScope) {\n    return {\n      enabled: noop,\n      on: noop,\n      off: noop,\n      pin: noop,\n\n      push: function(element, event, options, domOperation) {\n        if (domOperation) {\n          domOperation();\n        }\n\n        options = options || {};\n        if (options.from) {\n          element.css(options.from);\n        }\n        if (options.to) {\n          element.css(options.to);\n        }\n\n        if (options.addClass || options.removeClass) {\n          addRemoveClassesPostDigest(element, options.addClass, options.removeClass);\n        }\n\n        var runner = new $$AnimateRunner();\n\n        // since there are no animations to run the runner needs to be\n        // notified that the animation call is complete.\n        runner.complete();\n        return runner;\n      }\n    };\n\n\n    function updateData(data, classes, value) {\n      var changed = false;\n      if (classes) {\n        classes = isString(classes) ? classes.split(' ') :\n                  isArray(classes) ? classes : [];\n        forEach(classes, function(className) {\n          if (className) {\n            changed = true;\n            data[className] = value;\n          }\n        });\n      }\n      return changed;\n    }\n\n    function handleCSSClassChanges() {\n      forEach(postDigestElements, function(element) {\n        var data = postDigestQueue.get(element);\n        if (data) {\n          var existing = splitClasses(element.attr('class'));\n          var toAdd = '';\n          var toRemove = '';\n          forEach(data, function(status, className) {\n            var hasClass = !!existing[className];\n            if (status !== hasClass) {\n              if (status) {\n                toAdd += (toAdd.length ? ' ' : '') + className;\n              } else {\n                toRemove += (toRemove.length ? ' ' : '') + className;\n              }\n            }\n          });\n\n          forEach(element, function(elm) {\n            if (toAdd) {\n              jqLiteAddClass(elm, toAdd);\n            }\n            if (toRemove) {\n              jqLiteRemoveClass(elm, toRemove);\n            }\n          });\n          postDigestQueue.delete(element);\n        }\n      });\n      postDigestElements.length = 0;\n    }\n\n\n    function addRemoveClassesPostDigest(element, add, remove) {\n      var data = postDigestQueue.get(element) || {};\n\n      var classesAdded = updateData(data, add, true);\n      var classesRemoved = updateData(data, remove, false);\n\n      if (classesAdded || classesRemoved) {\n\n        postDigestQueue.set(element, data);\n        postDigestElements.push(element);\n\n        if (postDigestElements.length === 1) {\n          $rootScope.$$postDigest(handleCSSClassChanges);\n        }\n      }\n    }\n  }];\n};\n\n/**\n * @ngdoc provider\n * @name $animateProvider\n *\n * @description\n * Default implementation of $animate that doesn't perform any animations, instead just\n * synchronously performs DOM updates and resolves the returned runner promise.\n *\n * In order to enable animations the `ngAnimate` module has to be loaded.\n *\n * To see the functional implementation check out `src/ngAnimate/animate.js`.\n */\nvar $AnimateProvider = ['$provide', /** @this */ function($provide) {\n  var provider = this;\n  var classNameFilter = null;\n\n  this.$$registeredAnimations = Object.create(null);\n\n   /**\n   * @ngdoc method\n   * @name $animateProvider#register\n   *\n   * @description\n   * Registers a new injectable animation factory function. The factory function produces the\n   * animation object which contains callback functions for each event that is expected to be\n   * animated.\n   *\n   *   * `eventFn`: `function(element, ... , doneFunction, options)`\n   *   The element to animate, the `doneFunction` and the options fed into the animation. Depending\n   *   on the type of animation additional arguments will be injected into the animation function. The\n   *   list below explains the function signatures for the different animation methods:\n   *\n   *   - setClass: function(element, addedClasses, removedClasses, doneFunction, options)\n   *   - addClass: function(element, addedClasses, doneFunction, options)\n   *   - removeClass: function(element, removedClasses, doneFunction, options)\n   *   - enter, leave, move: function(element, doneFunction, options)\n   *   - animate: function(element, fromStyles, toStyles, doneFunction, options)\n   *\n   *   Make sure to trigger the `doneFunction` once the animation is fully complete.\n   *\n   * ```js\n   *   return {\n   *     //enter, leave, move signature\n   *     eventFn : function(element, done, options) {\n   *       //code to run the animation\n   *       //once complete, then run done()\n   *       return function endFunction(wasCancelled) {\n   *         //code to cancel the animation\n   *       }\n   *     }\n   *   }\n   * ```\n   *\n   * @param {string} name The name of the animation (this is what the class-based CSS value will be compared to).\n   * @param {Function} factory The factory function that will be executed to return the animation\n   *                           object.\n   */\n  this.register = function(name, factory) {\n    if (name && name.charAt(0) !== '.') {\n      throw $animateMinErr('notcsel', 'Expecting class selector starting with \\'.\\' got \\'{0}\\'.', name);\n    }\n\n    var key = name + '-animation';\n    provider.$$registeredAnimations[name.substr(1)] = key;\n    $provide.factory(key, factory);\n  };\n\n  /**\n   * @ngdoc method\n   * @name $animateProvider#classNameFilter\n   *\n   * @description\n   * Sets and/or returns the CSS class regular expression that is checked when performing\n   * an animation. Upon bootstrap the classNameFilter value is not set at all and will\n   * therefore enable $animate to attempt to perform an animation on any element that is triggered.\n   * When setting the `classNameFilter` value, animations will only be performed on elements\n   * that successfully match the filter expression. This in turn can boost performance\n   * for low-powered devices as well as applications containing a lot of structural operations.\n   * @param {RegExp=} expression The className expression which will be checked against all animations\n   * @return {RegExp} The current CSS className expression value. If null then there is no expression value\n   */\n  this.classNameFilter = function(expression) {\n    if (arguments.length === 1) {\n      classNameFilter = (expression instanceof RegExp) ? expression : null;\n      if (classNameFilter) {\n        var reservedRegex = new RegExp('[(\\\\s|\\\\/)]' + NG_ANIMATE_CLASSNAME + '[(\\\\s|\\\\/)]');\n        if (reservedRegex.test(classNameFilter.toString())) {\n          classNameFilter = null;\n          throw $animateMinErr('nongcls', '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the \"{0}\" CSS class.', NG_ANIMATE_CLASSNAME);\n        }\n      }\n    }\n    return classNameFilter;\n  };\n\n  this.$get = ['$$animateQueue', function($$animateQueue) {\n    function domInsert(element, parentElement, afterElement) {\n      // if for some reason the previous element was removed\n      // from the dom sometime before this code runs then let's\n      // just stick to using the parent element as the anchor\n      if (afterElement) {\n        var afterNode = extractElementNode(afterElement);\n        if (afterNode && !afterNode.parentNode && !afterNode.previousElementSibling) {\n          afterElement = null;\n        }\n      }\n      if (afterElement) {\n        afterElement.after(element);\n      } else {\n        parentElement.prepend(element);\n      }\n    }\n\n    /**\n     * @ngdoc service\n     * @name $animate\n     * @description The $animate service exposes a series of DOM utility methods that provide support\n     * for animation hooks. The default behavior is the application of DOM operations, however,\n     * when an animation is detected (and animations are enabled), $animate will do the heavy lifting\n     * to ensure that animation runs with the triggered DOM operation.\n     *\n     * By default $animate doesn't trigger any animations. This is because the `ngAnimate` module isn't\n     * included and only when it is active then the animation hooks that `$animate` triggers will be\n     * functional. Once active then all structural `ng-` directives will trigger animations as they perform\n     * their DOM-related operations (enter, leave and move). Other directives such as `ngClass`,\n     * `ngShow`, `ngHide` and `ngMessages` also provide support for animations.\n     *\n     * It is recommended that the`$animate` service is always used when executing DOM-related procedures within directives.\n     *\n     * To learn more about enabling animation support, click here to visit the\n     * {@link ngAnimate ngAnimate module page}.\n     */\n    return {\n      // we don't call it directly since non-existant arguments may\n      // be interpreted as null within the sub enabled function\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#on\n       * @kind function\n       * @description Sets up an event listener to fire whenever the animation event (enter, leave, move, etc...)\n       *    has fired on the given element or among any of its children. Once the listener is fired, the provided callback\n       *    is fired with the following params:\n       *\n       * ```js\n       * $animate.on('enter', container,\n       *    function callback(element, phase) {\n       *      // cool we detected an enter animation within the container\n       *    }\n       * );\n       * ```\n       *\n       * @param {string} event the animation event that will be captured (e.g. enter, leave, move, addClass, removeClass, etc...)\n       * @param {DOMElement} container the container element that will capture each of the animation events that are fired on itself\n       *     as well as among its children\n       * @param {Function} callback the callback function that will be fired when the listener is triggered\n       *\n       * The arguments present in the callback function are:\n       * * `element` - The captured DOM element that the animation was fired on.\n       * * `phase` - The phase of the animation. The two possible phases are **start** (when the animation starts) and **close** (when it ends).\n       */\n      on: $$animateQueue.on,\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#off\n       * @kind function\n       * @description Deregisters an event listener based on the event which has been associated with the provided element. This method\n       * can be used in three different ways depending on the arguments:\n       *\n       * ```js\n       * // remove all the animation event listeners listening for `enter`\n       * $animate.off('enter');\n       *\n       * // remove listeners for all animation events from the container element\n       * $animate.off(container);\n       *\n       * // remove all the animation event listeners listening for `enter` on the given element and its children\n       * $animate.off('enter', container);\n       *\n       * // remove the event listener function provided by `callback` that is set\n       * // to listen for `enter` on the given `container` as well as its children\n       * $animate.off('enter', container, callback);\n       * ```\n       *\n       * @param {string|DOMElement} event|container the animation event (e.g. enter, leave, move,\n       * addClass, removeClass, etc...), or the container element. If it is the element, all other\n       * arguments are ignored.\n       * @param {DOMElement=} container the container element the event listener was placed on\n       * @param {Function=} callback the callback function that was registered as the listener\n       */\n      off: $$animateQueue.off,\n\n      /**\n       * @ngdoc method\n       * @name $animate#pin\n       * @kind function\n       * @description Associates the provided element with a host parent element to allow the element to be animated even if it exists\n       *    outside of the DOM structure of the Angular application. By doing so, any animation triggered via `$animate` can be issued on the\n       *    element despite being outside the realm of the application or within another application. Say for example if the application\n       *    was bootstrapped on an element that is somewhere inside of the `<body>` tag, but we wanted to allow for an element to be situated\n       *    as a direct child of `document.body`, then this can be achieved by pinning the element via `$animate.pin(element)`. Keep in mind\n       *    that calling `$animate.pin(element, parentElement)` will not actually insert into the DOM anywhere; it will just create the association.\n       *\n       *    Note that this feature is only active when the `ngAnimate` module is used.\n       *\n       * @param {DOMElement} element the external element that will be pinned\n       * @param {DOMElement} parentElement the host parent element that will be associated with the external element\n       */\n      pin: $$animateQueue.pin,\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#enabled\n       * @kind function\n       * @description Used to get and set whether animations are enabled or not on the entire application or on an element and its children. This\n       * function can be called in four ways:\n       *\n       * ```js\n       * // returns true or false\n       * $animate.enabled();\n       *\n       * // changes the enabled state for all animations\n       * $animate.enabled(false);\n       * $animate.enabled(true);\n       *\n       * // returns true or false if animations are enabled for an element\n       * $animate.enabled(element);\n       *\n       * // changes the enabled state for an element and its children\n       * $animate.enabled(element, true);\n       * $animate.enabled(element, false);\n       * ```\n       *\n       * @param {DOMElement=} element the element that will be considered for checking/setting the enabled state\n       * @param {boolean=} enabled whether or not the animations will be enabled for the element\n       *\n       * @return {boolean} whether or not animations are enabled\n       */\n      enabled: $$animateQueue.enabled,\n\n      /**\n       * @ngdoc method\n       * @name $animate#cancel\n       * @kind function\n       * @description Cancels the provided animation.\n       *\n       * @param {Promise} animationPromise The animation promise that is returned when an animation is started.\n       */\n      cancel: function(runner) {\n        if (runner.end) {\n          runner.end();\n        }\n      },\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#enter\n       * @kind function\n       * @description Inserts the element into the DOM either after the `after` element (if provided) or\n       *   as the first child within the `parent` element and then triggers an animation.\n       *   A promise is returned that will be resolved during the next digest once the animation\n       *   has completed.\n       *\n       * @param {DOMElement} element the element which will be inserted into the DOM\n       * @param {DOMElement} parent the parent element which will append the element as\n       *   a child (so long as the after element is not present)\n       * @param {DOMElement=} after the sibling element after which the element will be appended\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      enter: function(element, parent, after, options) {\n        parent = parent && jqLite(parent);\n        after = after && jqLite(after);\n        parent = parent || after.parent();\n        domInsert(element, parent, after);\n        return $$animateQueue.push(element, 'enter', prepareAnimateOptions(options));\n      },\n\n      /**\n       *\n       * @ngdoc method\n       * @name $animate#move\n       * @kind function\n       * @description Inserts (moves) the element into its new position in the DOM either after\n       *   the `after` element (if provided) or as the first child within the `parent` element\n       *   and then triggers an animation. A promise is returned that will be resolved\n       *   during the next digest once the animation has completed.\n       *\n       * @param {DOMElement} element the element which will be moved into the new DOM position\n       * @param {DOMElement} parent the parent element which will append the element as\n       *   a child (so long as the after element is not present)\n       * @param {DOMElement=} after the sibling element after which the element will be appended\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      move: function(element, parent, after, options) {\n        parent = parent && jqLite(parent);\n        after = after && jqLite(after);\n        parent = parent || after.parent();\n        domInsert(element, parent, after);\n        return $$animateQueue.push(element, 'move', prepareAnimateOptions(options));\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#leave\n       * @kind function\n       * @description Triggers an animation and then removes the element from the DOM.\n       * When the function is called a promise is returned that will be resolved during the next\n       * digest once the animation has completed.\n       *\n       * @param {DOMElement} element the element which will be removed from the DOM\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      leave: function(element, options) {\n        return $$animateQueue.push(element, 'leave', prepareAnimateOptions(options), function() {\n          element.remove();\n        });\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#addClass\n       * @kind function\n       *\n       * @description Triggers an addClass animation surrounding the addition of the provided CSS class(es). Upon\n       *   execution, the addClass operation will only be handled after the next digest and it will not trigger an\n       *   animation if element already contains the CSS class or if the class is removed at a later step.\n       *   Note that class-based animations are treated differently compared to structural animations\n       *   (like enter, move and leave) since the CSS classes may be added/removed at different points\n       *   depending if CSS or JavaScript animations are used.\n       *\n       * @param {DOMElement} element the element which the CSS classes will be applied to\n       * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces)\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      addClass: function(element, className, options) {\n        options = prepareAnimateOptions(options);\n        options.addClass = mergeClasses(options.addclass, className);\n        return $$animateQueue.push(element, 'addClass', options);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#removeClass\n       * @kind function\n       *\n       * @description Triggers a removeClass animation surrounding the removal of the provided CSS class(es). Upon\n       *   execution, the removeClass operation will only be handled after the next digest and it will not trigger an\n       *   animation if element does not contain the CSS class or if the class is added at a later step.\n       *   Note that class-based animations are treated differently compared to structural animations\n       *   (like enter, move and leave) since the CSS classes may be added/removed at different points\n       *   depending if CSS or JavaScript animations are used.\n       *\n       * @param {DOMElement} element the element which the CSS classes will be applied to\n       * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces)\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      removeClass: function(element, className, options) {\n        options = prepareAnimateOptions(options);\n        options.removeClass = mergeClasses(options.removeClass, className);\n        return $$animateQueue.push(element, 'removeClass', options);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#setClass\n       * @kind function\n       *\n       * @description Performs both the addition and removal of a CSS classes on an element and (during the process)\n       *    triggers an animation surrounding the class addition/removal. Much like `$animate.addClass` and\n       *    `$animate.removeClass`, `setClass` will only evaluate the classes being added/removed once a digest has\n       *    passed. Note that class-based animations are treated differently compared to structural animations\n       *    (like enter, move and leave) since the CSS classes may be added/removed at different points\n       *    depending if CSS or JavaScript animations are used.\n       *\n       * @param {DOMElement} element the element which the CSS classes will be applied to\n       * @param {string} add the CSS class(es) that will be added (multiple classes are separated via spaces)\n       * @param {string} remove the CSS class(es) that will be removed (multiple classes are separated via spaces)\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      setClass: function(element, add, remove, options) {\n        options = prepareAnimateOptions(options);\n        options.addClass = mergeClasses(options.addClass, add);\n        options.removeClass = mergeClasses(options.removeClass, remove);\n        return $$animateQueue.push(element, 'setClass', options);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $animate#animate\n       * @kind function\n       *\n       * @description Performs an inline animation on the element which applies the provided to and from CSS styles to the element.\n       * If any detected CSS transition, keyframe or JavaScript matches the provided className value, then the animation will take\n       * on the provided styles. For example, if a transition animation is set for the given className, then the provided `from` and\n       * `to` styles will be applied alongside the given transition. If the CSS style provided in `from` does not have a corresponding\n       * style in `to`, the style in `from` is applied immediately, and no animation is run.\n       * If a JavaScript animation is detected then the provided styles will be given in as function parameters into the `animate`\n       * method (or as part of the `options` parameter):\n       *\n       * ```js\n       * ngModule.animation('.my-inline-animation', function() {\n       *   return {\n       *     animate : function(element, from, to, done, options) {\n       *       //animation\n       *       done();\n       *     }\n       *   }\n       * });\n       * ```\n       *\n       * @param {DOMElement} element the element which the CSS styles will be applied to\n       * @param {object} from the from (starting) CSS styles that will be applied to the element and across the animation.\n       * @param {object} to the to (destination) CSS styles that will be applied to the element and across the animation.\n       * @param {string=} className an optional CSS class that will be applied to the element for the duration of the animation. If\n       *    this value is left as empty then a CSS class of `ng-inline-animate` will be applied to the element.\n       *    (Note that if no animation is detected then this value will not be applied to the element.)\n       * @param {object=} options an optional collection of options/styles that will be applied to the element.\n       *   The object can have the following properties:\n       *\n       *   - **addClass** - `{string}` - space-separated CSS classes to add to element\n       *   - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to`\n       *   - **removeClass** - `{string}` - space-separated CSS classes to remove from element\n       *   - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from`\n       *\n       * @return {Promise} the animation callback promise\n       */\n      animate: function(element, from, to, className, options) {\n        options = prepareAnimateOptions(options);\n        options.from = options.from ? extend(options.from, from) : from;\n        options.to   = options.to   ? extend(options.to, to)     : to;\n\n        className = className || 'ng-inline-animate';\n        options.tempClasses = mergeClasses(options.tempClasses, className);\n        return $$animateQueue.push(element, 'animate', options);\n      }\n    };\n  }];\n}];\n\nvar $$AnimateAsyncRunFactoryProvider = /** @this */ function() {\n  this.$get = ['$$rAF', function($$rAF) {\n    var waitQueue = [];\n\n    function waitForTick(fn) {\n      waitQueue.push(fn);\n      if (waitQueue.length > 1) return;\n      $$rAF(function() {\n        for (var i = 0; i < waitQueue.length; i++) {\n          waitQueue[i]();\n        }\n        waitQueue = [];\n      });\n    }\n\n    return function() {\n      var passed = false;\n      waitForTick(function() {\n        passed = true;\n      });\n      return function(callback) {\n        if (passed) {\n          callback();\n        } else {\n          waitForTick(callback);\n        }\n      };\n    };\n  }];\n};\n\nvar $$AnimateRunnerFactoryProvider = /** @this */ function() {\n  this.$get = ['$q', '$sniffer', '$$animateAsyncRun', '$$isDocumentHidden', '$timeout',\n       function($q,   $sniffer,   $$animateAsyncRun,   $$isDocumentHidden,   $timeout) {\n\n    var INITIAL_STATE = 0;\n    var DONE_PENDING_STATE = 1;\n    var DONE_COMPLETE_STATE = 2;\n\n    AnimateRunner.chain = function(chain, callback) {\n      var index = 0;\n\n      next();\n      function next() {\n        if (index === chain.length) {\n          callback(true);\n          return;\n        }\n\n        chain[index](function(response) {\n          if (response === false) {\n            callback(false);\n            return;\n          }\n          index++;\n          next();\n        });\n      }\n    };\n\n    AnimateRunner.all = function(runners, callback) {\n      var count = 0;\n      var status = true;\n      forEach(runners, function(runner) {\n        runner.done(onProgress);\n      });\n\n      function onProgress(response) {\n        status = status && response;\n        if (++count === runners.length) {\n          callback(status);\n        }\n      }\n    };\n\n    function AnimateRunner(host) {\n      this.setHost(host);\n\n      var rafTick = $$animateAsyncRun();\n      var timeoutTick = function(fn) {\n        $timeout(fn, 0, false);\n      };\n\n      this._doneCallbacks = [];\n      this._tick = function(fn) {\n        if ($$isDocumentHidden()) {\n          timeoutTick(fn);\n        } else {\n          rafTick(fn);\n        }\n      };\n      this._state = 0;\n    }\n\n    AnimateRunner.prototype = {\n      setHost: function(host) {\n        this.host = host || {};\n      },\n\n      done: function(fn) {\n        if (this._state === DONE_COMPLETE_STATE) {\n          fn();\n        } else {\n          this._doneCallbacks.push(fn);\n        }\n      },\n\n      progress: noop,\n\n      getPromise: function() {\n        if (!this.promise) {\n          var self = this;\n          this.promise = $q(function(resolve, reject) {\n            self.done(function(status) {\n              if (status === false) {\n                reject();\n              } else {\n                resolve();\n              }\n            });\n          });\n        }\n        return this.promise;\n      },\n\n      then: function(resolveHandler, rejectHandler) {\n        return this.getPromise().then(resolveHandler, rejectHandler);\n      },\n\n      'catch': function(handler) {\n        return this.getPromise()['catch'](handler);\n      },\n\n      'finally': function(handler) {\n        return this.getPromise()['finally'](handler);\n      },\n\n      pause: function() {\n        if (this.host.pause) {\n          this.host.pause();\n        }\n      },\n\n      resume: function() {\n        if (this.host.resume) {\n          this.host.resume();\n        }\n      },\n\n      end: function() {\n        if (this.host.end) {\n          this.host.end();\n        }\n        this._resolve(true);\n      },\n\n      cancel: function() {\n        if (this.host.cancel) {\n          this.host.cancel();\n        }\n        this._resolve(false);\n      },\n\n      complete: function(response) {\n        var self = this;\n        if (self._state === INITIAL_STATE) {\n          self._state = DONE_PENDING_STATE;\n          self._tick(function() {\n            self._resolve(response);\n          });\n        }\n      },\n\n      _resolve: function(response) {\n        if (this._state !== DONE_COMPLETE_STATE) {\n          forEach(this._doneCallbacks, function(fn) {\n            fn(response);\n          });\n          this._doneCallbacks.length = 0;\n          this._state = DONE_COMPLETE_STATE;\n        }\n      }\n    };\n\n    return AnimateRunner;\n  }];\n};\n\n/* exported $CoreAnimateCssProvider */\n\n/**\n * @ngdoc service\n * @name $animateCss\n * @kind object\n * @this\n *\n * @description\n * This is the core version of `$animateCss`. By default, only when the `ngAnimate` is included,\n * then the `$animateCss` service will actually perform animations.\n *\n * Click here {@link ngAnimate.$animateCss to read the documentation for $animateCss}.\n */\nvar $CoreAnimateCssProvider = function() {\n  this.$get = ['$$rAF', '$q', '$$AnimateRunner', function($$rAF, $q, $$AnimateRunner) {\n\n    return function(element, initialOptions) {\n      // all of the animation functions should create\n      // a copy of the options data, however, if a\n      // parent service has already created a copy then\n      // we should stick to using that\n      var options = initialOptions || {};\n      if (!options.$$prepared) {\n        options = copy(options);\n      }\n\n      // there is no point in applying the styles since\n      // there is no animation that goes on at all in\n      // this version of $animateCss.\n      if (options.cleanupStyles) {\n        options.from = options.to = null;\n      }\n\n      if (options.from) {\n        element.css(options.from);\n        options.from = null;\n      }\n\n      var closed, runner = new $$AnimateRunner();\n      return {\n        start: run,\n        end: run\n      };\n\n      function run() {\n        $$rAF(function() {\n          applyAnimationContents();\n          if (!closed) {\n            runner.complete();\n          }\n          closed = true;\n        });\n        return runner;\n      }\n\n      function applyAnimationContents() {\n        if (options.addClass) {\n          element.addClass(options.addClass);\n          options.addClass = null;\n        }\n        if (options.removeClass) {\n          element.removeClass(options.removeClass);\n          options.removeClass = null;\n        }\n        if (options.to) {\n          element.css(options.to);\n          options.to = null;\n        }\n      }\n    };\n  }];\n};\n\n/* global stripHash: true */\n\n/**\n * ! This is a private undocumented service !\n *\n * @name $browser\n * @requires $log\n * @description\n * This object has two goals:\n *\n * - hide all the global state in the browser caused by the window object\n * - abstract away all the browser specific features and inconsistencies\n *\n * For tests we provide {@link ngMock.$browser mock implementation} of the `$browser`\n * service, which can be used for convenient testing of the application without the interaction with\n * the real browser apis.\n */\n/**\n * @param {object} window The global window object.\n * @param {object} document jQuery wrapped document.\n * @param {object} $log window.console or an object with the same interface.\n * @param {object} $sniffer $sniffer service\n */\nfunction Browser(window, document, $log, $sniffer) {\n  var self = this,\n      location = window.location,\n      history = window.history,\n      setTimeout = window.setTimeout,\n      clearTimeout = window.clearTimeout,\n      pendingDeferIds = {};\n\n  self.isMock = false;\n\n  var outstandingRequestCount = 0;\n  var outstandingRequestCallbacks = [];\n\n  // TODO(vojta): remove this temporary api\n  self.$$completeOutstandingRequest = completeOutstandingRequest;\n  self.$$incOutstandingRequestCount = function() { outstandingRequestCount++; };\n\n  /**\n   * Executes the `fn` function(supports currying) and decrements the `outstandingRequestCallbacks`\n   * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed.\n   */\n  function completeOutstandingRequest(fn) {\n    try {\n      fn.apply(null, sliceArgs(arguments, 1));\n    } finally {\n      outstandingRequestCount--;\n      if (outstandingRequestCount === 0) {\n        while (outstandingRequestCallbacks.length) {\n          try {\n            outstandingRequestCallbacks.pop()();\n          } catch (e) {\n            $log.error(e);\n          }\n        }\n      }\n    }\n  }\n\n  function getHash(url) {\n    var index = url.indexOf('#');\n    return index === -1 ? '' : url.substr(index);\n  }\n\n  /**\n   * @private\n   * Note: this method is used only by scenario runner\n   * TODO(vojta): prefix this method with $$ ?\n   * @param {function()} callback Function that will be called when no outstanding request\n   */\n  self.notifyWhenNoOutstandingRequests = function(callback) {\n    if (outstandingRequestCount === 0) {\n      callback();\n    } else {\n      outstandingRequestCallbacks.push(callback);\n    }\n  };\n\n  //////////////////////////////////////////////////////////////\n  // URL API\n  //////////////////////////////////////////////////////////////\n\n  var cachedState, lastHistoryState,\n      lastBrowserUrl = location.href,\n      baseElement = document.find('base'),\n      pendingLocation = null,\n      getCurrentState = !$sniffer.history ? noop : function getCurrentState() {\n        try {\n          return history.state;\n        } catch (e) {\n          // MSIE can reportedly throw when there is no state (UNCONFIRMED).\n        }\n      };\n\n  cacheState();\n\n  /**\n   * @name $browser#url\n   *\n   * @description\n   * GETTER:\n   * Without any argument, this method just returns current value of location.href.\n   *\n   * SETTER:\n   * With at least one argument, this method sets url to new value.\n   * If html5 history api supported, pushState/replaceState is used, otherwise\n   * location.href/location.replace is used.\n   * Returns its own instance to allow chaining\n   *\n   * NOTE: this api is intended for use only by the $location service. Please use the\n   * {@link ng.$location $location service} to change url.\n   *\n   * @param {string} url New url (when used as setter)\n   * @param {boolean=} replace Should new url replace current history record?\n   * @param {object=} state object to use with pushState/replaceState\n   */\n  self.url = function(url, replace, state) {\n    // In modern browsers `history.state` is `null` by default; treating it separately\n    // from `undefined` would cause `$browser.url('/foo')` to change `history.state`\n    // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.\n    if (isUndefined(state)) {\n      state = null;\n    }\n\n    // Android Browser BFCache causes location, history reference to become stale.\n    if (location !== window.location) location = window.location;\n    if (history !== window.history) history = window.history;\n\n    // setter\n    if (url) {\n      var sameState = lastHistoryState === state;\n\n      // Don't change anything if previous and current URLs and states match. This also prevents\n      // IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.\n      // See https://github.com/angular/angular.js/commit/ffb2701\n      if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {\n        return self;\n      }\n      var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);\n      lastBrowserUrl = url;\n      lastHistoryState = state;\n      // Don't use history API if only the hash changed\n      // due to a bug in IE10/IE11 which leads\n      // to not firing a `hashchange` nor `popstate` event\n      // in some cases (see #9143).\n      if ($sniffer.history && (!sameBase || !sameState)) {\n        history[replace ? 'replaceState' : 'pushState'](state, '', url);\n        cacheState();\n      } else {\n        if (!sameBase) {\n          pendingLocation = url;\n        }\n        if (replace) {\n          location.replace(url);\n        } else if (!sameBase) {\n          location.href = url;\n        } else {\n          location.hash = getHash(url);\n        }\n        if (location.href !== url) {\n          pendingLocation = url;\n        }\n      }\n      if (pendingLocation) {\n        pendingLocation = url;\n      }\n      return self;\n    // getter\n    } else {\n      // - pendingLocation is needed as browsers don't allow to read out\n      //   the new location.href if a reload happened or if there is a bug like in iOS 9 (see\n      //   https://openradar.appspot.com/22186109).\n      // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172\n      return pendingLocation || location.href.replace(/%27/g,'\\'');\n    }\n  };\n\n  /**\n   * @name $browser#state\n   *\n   * @description\n   * This method is a getter.\n   *\n   * Return history.state or null if history.state is undefined.\n   *\n   * @returns {object} state\n   */\n  self.state = function() {\n    return cachedState;\n  };\n\n  var urlChangeListeners = [],\n      urlChangeInit = false;\n\n  function cacheStateAndFireUrlChange() {\n    pendingLocation = null;\n    fireStateOrUrlChange();\n  }\n\n  // This variable should be used *only* inside the cacheState function.\n  var lastCachedState = null;\n  function cacheState() {\n    // This should be the only place in $browser where `history.state` is read.\n    cachedState = getCurrentState();\n    cachedState = isUndefined(cachedState) ? null : cachedState;\n\n    // Prevent callbacks fo fire twice if both hashchange & popstate were fired.\n    if (equals(cachedState, lastCachedState)) {\n      cachedState = lastCachedState;\n    }\n\n    lastCachedState = cachedState;\n    lastHistoryState = cachedState;\n  }\n\n  function fireStateOrUrlChange() {\n    var prevLastHistoryState = lastHistoryState;\n    cacheState();\n\n    if (lastBrowserUrl === self.url() && prevLastHistoryState === cachedState) {\n      return;\n    }\n\n    lastBrowserUrl = self.url();\n    lastHistoryState = cachedState;\n    forEach(urlChangeListeners, function(listener) {\n      listener(self.url(), cachedState);\n    });\n  }\n\n  /**\n   * @name $browser#onUrlChange\n   *\n   * @description\n   * Register callback function that will be called, when url changes.\n   *\n   * It's only called when the url is changed from outside of angular:\n   * - user types different url into address bar\n   * - user clicks on history (forward/back) button\n   * - user clicks on a link\n   *\n   * It's not called when url is changed by $browser.url() method\n   *\n   * The listener gets called with new url as parameter.\n   *\n   * NOTE: this api is intended for use only by the $location service. Please use the\n   * {@link ng.$location $location service} to monitor url changes in angular apps.\n   *\n   * @param {function(string)} listener Listener function to be called when url changes.\n   * @return {function(string)} Returns the registered listener fn - handy if the fn is anonymous.\n   */\n  self.onUrlChange = function(callback) {\n    // TODO(vojta): refactor to use node's syntax for events\n    if (!urlChangeInit) {\n      // We listen on both (hashchange/popstate) when available, as some browsers don't\n      // fire popstate when user changes the address bar and don't fire hashchange when url\n      // changed by push/replaceState\n\n      // html5 history api - popstate event\n      if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange);\n      // hashchange event\n      jqLite(window).on('hashchange', cacheStateAndFireUrlChange);\n\n      urlChangeInit = true;\n    }\n\n    urlChangeListeners.push(callback);\n    return callback;\n  };\n\n  /**\n   * @private\n   * Remove popstate and hashchange handler from window.\n   *\n   * NOTE: this api is intended for use only by $rootScope.\n   */\n  self.$$applicationDestroyed = function() {\n    jqLite(window).off('hashchange popstate', cacheStateAndFireUrlChange);\n  };\n\n  /**\n   * Checks whether the url has changed outside of Angular.\n   * Needs to be exported to be able to check for changes that have been done in sync,\n   * as hashchange/popstate events fire in async.\n   */\n  self.$$checkUrlChange = fireStateOrUrlChange;\n\n  //////////////////////////////////////////////////////////////\n  // Misc API\n  //////////////////////////////////////////////////////////////\n\n  /**\n   * @name $browser#baseHref\n   *\n   * @description\n   * Returns current <base href>\n   * (always relative - without domain)\n   *\n   * @returns {string} The current base href\n   */\n  self.baseHref = function() {\n    var href = baseElement.attr('href');\n    return href ? href.replace(/^(https?:)?\\/\\/[^/]*/, '') : '';\n  };\n\n  /**\n   * @name $browser#defer\n   * @param {function()} fn A function, who's execution should be deferred.\n   * @param {number=} [delay=0] of milliseconds to defer the function execution.\n   * @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`.\n   *\n   * @description\n   * Executes a fn asynchronously via `setTimeout(fn, delay)`.\n   *\n   * Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using\n   * `setTimeout` in tests, the fns are queued in an array, which can be programmatically flushed\n   * via `$browser.defer.flush()`.\n   *\n   */\n  self.defer = function(fn, delay) {\n    var timeoutId;\n    outstandingRequestCount++;\n    timeoutId = setTimeout(function() {\n      delete pendingDeferIds[timeoutId];\n      completeOutstandingRequest(fn);\n    }, delay || 0);\n    pendingDeferIds[timeoutId] = true;\n    return timeoutId;\n  };\n\n\n  /**\n   * @name $browser#defer.cancel\n   *\n   * @description\n   * Cancels a deferred task identified with `deferId`.\n   *\n   * @param {*} deferId Token returned by the `$browser.defer` function.\n   * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully\n   *                    canceled.\n   */\n  self.defer.cancel = function(deferId) {\n    if (pendingDeferIds[deferId]) {\n      delete pendingDeferIds[deferId];\n      clearTimeout(deferId);\n      completeOutstandingRequest(noop);\n      return true;\n    }\n    return false;\n  };\n\n}\n\n/** @this */\nfunction $BrowserProvider() {\n  this.$get = ['$window', '$log', '$sniffer', '$document',\n      function($window, $log, $sniffer, $document) {\n        return new Browser($window, $document, $log, $sniffer);\n      }];\n}\n\n/**\n * @ngdoc service\n * @name $cacheFactory\n * @this\n *\n * @description\n * Factory that constructs {@link $cacheFactory.Cache Cache} objects and gives access to\n * them.\n *\n * ```js\n *\n *  var cache = $cacheFactory('cacheId');\n *  expect($cacheFactory.get('cacheId')).toBe(cache);\n *  expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();\n *\n *  cache.put(\"key\", \"value\");\n *  cache.put(\"another key\", \"another value\");\n *\n *  // We've specified no options on creation\n *  expect(cache.info()).toEqual({id: 'cacheId', size: 2});\n *\n * ```\n *\n *\n * @param {string} cacheId Name or id of the newly created cache.\n * @param {object=} options Options object that specifies the cache behavior. Properties:\n *\n *   - `{number=}` `capacity` — turns the cache into LRU cache.\n *\n * @returns {object} Newly created cache object with the following set of methods:\n *\n * - `{object}` `info()` — Returns id, size, and options of cache.\n * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns\n *   it.\n * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.\n * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.\n * - `{void}` `removeAll()` — Removes all cached values.\n * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory.\n *\n * @example\n   <example module=\"cacheExampleApp\" name=\"cache-factory\">\n     <file name=\"index.html\">\n       <div ng-controller=\"CacheController\">\n         <input ng-model=\"newCacheKey\" placeholder=\"Key\">\n         <input ng-model=\"newCacheValue\" placeholder=\"Value\">\n         <button ng-click=\"put(newCacheKey, newCacheValue)\">Cache</button>\n\n         <p ng-if=\"keys.length\">Cached Values</p>\n         <div ng-repeat=\"key in keys\">\n           <span ng-bind=\"key\"></span>\n           <span>: </span>\n           <b ng-bind=\"cache.get(key)\"></b>\n         </div>\n\n         <p>Cache Info</p>\n         <div ng-repeat=\"(key, value) in cache.info()\">\n           <span ng-bind=\"key\"></span>\n           <span>: </span>\n           <b ng-bind=\"value\"></b>\n         </div>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('cacheExampleApp', []).\n         controller('CacheController', ['$scope', '$cacheFactory', function($scope, $cacheFactory) {\n           $scope.keys = [];\n           $scope.cache = $cacheFactory('cacheId');\n           $scope.put = function(key, value) {\n             if (angular.isUndefined($scope.cache.get(key))) {\n               $scope.keys.push(key);\n             }\n             $scope.cache.put(key, angular.isUndefined(value) ? null : value);\n           };\n         }]);\n     </file>\n     <file name=\"style.css\">\n       p {\n         margin: 10px 0 3px;\n       }\n     </file>\n   </example>\n */\nfunction $CacheFactoryProvider() {\n\n  this.$get = function() {\n    var caches = {};\n\n    function cacheFactory(cacheId, options) {\n      if (cacheId in caches) {\n        throw minErr('$cacheFactory')('iid', 'CacheId \\'{0}\\' is already taken!', cacheId);\n      }\n\n      var size = 0,\n          stats = extend({}, options, {id: cacheId}),\n          data = createMap(),\n          capacity = (options && options.capacity) || Number.MAX_VALUE,\n          lruHash = createMap(),\n          freshEnd = null,\n          staleEnd = null;\n\n      /**\n       * @ngdoc type\n       * @name $cacheFactory.Cache\n       *\n       * @description\n       * A cache object used to store and retrieve data, primarily used by\n       * {@link $http $http} and the {@link ng.directive:script script} directive to cache\n       * templates and other data.\n       *\n       * ```js\n       *  angular.module('superCache')\n       *    .factory('superCache', ['$cacheFactory', function($cacheFactory) {\n       *      return $cacheFactory('super-cache');\n       *    }]);\n       * ```\n       *\n       * Example test:\n       *\n       * ```js\n       *  it('should behave like a cache', inject(function(superCache) {\n       *    superCache.put('key', 'value');\n       *    superCache.put('another key', 'another value');\n       *\n       *    expect(superCache.info()).toEqual({\n       *      id: 'super-cache',\n       *      size: 2\n       *    });\n       *\n       *    superCache.remove('another key');\n       *    expect(superCache.get('another key')).toBeUndefined();\n       *\n       *    superCache.removeAll();\n       *    expect(superCache.info()).toEqual({\n       *      id: 'super-cache',\n       *      size: 0\n       *    });\n       *  }));\n       * ```\n       */\n      return (caches[cacheId] = {\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#put\n         * @kind function\n         *\n         * @description\n         * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be\n         * retrieved later, and incrementing the size of the cache if the key was not already\n         * present in the cache. If behaving like an LRU cache, it will also remove stale\n         * entries from the set.\n         *\n         * It will not insert undefined values into the cache.\n         *\n         * @param {string} key the key under which the cached data is stored.\n         * @param {*} value the value to store alongside the key. If it is undefined, the key\n         *    will not be stored.\n         * @returns {*} the value stored.\n         */\n        put: function(key, value) {\n          if (isUndefined(value)) return;\n          if (capacity < Number.MAX_VALUE) {\n            var lruEntry = lruHash[key] || (lruHash[key] = {key: key});\n\n            refresh(lruEntry);\n          }\n\n          if (!(key in data)) size++;\n          data[key] = value;\n\n          if (size > capacity) {\n            this.remove(staleEnd.key);\n          }\n\n          return value;\n        },\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#get\n         * @kind function\n         *\n         * @description\n         * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object.\n         *\n         * @param {string} key the key of the data to be retrieved\n         * @returns {*} the value stored.\n         */\n        get: function(key) {\n          if (capacity < Number.MAX_VALUE) {\n            var lruEntry = lruHash[key];\n\n            if (!lruEntry) return;\n\n            refresh(lruEntry);\n          }\n\n          return data[key];\n        },\n\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#remove\n         * @kind function\n         *\n         * @description\n         * Removes an entry from the {@link $cacheFactory.Cache Cache} object.\n         *\n         * @param {string} key the key of the entry to be removed\n         */\n        remove: function(key) {\n          if (capacity < Number.MAX_VALUE) {\n            var lruEntry = lruHash[key];\n\n            if (!lruEntry) return;\n\n            if (lruEntry === freshEnd) freshEnd = lruEntry.p;\n            if (lruEntry === staleEnd) staleEnd = lruEntry.n;\n            link(lruEntry.n,lruEntry.p);\n\n            delete lruHash[key];\n          }\n\n          if (!(key in data)) return;\n\n          delete data[key];\n          size--;\n        },\n\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#removeAll\n         * @kind function\n         *\n         * @description\n         * Clears the cache object of any entries.\n         */\n        removeAll: function() {\n          data = createMap();\n          size = 0;\n          lruHash = createMap();\n          freshEnd = staleEnd = null;\n        },\n\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#destroy\n         * @kind function\n         *\n         * @description\n         * Destroys the {@link $cacheFactory.Cache Cache} object entirely,\n         * removing it from the {@link $cacheFactory $cacheFactory} set.\n         */\n        destroy: function() {\n          data = null;\n          stats = null;\n          lruHash = null;\n          delete caches[cacheId];\n        },\n\n\n        /**\n         * @ngdoc method\n         * @name $cacheFactory.Cache#info\n         * @kind function\n         *\n         * @description\n         * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}.\n         *\n         * @returns {object} an object with the following properties:\n         *   <ul>\n         *     <li>**id**: the id of the cache instance</li>\n         *     <li>**size**: the number of entries kept in the cache instance</li>\n         *     <li>**...**: any additional properties from the options object when creating the\n         *       cache.</li>\n         *   </ul>\n         */\n        info: function() {\n          return extend({}, stats, {size: size});\n        }\n      });\n\n\n      /**\n       * makes the `entry` the freshEnd of the LRU linked list\n       */\n      function refresh(entry) {\n        if (entry !== freshEnd) {\n          if (!staleEnd) {\n            staleEnd = entry;\n          } else if (staleEnd === entry) {\n            staleEnd = entry.n;\n          }\n\n          link(entry.n, entry.p);\n          link(entry, freshEnd);\n          freshEnd = entry;\n          freshEnd.n = null;\n        }\n      }\n\n\n      /**\n       * bidirectionally links two entries of the LRU linked list\n       */\n      function link(nextEntry, prevEntry) {\n        if (nextEntry !== prevEntry) {\n          if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify\n          if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify\n        }\n      }\n    }\n\n\n  /**\n   * @ngdoc method\n   * @name $cacheFactory#info\n   *\n   * @description\n   * Get information about all the caches that have been created\n   *\n   * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`\n   */\n    cacheFactory.info = function() {\n      var info = {};\n      forEach(caches, function(cache, cacheId) {\n        info[cacheId] = cache.info();\n      });\n      return info;\n    };\n\n\n  /**\n   * @ngdoc method\n   * @name $cacheFactory#get\n   *\n   * @description\n   * Get access to a cache object by the `cacheId` used when it was created.\n   *\n   * @param {string} cacheId Name or id of a cache to access.\n   * @returns {object} Cache object identified by the cacheId or undefined if no such cache.\n   */\n    cacheFactory.get = function(cacheId) {\n      return caches[cacheId];\n    };\n\n\n    return cacheFactory;\n  };\n}\n\n/**\n * @ngdoc service\n * @name $templateCache\n * @this\n *\n * @description\n * The first time a template is used, it is loaded in the template cache for quick retrieval. You\n * can load templates directly into the cache in a `script` tag, or by consuming the\n * `$templateCache` service directly.\n *\n * Adding via the `script` tag:\n *\n * ```html\n *   <script type=\"text/ng-template\" id=\"templateId.html\">\n *     <p>This is the content of the template</p>\n *   </script>\n * ```\n *\n * **Note:** the `script` tag containing the template does not need to be included in the `head` of\n * the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE,\n * element with ng-app attribute), otherwise the template will be ignored.\n *\n * Adding via the `$templateCache` service:\n *\n * ```js\n * var myApp = angular.module('myApp', []);\n * myApp.run(function($templateCache) {\n *   $templateCache.put('templateId.html', 'This is the content of the template');\n * });\n * ```\n *\n * To retrieve the template later, simply use it in your component:\n * ```js\n * myApp.component('myComponent', {\n *    templateUrl: 'templateId.html'\n * });\n * ```\n *\n * or get it via the `$templateCache` service:\n * ```js\n * $templateCache.get('templateId.html')\n * ```\n *\n * See {@link ng.$cacheFactory $cacheFactory}.\n *\n */\nfunction $TemplateCacheProvider() {\n  this.$get = ['$cacheFactory', function($cacheFactory) {\n    return $cacheFactory('templates');\n  }];\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *     Any commits to this file should be reviewed with security in mind.  *\n *   Changes to this file can potentially create security vulnerabilities. *\n *          An approval from 2 Core members with history of modifying      *\n *                         this file is required.                          *\n *                                                                         *\n *  Does the change somehow allow for arbitrary javascript to be executed? *\n *    Or allows for someone to change the prototype of built-in objects?   *\n *     Or gives undesired access to variables like document or window?    *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE!\n *\n * DOM-related variables:\n *\n * - \"node\" - DOM Node\n * - \"element\" - DOM Element or Node\n * - \"$node\" or \"$element\" - jqLite-wrapped node or element\n *\n *\n * Compiler related stuff:\n *\n * - \"linkFn\" - linking fn of a single directive\n * - \"nodeLinkFn\" - function that aggregates all linking fns for a particular node\n * - \"childLinkFn\" -  function that aggregates all linking fns for child nodes of a particular node\n * - \"compositeLinkFn\" - function that aggregates all linking fns for a compilation root (nodeList)\n */\n\n\n/**\n * @ngdoc service\n * @name $compile\n * @kind function\n *\n * @description\n * Compiles an HTML string or DOM into a template and produces a template function, which\n * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together.\n *\n * The compilation is a process of walking the DOM tree and matching DOM elements to\n * {@link ng.$compileProvider#directive directives}.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** This document is an in-depth reference of all directive options.\n * For a gentle introduction to directives with examples of common use cases,\n * see the {@link guide/directive directive guide}.\n * </div>\n *\n * ## Comprehensive Directive API\n *\n * There are many different options for a directive.\n *\n * The difference resides in the return value of the factory function.\n * You can either return a {@link $compile#directive-definition-object Directive Definition Object (see below)}\n * that defines the directive properties, or just the `postLink` function (all other properties will have\n * the default values).\n *\n * <div class=\"alert alert-success\">\n * **Best Practice:** It's recommended to use the \"directive definition object\" form.\n * </div>\n *\n * Here's an example directive declared with a Directive Definition Object:\n *\n * ```js\n *   var myModule = angular.module(...);\n *\n *   myModule.directive('directiveName', function factory(injectables) {\n *     var directiveDefinitionObject = {\n *       {@link $compile#-priority- priority}: 0,\n *       {@link $compile#-template- template}: '<div></div>', // or // function(tElement, tAttrs) { ... },\n *       // or\n *       // {@link $compile#-templateurl- templateUrl}: 'directive.html', // or // function(tElement, tAttrs) { ... },\n *       {@link $compile#-transclude- transclude}: false,\n *       {@link $compile#-restrict- restrict}: 'A',\n *       {@link $compile#-templatenamespace- templateNamespace}: 'html',\n *       {@link $compile#-scope- scope}: false,\n *       {@link $compile#-controller- controller}: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },\n *       {@link $compile#-controlleras- controllerAs}: 'stringIdentifier',\n *       {@link $compile#-bindtocontroller- bindToController}: false,\n *       {@link $compile#-require- require}: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],\n *       {@link $compile#-multielement- multiElement}: false,\n *       {@link $compile#-compile- compile}: function compile(tElement, tAttrs, transclude) {\n *         return {\n *            {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },\n *            {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }\n *         }\n *         // or\n *         // return function postLink( ... ) { ... }\n *       },\n *       // or\n *       // {@link $compile#-link- link}: {\n *       //  {@link $compile#pre-linking-function pre}: function preLink(scope, iElement, iAttrs, controller) { ... },\n *       //  {@link $compile#post-linking-function post}: function postLink(scope, iElement, iAttrs, controller) { ... }\n *       // }\n *       // or\n *       // {@link $compile#-link- link}: function postLink( ... ) { ... }\n *     };\n *     return directiveDefinitionObject;\n *   });\n * ```\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Any unspecified options will use the default value. You can see the default values below.\n * </div>\n *\n * Therefore the above can be simplified as:\n *\n * ```js\n *   var myModule = angular.module(...);\n *\n *   myModule.directive('directiveName', function factory(injectables) {\n *     var directiveDefinitionObject = {\n *       link: function postLink(scope, iElement, iAttrs) { ... }\n *     };\n *     return directiveDefinitionObject;\n *     // or\n *     // return function postLink(scope, iElement, iAttrs) { ... }\n *   });\n * ```\n *\n * ### Life-cycle hooks\n * Directive controllers can provide the following methods that are called by Angular at points in the life-cycle of the\n * directive:\n * * `$onInit()` - Called on each controller after all the controllers on an element have been constructed and\n *   had their bindings initialized (and before the pre &amp; post linking functions for the directives on\n *   this element). This is a good place to put initialization code for your controller.\n * * `$onChanges(changesObj)` - Called whenever one-way (`<`) or interpolation (`@`) bindings are updated. The\n *   `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an\n *   object of the form `{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a\n *   component such as cloning the bound value to prevent accidental mutation of the outer value. Note that this will\n *   also be called when your bindings are initialized.\n * * `$doCheck()` - Called on each turn of the digest cycle. Provides an opportunity to detect and act on\n *   changes. Any actions that you wish to take in response to the changes that you detect must be\n *   invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook\n *   could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not\n *   be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;\n *   if detecting changes, you must store the previous value(s) for comparison to the current values.\n * * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing\n *   external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in\n *   the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent\n *   components will have their `$onDestroy()` hook called before child components.\n * * `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link\n *   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.\n *   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since\n *   they are waiting for their template to load asynchronously and their own compilation and linking has been\n *   suspended until that occurs.\n *\n * #### Comparison with Angular 2 life-cycle hooks\n * Angular 2 also uses life-cycle hooks for its components. While the Angular 1 life-cycle hooks are similar there are\n * some differences that you should be aware of, especially when it comes to moving your code from Angular 1 to Angular 2:\n *\n * * Angular 1 hooks are prefixed with `$`, such as `$onInit`. Angular 2 hooks are prefixed with `ng`, such as `ngOnInit`.\n * * Angular 1 hooks can be defined on the controller prototype or added to the controller inside its constructor.\n *   In Angular 2 you can only define hooks on the prototype of the Component class.\n * * Due to the differences in change-detection, you may get many more calls to `$doCheck` in Angular 1 than you would to\n *   `ngDoCheck` in Angular 2\n * * Changes to the model inside `$doCheck` will trigger new turns of the digest loop, which will cause the changes to be\n *   propagated throughout the application.\n *   Angular 2 does not allow the `ngDoCheck` hook to trigger a change outside of the component. It will either throw an\n *   error or do nothing depending upon the state of `enableProdMode()`.\n *\n * #### Life-cycle hook examples\n *\n * This example shows how you can check for mutations to a Date object even though the identity of the object\n * has not changed.\n *\n * <example name=\"doCheckDateExample\" module=\"do-check-module\">\n *   <file name=\"app.js\">\n *     angular.module('do-check-module', [])\n *       .component('app', {\n *         template:\n *           'Month: <input ng-model=\"$ctrl.month\" ng-change=\"$ctrl.updateDate()\">' +\n *           'Date: {{ $ctrl.date }}' +\n *           '<test date=\"$ctrl.date\"></test>',\n *         controller: function() {\n *           this.date = new Date();\n *           this.month = this.date.getMonth();\n *           this.updateDate = function() {\n *             this.date.setMonth(this.month);\n *           };\n *         }\n *       })\n *       .component('test', {\n *         bindings: { date: '<' },\n *         template:\n *           '<pre>{{ $ctrl.log | json }}</pre>',\n *         controller: function() {\n *           var previousValue;\n *           this.log = [];\n *           this.$doCheck = function() {\n *             var currentValue = this.date && this.date.valueOf();\n *             if (previousValue !== currentValue) {\n *               this.log.push('doCheck: date mutated: ' + this.date);\n *               previousValue = currentValue;\n *             }\n *           };\n *         }\n *       });\n *   </file>\n *   <file name=\"index.html\">\n *     <app></app>\n *   </file>\n * </example>\n *\n * This example show how you might use `$doCheck` to trigger changes in your component's inputs even if the\n * actual identity of the component doesn't change. (Be aware that cloning and deep equality checks on large\n * arrays or objects can have a negative impact on your application performance)\n *\n * <example name=\"doCheckArrayExample\" module=\"do-check-module\">\n *   <file name=\"index.html\">\n *     <div ng-init=\"items = []\">\n *       <button ng-click=\"items.push(items.length)\">Add Item</button>\n *       <button ng-click=\"items = []\">Reset Items</button>\n *       <pre>{{ items }}</pre>\n *       <test items=\"items\"></test>\n *     </div>\n *   </file>\n *   <file name=\"app.js\">\n *      angular.module('do-check-module', [])\n *        .component('test', {\n *          bindings: { items: '<' },\n *          template:\n *            '<pre>{{ $ctrl.log | json }}</pre>',\n *          controller: function() {\n *            this.log = [];\n *\n *            this.$doCheck = function() {\n *              if (this.items_ref !== this.items) {\n *                this.log.push('doCheck: items changed');\n *                this.items_ref = this.items;\n *              }\n *              if (!angular.equals(this.items_clone, this.items)) {\n *                this.log.push('doCheck: items mutated');\n *                this.items_clone = angular.copy(this.items);\n *              }\n *            };\n *          }\n *        });\n *   </file>\n * </example>\n *\n *\n * ### Directive Definition Object\n *\n * The directive definition object provides instructions to the {@link ng.$compile\n * compiler}. The attributes are:\n *\n * #### `multiElement`\n * When this property is set to true (default is `false`), the HTML compiler will collect DOM nodes between\n * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them\n * together as the directive elements. It is recommended that this feature be used on directives\n * which are not strictly behavioral (such as {@link ngClick}), and which\n * do not manipulate or replace child nodes (such as {@link ngInclude}).\n *\n * #### `priority`\n * When there are multiple directives defined on a single DOM element, sometimes it\n * is necessary to specify the order in which the directives are applied. The `priority` is used\n * to sort the directives before their `compile` functions get called. Priority is defined as a\n * number. Directives with greater numerical `priority` are compiled first. Pre-link functions\n * are also run in priority order, but post-link functions are run in reverse order. The order\n * of directives with the same priority is undefined. The default priority is `0`.\n *\n * #### `terminal`\n * If set to true then the current `priority` will be the last set of directives\n * which will execute (any directives at the current priority will still execute\n * as the order of execution on same `priority` is undefined). Note that expressions\n * and other directives used in the directive's template will also be excluded from execution.\n *\n * #### `scope`\n * The scope property can be `false`, `true`, or an object:\n *\n * * **`false` (default):** No scope will be created for the directive. The directive will use its\n * parent's scope.\n *\n * * **`true`:** A new child scope that prototypically inherits from its parent will be created for\n * the directive's element. If multiple directives on the same element request a new scope,\n * only one new scope is created.\n *\n * * **`{...}` (an object hash):** A new \"isolate\" scope is created for the directive's template.\n * The 'isolate' scope differs from normal scope in that it does not prototypically\n * inherit from its parent scope. This is useful when creating reusable components, which should not\n * accidentally read or modify data in the parent scope. Note that an isolate scope\n * directive without a `template` or `templateUrl` will not apply the isolate scope\n * to its children elements.\n *\n * The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the\n * directive's element. These local properties are useful for aliasing values for templates. The keys in\n * the object hash map to the name of the property on the isolate scope; the values define how the property\n * is bound to the parent scope, via matching attributes on the directive's element:\n *\n * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is\n *   always a string since DOM attributes are strings. If no `attr` name is specified then the\n *   attribute name is assumed to be the same as the local name. Given `<my-component\n *   my-attr=\"hello {{name}}\">` and the isolate scope definition `scope: { localName:'@myAttr' }`,\n *   the directive's scope property `localName` will reflect the interpolated value of `hello\n *   {{name}}`. As the `name` attribute changes so will the `localName` property on the directive's\n *   scope. The `name` is read from the parent scope (not the directive's scope).\n *\n * * `=` or `=attr` - set up a bidirectional binding between a local scope property and an expression\n *   passed via the attribute `attr`. The expression is evaluated in the context of the parent scope.\n *   If no `attr` name is specified then the attribute name is assumed to be the same as the local\n *   name. Given `<my-component my-attr=\"parentModel\">` and the isolate scope definition `scope: {\n *   localModel: '=myAttr' }`, the property `localModel` on the directive's scope will reflect the\n *   value of `parentModel` on the parent scope. Changes to `parentModel` will be reflected in\n *   `localModel` and vice versa. Optional attributes should be marked as such with a question mark:\n *   `=?` or `=?attr`. If the binding expression is non-assignable, or if the attribute isn't\n *   optional and doesn't exist, an exception ({@link error/$compile/nonassign `$compile:nonassign`})\n *   will be thrown upon discovering changes to the local value, since it will be impossible to sync\n *   them back to the parent scope. By default, the {@link ng.$rootScope.Scope#$watch `$watch`}\n *   method is used for tracking changes, and the equality check is based on object identity.\n *   However, if an object literal or an array literal is passed as the binding expression, the\n *   equality check is done by value (using the {@link angular.equals} function). It's also possible\n *   to watch the evaluated value shallowly with {@link ng.$rootScope.Scope#$watchCollection\n *   `$watchCollection`}: use `=*` or `=*attr` (`=*?` or `=*?attr` if the attribute is optional).\n *\n  * * `<` or `<attr` - set up a one-way (one-directional) binding between a local scope property and an\n *   expression passed via the attribute `attr`. The expression is evaluated in the context of the\n *   parent scope. If no `attr` name is specified then the attribute name is assumed to be the same as the\n *   local name. You can also make the binding optional by adding `?`: `<?` or `<?attr`.\n *\n *   For example, given `<my-component my-attr=\"parentModel\">` and directive definition of\n *   `scope: { localModel:'<myAttr' }`, then the isolated scope property `localModel` will reflect the\n *   value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected\n *   in `localModel`, but changes in `localModel` will not reflect in `parentModel`. There are however\n *   two caveats:\n *     1. one-way binding does not copy the value from the parent to the isolate scope, it simply\n *     sets the same value. That means if your bound value is an object, changes to its properties\n *     in the isolated scope will be reflected in the parent scope (because both reference the same object).\n *     2. one-way binding watches changes to the **identity** of the parent value. That means the\n *     {@link ng.$rootScope.Scope#$watch `$watch`} on the parent value only fires if the reference\n *     to the value has changed. In most cases, this should not be of concern, but can be important\n *     to know if you one-way bind to an object, and then replace that object in the isolated scope.\n *     If you now change a property of the object in your parent scope, the change will not be\n *     propagated to the isolated scope, because the identity of the object on the parent scope\n *     has not changed. Instead you must assign a new object.\n *\n *   One-way binding is useful if you do not plan to propagate changes to your isolated scope bindings\n *   back to the parent. However, it does not make this completely impossible.\n *\n * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope. If\n *   no `attr` name is specified then the attribute name is assumed to be the same as the local name.\n *   Given `<my-component my-attr=\"count = count + value\">` and the isolate scope definition `scope: {\n *   localFn:'&myAttr' }`, the isolate scope property `localFn` will point to a function wrapper for\n *   the `count = count + value` expression. Often it's desirable to pass data from the isolated scope\n *   via an expression to the parent scope. This can be done by passing a map of local variable names\n *   and values into the expression wrapper fn. For example, if the expression is `increment(amount)`\n *   then we can specify the amount value by calling the `localFn` as `localFn({amount: 22})`.\n *\n * In general it's possible to apply more than one directive to one element, but there might be limitations\n * depending on the type of scope required by the directives. The following points will help explain these limitations.\n * For simplicity only two directives are taken into account, but it is also applicable for several directives:\n *\n * * **no scope** + **no scope** => Two directives which don't require their own scope will use their parent's scope\n * * **child scope** + **no scope** =>  Both directives will share one single child scope\n * * **child scope** + **child scope** =>  Both directives will share one single child scope\n * * **isolated scope** + **no scope** =>  The isolated directive will use it's own created isolated scope. The other directive will use\n * its parent's scope\n * * **isolated scope** + **child scope** =>  **Won't work!** Only one scope can be related to one element. Therefore these directives cannot\n * be applied to the same element.\n * * **isolated scope** + **isolated scope**  =>  **Won't work!** Only one scope can be related to one element. Therefore these directives\n * cannot be applied to the same element.\n *\n *\n * #### `bindToController`\n * This property is used to bind scope properties directly to the controller. It can be either\n * `true` or an object hash with the same format as the `scope` property.\n *\n * When an isolate scope is used for a directive (see above), `bindToController: true` will\n * allow a component to have its properties bound to the controller, rather than to scope.\n *\n * After the controller is instantiated, the initial values of the isolate scope bindings will be bound to the controller\n * properties. You can access these bindings once they have been initialized by providing a controller method called\n * `$onInit`, which is called after all the controllers on an element have been constructed and had their bindings\n * initialized.\n *\n * <div class=\"alert alert-warning\">\n * **Deprecation warning:** although bindings for non-ES6 class controllers are currently\n * bound to `this` before the controller constructor is called, this use is now deprecated. Please place initialization\n * code that relies upon bindings inside a `$onInit` method on the controller, instead.\n * </div>\n *\n * It is also possible to set `bindToController` to an object hash with the same format as the `scope` property.\n * This will set up the scope bindings to the controller directly. Note that `scope` can still be used\n * to define which kind of scope is created. By default, no scope is created. Use `scope: {}` to create an isolate\n * scope (useful for component directives).\n *\n * If both `bindToController` and `scope` are defined and have object hashes, `bindToController` overrides `scope`.\n *\n *\n * #### `controller`\n * Controller constructor function. The controller is instantiated before the\n * pre-linking phase and can be accessed by other directives (see\n * `require` attribute). This allows the directives to communicate with each other and augment\n * each other's behavior. The controller is injectable (and supports bracket notation) with the following locals:\n *\n * * `$scope` - Current scope associated with the element\n * * `$element` - Current element\n * * `$attrs` - Current attributes object for the element\n * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:\n *   `function([scope], cloneLinkingFn, futureParentElement, slotName)`:\n *    * `scope`: (optional) override the scope.\n *    * `cloneLinkingFn`: (optional) argument to create clones of the original transcluded content.\n *    * `futureParentElement` (optional):\n *        * defines the parent to which the `cloneLinkingFn` will add the cloned elements.\n *        * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.\n *        * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)\n *          and when the `cloneLinkingFn` is passed,\n *          as those elements need to created and cloned in a special way when they are defined outside their\n *          usual containers (e.g. like `<svg>`).\n *        * See also the `directive.templateNamespace` property.\n *    * `slotName`: (optional) the name of the slot to transclude. If falsy (e.g. `null`, `undefined` or `''`)\n *      then the default transclusion is provided.\n *    The `$transclude` function also has a method on it, `$transclude.isSlotFilled(slotName)`, which returns\n *    `true` if the specified slot contains content (i.e. one or more DOM nodes).\n *\n * #### `require`\n * Require another directive and inject its controller as the fourth argument to the linking function. The\n * `require` property can be a string, an array or an object:\n * * a **string** containing the name of the directive to pass to the linking function\n * * an **array** containing the names of directives to pass to the linking function. The argument passed to the\n * linking function will be an array of controllers in the same order as the names in the `require` property\n * * an **object** whose property values are the names of the directives to pass to the linking function. The argument\n * passed to the linking function will also be an object with matching keys, whose values will hold the corresponding\n * controllers.\n *\n * If the `require` property is an object and `bindToController` is truthy, then the required controllers are\n * bound to the controller using the keys of the `require` property. This binding occurs after all the controllers\n * have been constructed but before `$onInit` is called.\n * If the name of the required controller is the same as the local name (the key), the name can be\n * omitted. For example, `{parentDir: '^^'}` is equivalent to `{parentDir: '^^parentDir'}`.\n * See the {@link $compileProvider#component} helper for an example of how this can be used.\n * If no such required directive(s) can be found, or if the directive does not have a controller, then an error is\n * raised (unless no link function is specified and the required controllers are not being bound to the directive\n * controller, in which case error checking is skipped). The name can be prefixed with:\n *\n * * (no prefix) - Locate the required controller on the current element. Throw an error if not found.\n * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.\n * * `^` - Locate the required controller by searching the element and its parents. Throw an error if not found.\n * * `^^` - Locate the required controller by searching the element's parents. Throw an error if not found.\n * * `?^` - Attempt to locate the required controller by searching the element and its parents or pass\n *   `null` to the `link` fn if not found.\n * * `?^^` - Attempt to locate the required controller by searching the element's parents, or pass\n *   `null` to the `link` fn if not found.\n *\n *\n * #### `controllerAs`\n * Identifier name for a reference to the controller in the directive's scope.\n * This allows the controller to be referenced from the directive template. This is especially\n * useful when a directive is used as component, i.e. with an `isolate` scope. It's also possible\n * to use it in a directive without an `isolate` / `new` scope, but you need to be aware that the\n * `controllerAs` reference might overwrite a property that already exists on the parent scope.\n *\n *\n * #### `restrict`\n * String of subset of `EACM` which restricts the directive to a specific directive\n * declaration style. If omitted, the defaults (elements and attributes) are used.\n *\n * * `E` - Element name (default): `<my-directive></my-directive>`\n * * `A` - Attribute (default): `<div my-directive=\"exp\"></div>`\n * * `C` - Class: `<div class=\"my-directive: exp;\"></div>`\n * * `M` - Comment: `<!-- directive: my-directive exp -->`\n *\n *\n * #### `templateNamespace`\n * String representing the document type used by the markup in the template.\n * AngularJS needs this information as those elements need to be created and cloned\n * in a special way when they are defined outside their usual containers like `<svg>` and `<math>`.\n *\n * * `html` - All root nodes in the template are HTML. Root nodes may also be\n *   top-level elements such as `<svg>` or `<math>`.\n * * `svg` - The root nodes in the template are SVG elements (excluding `<math>`).\n * * `math` - The root nodes in the template are MathML elements (excluding `<svg>`).\n *\n * If no `templateNamespace` is specified, then the namespace is considered to be `html`.\n *\n * #### `template`\n * HTML markup that may:\n * * Replace the contents of the directive's element (default).\n * * Replace the directive's element itself (if `replace` is true - DEPRECATED).\n * * Wrap the contents of the directive's element (if `transclude` is true).\n *\n * Value may be:\n *\n * * A string. For example `<div red-on-hover>{{delete_str}}</div>`.\n * * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile`\n *   function api below) and returns a string value.\n *\n *\n * #### `templateUrl`\n * This is similar to `template` but the template is loaded from the specified URL, asynchronously.\n *\n * Because template loading is asynchronous the compiler will suspend compilation of directives on that element\n * for later when the template has been resolved.  In the meantime it will continue to compile and link\n * sibling and parent elements as though this element had not contained any directives.\n *\n * The compiler does not suspend the entire compilation to wait for templates to be loaded because this\n * would result in the whole app \"stalling\" until all templates are loaded asynchronously - even in the\n * case when only one deeply nested directive has `templateUrl`.\n *\n * Template loading is asynchronous even if the template has been preloaded into the {@link $templateCache}\n *\n * You can specify `templateUrl` as a string representing the URL or as a function which takes two\n * arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns\n * a string value representing the url.  In either case, the template URL is passed through {@link\n * $sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}.\n *\n *\n * #### `replace` ([*DEPRECATED*!], will be removed in next major release - i.e. v2.0)\n * specify what the template should replace. Defaults to `false`.\n *\n * * `true` - the template will replace the directive's element.\n * * `false` - the template will replace the contents of the directive's element.\n *\n * The replacement process migrates all of the attributes / classes from the old element to the new\n * one. See the {@link guide/directive#template-expanding-directive\n * Directives Guide} for an example.\n *\n * There are very few scenarios where element replacement is required for the application function,\n * the main one being reusable custom components that are used within SVG contexts\n * (because SVG doesn't work with custom elements in the DOM tree).\n *\n * #### `transclude`\n * Extract the contents of the element where the directive appears and make it available to the directive.\n * The contents are compiled and provided to the directive as a **transclusion function**. See the\n * {@link $compile#transclusion Transclusion} section below.\n *\n *\n * #### `compile`\n *\n * ```js\n *   function compile(tElement, tAttrs, transclude) { ... }\n * ```\n *\n * The compile function deals with transforming the template DOM. Since most directives do not do\n * template transformation, it is not used often. The compile function takes the following arguments:\n *\n *   * `tElement` - template element - The element where the directive has been declared. It is\n *     safe to do template transformation on the element and child elements only.\n *\n *   * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared\n *     between all directive compile functions.\n *\n *   * `transclude` -  [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)`\n *\n * <div class=\"alert alert-warning\">\n * **Note:** The template instance and the link instance may be different objects if the template has\n * been cloned. For this reason it is **not** safe to do anything other than DOM transformations that\n * apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration\n * should be done in a linking function rather than in a compile function.\n * </div>\n\n * <div class=\"alert alert-warning\">\n * **Note:** The compile function cannot handle directives that recursively use themselves in their\n * own templates or compile functions. Compiling these directives results in an infinite loop and\n * stack overflow errors.\n *\n * This can be avoided by manually using $compile in the postLink function to imperatively compile\n * a directive's template instead of relying on automatic template compilation via `template` or\n * `templateUrl` declaration or manual compilation inside the compile function.\n * </div>\n *\n * <div class=\"alert alert-danger\">\n * **Note:** The `transclude` function that is passed to the compile function is deprecated, as it\n *   e.g. does not know about the right outer scope. Please use the transclude function that is passed\n *   to the link function instead.\n * </div>\n\n * A compile function can have a return value which can be either a function or an object.\n *\n * * returning a (post-link) function - is equivalent to registering the linking function via the\n *   `link` property of the config object when the compile function is empty.\n *\n * * returning an object with function(s) registered via `pre` and `post` properties - allows you to\n *   control when a linking function should be called during the linking phase. See info about\n *   pre-linking and post-linking functions below.\n *\n *\n * #### `link`\n * This property is used only if the `compile` property is not defined.\n *\n * ```js\n *   function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }\n * ```\n *\n * The link function is responsible for registering DOM listeners as well as updating the DOM. It is\n * executed after the template has been cloned. This is where most of the directive logic will be\n * put.\n *\n *   * `scope` - {@link ng.$rootScope.Scope Scope} - The scope to be used by the\n *     directive for registering {@link ng.$rootScope.Scope#$watch watches}.\n *\n *   * `iElement` - instance element - The element where the directive is to be used. It is safe to\n *     manipulate the children of the element only in `postLink` function since the children have\n *     already been linked.\n *\n *   * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared\n *     between all directive linking functions.\n *\n *   * `controller` - the directive's required controller instance(s) - Instances are shared\n *     among all directives, which allows the directives to use the controllers as a communication\n *     channel. The exact value depends on the directive's `require` property:\n *       * no controller(s) required: the directive's own controller, or `undefined` if it doesn't have one\n *       * `string`: the controller instance\n *       * `array`: array of controller instances\n *\n *     If a required controller cannot be found, and it is optional, the instance is `null`,\n *     otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown.\n *\n *     Note that you can also require the directive's own controller - it will be made available like\n *     any other controller.\n *\n *   * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.\n *     This is the same as the `$transclude` parameter of directive controllers,\n *     see {@link ng.$compile#-controller- the controller section for details}.\n *     `function([scope], cloneLinkingFn, futureParentElement)`.\n *\n * #### Pre-linking function\n *\n * Executed before the child elements are linked. Not safe to do DOM transformation since the\n * compiler linking function will fail to locate the correct elements for linking.\n *\n * #### Post-linking function\n *\n * Executed after the child elements are linked.\n *\n * Note that child elements that contain `templateUrl` directives will not have been compiled\n * and linked since they are waiting for their template to load asynchronously and their own\n * compilation and linking has been suspended until that occurs.\n *\n * It is safe to do DOM transformation in the post-linking function on elements that are not waiting\n * for their async templates to be resolved.\n *\n *\n * ### Transclusion\n *\n * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and\n * copying them to another part of the DOM, while maintaining their connection to the original AngularJS\n * scope from where they were taken.\n *\n * Transclusion is used (often with {@link ngTransclude}) to insert the\n * original contents of a directive's element into a specified place in the template of the directive.\n * The benefit of transclusion, over simply moving the DOM elements manually, is that the transcluded\n * content has access to the properties on the scope from which it was taken, even if the directive\n * has isolated scope.\n * See the {@link guide/directive#creating-a-directive-that-wraps-other-elements Directives Guide}.\n *\n * This makes it possible for the widget to have private state for its template, while the transcluded\n * content has access to its originating scope.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** When testing an element transclude directive you must not place the directive at the root of the\n * DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives\n * Testing Transclusion Directives}.\n * </div>\n *\n * There are three kinds of transclusion depending upon whether you want to transclude just the contents of the\n * directive's element, the entire element or multiple parts of the element contents:\n *\n * * `true` - transclude the content (i.e. the child nodes) of the directive's element.\n * * `'element'` - transclude the whole of the directive's element including any directives on this\n *   element that defined at a lower priority than this directive. When used, the `template`\n *   property is ignored.\n * * **`{...}` (an object hash):** - map elements of the content onto transclusion \"slots\" in the template.\n *\n * **Mult-slot transclusion** is declared by providing an object for the `transclude` property.\n *\n * This object is a map where the keys are the name of the slot to fill and the value is an element selector\n * used to match the HTML to the slot. The element selector should be in normalized form (e.g. `myElement`)\n * and will match the standard element variants (e.g. `my-element`, `my:element`, `data-my-element`, etc).\n *\n * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}\n *\n * If the element selector is prefixed with a `?` then that slot is optional.\n *\n * For example, the transclude object `{ slotA: '?myCustomElement' }` maps `<my-custom-element>` elements to\n * the `slotA` slot, which can be accessed via the `$transclude` function or via the {@link ngTransclude} directive.\n *\n * Slots that are not marked as optional (`?`) will trigger a compile time error if there are no matching elements\n * in the transclude content. If you wish to know if an optional slot was filled with content, then you can call\n * `$transclude.isSlotFilled(slotName)` on the transclude function passed to the directive's link function and\n * injectable into the directive's controller.\n *\n *\n * #### Transclusion Functions\n *\n * When a directive requests transclusion, the compiler extracts its contents and provides a **transclusion\n * function** to the directive's `link` function and `controller`. This transclusion function is a special\n * **linking function** that will return the compiled contents linked to a new transclusion scope.\n *\n * <div class=\"alert alert-info\">\n * If you are just using {@link ngTransclude} then you don't need to worry about this function, since\n * ngTransclude will deal with it for us.\n * </div>\n *\n * If you want to manually control the insertion and removal of the transcluded content in your directive\n * then you must use this transclude function. When you call a transclude function it returns a a jqLite/JQuery\n * object that contains the compiled DOM, which is linked to the correct transclusion scope.\n *\n * When you call a transclusion function you can pass in a **clone attach function**. This function accepts\n * two parameters, `function(clone, scope) { ... }`, where the `clone` is a fresh compiled copy of your transcluded\n * content and the `scope` is the newly created transclusion scope, which the clone will be linked to.\n *\n * <div class=\"alert alert-info\">\n * **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a transclude function\n * since you then get a fresh clone of the original DOM and also have access to the new transclusion scope.\n * </div>\n *\n * It is normal practice to attach your transcluded content (`clone`) to the DOM inside your **clone\n * attach function**:\n *\n * ```js\n * var transcludedContent, transclusionScope;\n *\n * $transclude(function(clone, scope) {\n *   element.append(clone);\n *   transcludedContent = clone;\n *   transclusionScope = scope;\n * });\n * ```\n *\n * Later, if you want to remove the transcluded content from your DOM then you should also destroy the\n * associated transclusion scope:\n *\n * ```js\n * transcludedContent.remove();\n * transclusionScope.$destroy();\n * ```\n *\n * <div class=\"alert alert-info\">\n * **Best Practice**: if you intend to add and remove transcluded content manually in your directive\n * (by calling the transclude function to get the DOM and calling `element.remove()` to remove it),\n * then you are also responsible for calling `$destroy` on the transclusion scope.\n * </div>\n *\n * The built-in DOM manipulation directives, such as {@link ngIf}, {@link ngSwitch} and {@link ngRepeat}\n * automatically destroy their transcluded clones as necessary so you do not need to worry about this if\n * you are simply using {@link ngTransclude} to inject the transclusion into your directive.\n *\n *\n * #### Transclusion Scopes\n *\n * When you call a transclude function it returns a DOM fragment that is pre-bound to a **transclusion\n * scope**. This scope is special, in that it is a child of the directive's scope (and so gets destroyed\n * when the directive's scope gets destroyed) but it inherits the properties of the scope from which it\n * was taken.\n *\n * For example consider a directive that uses transclusion and isolated scope. The DOM hierarchy might look\n * like this:\n *\n * ```html\n * <div ng-app>\n *   <div isolate>\n *     <div transclusion>\n *     </div>\n *   </div>\n * </div>\n * ```\n *\n * The `$parent` scope hierarchy will look like this:\n *\n   ```\n   - $rootScope\n     - isolate\n       - transclusion\n   ```\n *\n * but the scopes will inherit prototypically from different scopes to their `$parent`.\n *\n   ```\n   - $rootScope\n     - transclusion\n   - isolate\n   ```\n *\n *\n * ### Attributes\n *\n * The {@link ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the\n * `link()` or `compile()` functions. It has a variety of uses.\n *\n * * *Accessing normalized attribute names:* Directives like 'ngBind' can be expressed in many ways:\n *   'ng:bind', `data-ng-bind`, or 'x-ng-bind'. The attributes object allows for normalized access\n *   to the attributes.\n *\n * * *Directive inter-communication:* All directives share the same instance of the attributes\n *   object which allows the directives to use the attributes object as inter directive\n *   communication.\n *\n * * *Supports interpolation:* Interpolation attributes are assigned to the attribute object\n *   allowing other directives to read the interpolated value.\n *\n * * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes\n *   that contain interpolation (e.g. `src=\"{{bar}}\"`). Not only is this very efficient but it's also\n *   the only way to easily get the actual value because during the linking phase the interpolation\n *   hasn't been evaluated yet and so the value is at this time set to `undefined`.\n *\n * ```js\n * function linkingFn(scope, elm, attrs, ctrl) {\n *   // get the attribute value\n *   console.log(attrs.ngModel);\n *\n *   // change the attribute\n *   attrs.$set('ngModel', 'new value');\n *\n *   // observe changes to interpolated attribute\n *   attrs.$observe('ngModel', function(value) {\n *     console.log('ngModel has changed value to ' + value);\n *   });\n * }\n * ```\n *\n * ## Example\n *\n * <div class=\"alert alert-warning\">\n * **Note**: Typically directives are registered with `module.directive`. The example below is\n * to illustrate how `$compile` works.\n * </div>\n *\n <example module=\"compileExample\" name=\"compile\">\n   <file name=\"index.html\">\n    <script>\n      angular.module('compileExample', [], function($compileProvider) {\n        // configure new 'compile' directive by passing a directive\n        // factory function. The factory function injects the '$compile'\n        $compileProvider.directive('compile', function($compile) {\n          // directive factory creates a link function\n          return function(scope, element, attrs) {\n            scope.$watch(\n              function(scope) {\n                 // watch the 'compile' expression for changes\n                return scope.$eval(attrs.compile);\n              },\n              function(value) {\n                // when the 'compile' expression changes\n                // assign it into the current DOM\n                element.html(value);\n\n                // compile the new DOM and link it to the current\n                // scope.\n                // NOTE: we only compile .childNodes so that\n                // we don't get into infinite loop compiling ourselves\n                $compile(element.contents())(scope);\n              }\n            );\n          };\n        });\n      })\n      .controller('GreeterController', ['$scope', function($scope) {\n        $scope.name = 'Angular';\n        $scope.html = 'Hello {{name}}';\n      }]);\n    </script>\n    <div ng-controller=\"GreeterController\">\n      <input ng-model=\"name\"> <br/>\n      <textarea ng-model=\"html\"></textarea> <br/>\n      <div compile=\"html\"></div>\n    </div>\n   </file>\n   <file name=\"protractor.js\" type=\"protractor\">\n     it('should auto compile', function() {\n       var textarea = $('textarea');\n       var output = $('div[compile]');\n       // The initial state reads 'Hello Angular'.\n       expect(output.getText()).toBe('Hello Angular');\n       textarea.clear();\n       textarea.sendKeys('{{name}}!');\n       expect(output.getText()).toBe('Angular!');\n     });\n   </file>\n </example>\n\n *\n *\n * @param {string|DOMElement} element Element or HTML string to compile into a template function.\n * @param {function(angular.Scope, cloneAttachFn=)} transclude function available to directives - DEPRECATED.\n *\n * <div class=\"alert alert-danger\">\n * **Note:** Passing a `transclude` function to the $compile function is deprecated, as it\n *   e.g. will not use the right outer scope. Please pass the transclude function as a\n *   `parentBoundTranscludeFn` to the link function instead.\n * </div>\n *\n * @param {number} maxPriority only apply directives lower than given priority (Only effects the\n *                 root element(s), not their children)\n * @returns {function(scope, cloneAttachFn=, options=)} a link function which is used to bind template\n * (a DOM element/tree) to a scope. Where:\n *\n *  * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to.\n *  * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the\n *  `template` and call the `cloneAttachFn` function allowing the caller to attach the\n *  cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is\n *  called as: <br/> `cloneAttachFn(clonedElement, scope)` where:\n *\n *      * `clonedElement` - is a clone of the original `element` passed into the compiler.\n *      * `scope` - is the current scope with which the linking function is working with.\n *\n *  * `options` - An optional object hash with linking options. If `options` is provided, then the following\n *  keys may be used to control linking behavior:\n *\n *      * `parentBoundTranscludeFn` - the transclude function made available to\n *        directives; if given, it will be passed through to the link functions of\n *        directives found in `element` during compilation.\n *      * `transcludeControllers` - an object hash with keys that map controller names\n *        to a hash with the key `instance`, which maps to the controller instance;\n *        if given, it will make the controllers available to directives on the compileNode:\n *        ```\n *        {\n *          parent: {\n *            instance: parentControllerInstance\n *          }\n *        }\n *        ```\n *      * `futureParentElement` - defines the parent to which the `cloneAttachFn` will add\n *        the cloned elements; only needed for transcludes that are allowed to contain non html\n *        elements (e.g. SVG elements). See also the directive.controller property.\n *\n * Calling the linking function returns the element of the template. It is either the original\n * element passed in, or the clone of the element if the `cloneAttachFn` is provided.\n *\n * After linking the view is not updated until after a call to $digest which typically is done by\n * Angular automatically.\n *\n * If you need access to the bound view, there are two ways to do it:\n *\n * - If you are not asking the linking function to clone the template, create the DOM element(s)\n *   before you send them to the compiler and keep this reference around.\n *   ```js\n *     var element = $compile('<p>{{total}}</p>')(scope);\n *   ```\n *\n * - if on the other hand, you need the element to be cloned, the view reference from the original\n *   example would not point to the clone, but rather to the original template that was cloned. In\n *   this case, you can access the clone via the cloneAttachFn:\n *   ```js\n *     var templateElement = angular.element('<p>{{total}}</p>'),\n *         scope = ....;\n *\n *     var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {\n *       //attach the clone to DOM document at the right place\n *     });\n *\n *     //now we have reference to the cloned DOM via `clonedElement`\n *   ```\n *\n *\n * For information on how the compiler works, see the\n * {@link guide/compiler Angular HTML Compiler} section of the Developer Guide.\n *\n * @knownIssue\n *\n * ### Double Compilation\n *\n   Double compilation occurs when an already compiled part of the DOM gets\n   compiled again. This is an undesired effect and can lead to misbehaving directives, performance issues,\n   and memory leaks. Refer to the Compiler Guide {@link guide/compiler#double-compilation-and-how-to-avoid-it\n   section on double compilation} for an in-depth explanation and ways to avoid it.\n *\n */\n\nvar $compileMinErr = minErr('$compile');\n\nfunction UNINITIALIZED_VALUE() {}\nvar _UNINITIALIZED_VALUE = new UNINITIALIZED_VALUE();\n\n/**\n * @ngdoc provider\n * @name $compileProvider\n *\n * @description\n */\n$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];\n/** @this */\nfunction $CompileProvider($provide, $$sanitizeUriProvider) {\n  var hasDirectives = {},\n      Suffix = 'Directive',\n      COMMENT_DIRECTIVE_REGEXP = /^\\s*directive:\\s*([\\w-]+)\\s+(.*)$/,\n      CLASS_DIRECTIVE_REGEXP = /(([\\w-]+)(?::([^;]+))?;?)/,\n      ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),\n      REQUIRE_PREFIX_REGEXP = /^(?:(\\^\\^?)?(\\?)?(\\^\\^?)?)?/;\n\n  // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes\n  // The assumption is that future DOM event attribute names will begin with\n  // 'on' and be composed of only English letters.\n  var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;\n  var bindingCache = createMap();\n\n  function parseIsolateBindings(scope, directiveName, isController) {\n    var LOCAL_REGEXP = /^\\s*([@&<]|=(\\*?))(\\??)\\s*([\\w$]*)\\s*$/;\n\n    var bindings = createMap();\n\n    forEach(scope, function(definition, scopeName) {\n      if (definition in bindingCache) {\n        bindings[scopeName] = bindingCache[definition];\n        return;\n      }\n      var match = definition.match(LOCAL_REGEXP);\n\n      if (!match) {\n        throw $compileMinErr('iscp',\n            'Invalid {3} for directive \\'{0}\\'.' +\n            ' Definition: {... {1}: \\'{2}\\' ...}',\n            directiveName, scopeName, definition,\n            (isController ? 'controller bindings definition' :\n            'isolate scope definition'));\n      }\n\n      bindings[scopeName] = {\n        mode: match[1][0],\n        collection: match[2] === '*',\n        optional: match[3] === '?',\n        attrName: match[4] || scopeName\n      };\n      if (match[4]) {\n        bindingCache[definition] = bindings[scopeName];\n      }\n    });\n\n    return bindings;\n  }\n\n  function parseDirectiveBindings(directive, directiveName) {\n    var bindings = {\n      isolateScope: null,\n      bindToController: null\n    };\n    if (isObject(directive.scope)) {\n      if (directive.bindToController === true) {\n        bindings.bindToController = parseIsolateBindings(directive.scope,\n                                                         directiveName, true);\n        bindings.isolateScope = {};\n      } else {\n        bindings.isolateScope = parseIsolateBindings(directive.scope,\n                                                     directiveName, false);\n      }\n    }\n    if (isObject(directive.bindToController)) {\n      bindings.bindToController =\n          parseIsolateBindings(directive.bindToController, directiveName, true);\n    }\n    if (bindings.bindToController && !directive.controller) {\n      // There is no controller\n      throw $compileMinErr('noctrl',\n            'Cannot bind to controller without directive \\'{0}\\'s controller.',\n            directiveName);\n    }\n    return bindings;\n  }\n\n  function assertValidDirectiveName(name) {\n    var letter = name.charAt(0);\n    if (!letter || letter !== lowercase(letter)) {\n      throw $compileMinErr('baddir', 'Directive/Component name \\'{0}\\' is invalid. The first character must be a lowercase letter', name);\n    }\n    if (name !== name.trim()) {\n      throw $compileMinErr('baddir',\n            'Directive/Component name \\'{0}\\' is invalid. The name should not contain leading or trailing whitespaces',\n            name);\n    }\n  }\n\n  function getDirectiveRequire(directive) {\n    var require = directive.require || (directive.controller && directive.name);\n\n    if (!isArray(require) && isObject(require)) {\n      forEach(require, function(value, key) {\n        var match = value.match(REQUIRE_PREFIX_REGEXP);\n        var name = value.substring(match[0].length);\n        if (!name) require[key] = match[0] + key;\n      });\n    }\n\n    return require;\n  }\n\n  function getDirectiveRestrict(restrict, name) {\n    if (restrict && !(isString(restrict) && /[EACM]/.test(restrict))) {\n      throw $compileMinErr('badrestrict',\n          'Restrict property \\'{0}\\' of directive \\'{1}\\' is invalid',\n          restrict,\n          name);\n    }\n\n    return restrict || 'EA';\n  }\n\n  /**\n   * @ngdoc method\n   * @name $compileProvider#directive\n   * @kind function\n   *\n   * @description\n   * Register a new directive with the compiler.\n   *\n   * @param {string|Object} name Name of the directive in camel-case (i.e. <code>ngBind</code> which\n   *    will match as <code>ng-bind</code>), or an object map of directives where the keys are the\n   *    names and the values are the factories.\n   * @param {Function|Array} directiveFactory An injectable directive factory function. See the\n   *    {@link guide/directive directive guide} and the {@link $compile compile API} for more info.\n   * @returns {ng.$compileProvider} Self for chaining.\n   */\n  this.directive = function registerDirective(name, directiveFactory) {\n    assertArg(name, 'name');\n    assertNotHasOwnProperty(name, 'directive');\n    if (isString(name)) {\n      assertValidDirectiveName(name);\n      assertArg(directiveFactory, 'directiveFactory');\n      if (!hasDirectives.hasOwnProperty(name)) {\n        hasDirectives[name] = [];\n        $provide.factory(name + Suffix, ['$injector', '$exceptionHandler',\n          function($injector, $exceptionHandler) {\n            var directives = [];\n            forEach(hasDirectives[name], function(directiveFactory, index) {\n              try {\n                var directive = $injector.invoke(directiveFactory);\n                if (isFunction(directive)) {\n                  directive = { compile: valueFn(directive) };\n                } else if (!directive.compile && directive.link) {\n                  directive.compile = valueFn(directive.link);\n                }\n                directive.priority = directive.priority || 0;\n                directive.index = index;\n                directive.name = directive.name || name;\n                directive.require = getDirectiveRequire(directive);\n                directive.restrict = getDirectiveRestrict(directive.restrict, name);\n                directive.$$moduleName = directiveFactory.$$moduleName;\n                directives.push(directive);\n              } catch (e) {\n                $exceptionHandler(e);\n              }\n            });\n            return directives;\n          }]);\n      }\n      hasDirectives[name].push(directiveFactory);\n    } else {\n      forEach(name, reverseParams(registerDirective));\n    }\n    return this;\n  };\n\n  /**\n   * @ngdoc method\n   * @name $compileProvider#component\n   * @module ng\n   * @param {string} name Name of the component in camelCase (i.e. `myComp` which will match `<my-comp>`)\n   * @param {Object} options Component definition object (a simplified\n   *    {@link ng.$compile#directive-definition-object directive definition object}),\n   *    with the following properties (all optional):\n   *\n   *    - `controller` – `{(string|function()=}` – controller constructor function that should be\n   *      associated with newly created scope or the name of a {@link ng.$compile#-controller-\n   *      registered controller} if passed as a string. An empty `noop` function by default.\n   *    - `controllerAs` – `{string=}` – identifier name for to reference the controller in the component's scope.\n   *      If present, the controller will be published to scope under the `controllerAs` name.\n   *      If not present, this will default to be `$ctrl`.\n   *    - `template` – `{string=|function()=}` – html template as a string or a function that\n   *      returns an html template as a string which should be used as the contents of this component.\n   *      Empty string by default.\n   *\n   *      If `template` is a function, then it is {@link auto.$injector#invoke injected} with\n   *      the following locals:\n   *\n   *      - `$element` - Current element\n   *      - `$attrs` - Current attributes object for the element\n   *\n   *    - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html\n   *      template that should be used  as the contents of this component.\n   *\n   *      If `templateUrl` is a function, then it is {@link auto.$injector#invoke injected} with\n   *      the following locals:\n   *\n   *      - `$element` - Current element\n   *      - `$attrs` - Current attributes object for the element\n   *\n   *    - `bindings` – `{object=}` – defines bindings between DOM attributes and component properties.\n   *      Component properties are always bound to the component controller and not to the scope.\n   *      See {@link ng.$compile#-bindtocontroller- `bindToController`}.\n   *    - `transclude` – `{boolean=}` – whether {@link $compile#transclusion content transclusion} is enabled.\n   *      Disabled by default.\n   *    - `require` - `{Object<string, string>=}` - requires the controllers of other directives and binds them to\n   *      this component's controller. The object keys specify the property names under which the required\n   *      controllers (object values) will be bound. See {@link ng.$compile#-require- `require`}.\n   *    - `$...` – additional properties to attach to the directive factory function and the controller\n   *      constructor function. (This is used by the component router to annotate)\n   *\n   * @returns {ng.$compileProvider} the compile provider itself, for chaining of function calls.\n   * @description\n   * Register a **component definition** with the compiler. This is a shorthand for registering a special\n   * type of directive, which represents a self-contained UI component in your application. Such components\n   * are always isolated (i.e. `scope: {}`) and are always restricted to elements (i.e. `restrict: 'E'`).\n   *\n   * Component definitions are very simple and do not require as much configuration as defining general\n   * directives. Component definitions usually consist only of a template and a controller backing it.\n   *\n   * In order to make the definition easier, components enforce best practices like use of `controllerAs`,\n   * `bindToController`. They always have **isolate scope** and are restricted to elements.\n   *\n   * Here are a few examples of how you would usually define components:\n   *\n   * ```js\n   *   var myMod = angular.module(...);\n   *   myMod.component('myComp', {\n   *     template: '<div>My name is {{$ctrl.name}}</div>',\n   *     controller: function() {\n   *       this.name = 'shahar';\n   *     }\n   *   });\n   *\n   *   myMod.component('myComp', {\n   *     template: '<div>My name is {{$ctrl.name}}</div>',\n   *     bindings: {name: '@'}\n   *   });\n   *\n   *   myMod.component('myComp', {\n   *     templateUrl: 'views/my-comp.html',\n   *     controller: 'MyCtrl',\n   *     controllerAs: 'ctrl',\n   *     bindings: {name: '@'}\n   *   });\n   *\n   * ```\n   * For more examples, and an in-depth guide, see the {@link guide/component component guide}.\n   *\n   * <br />\n   * See also {@link ng.$compileProvider#directive $compileProvider.directive()}.\n   */\n  this.component = function registerComponent(name, options) {\n    var controller = options.controller || function() {};\n\n    function factory($injector) {\n      function makeInjectable(fn) {\n        if (isFunction(fn) || isArray(fn)) {\n          return /** @this */ function(tElement, tAttrs) {\n            return $injector.invoke(fn, this, {$element: tElement, $attrs: tAttrs});\n          };\n        } else {\n          return fn;\n        }\n      }\n\n      var template = (!options.template && !options.templateUrl ? '' : options.template);\n      var ddo = {\n        controller: controller,\n        controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',\n        template: makeInjectable(template),\n        templateUrl: makeInjectable(options.templateUrl),\n        transclude: options.transclude,\n        scope: {},\n        bindToController: options.bindings || {},\n        restrict: 'E',\n        require: options.require\n      };\n\n      // Copy annotations (starting with $) over to the DDO\n      forEach(options, function(val, key) {\n        if (key.charAt(0) === '$') ddo[key] = val;\n      });\n\n      return ddo;\n    }\n\n    // TODO(pete) remove the following `forEach` before we release 1.6.0\n    // The component-router@0.2.0 looks for the annotations on the controller constructor\n    // Nothing in Angular looks for annotations on the factory function but we can't remove\n    // it from 1.5.x yet.\n\n    // Copy any annotation properties (starting with $) over to the factory and controller constructor functions\n    // These could be used by libraries such as the new component router\n    forEach(options, function(val, key) {\n      if (key.charAt(0) === '$') {\n        factory[key] = val;\n        // Don't try to copy over annotations to named controller\n        if (isFunction(controller)) controller[key] = val;\n      }\n    });\n\n    factory.$inject = ['$injector'];\n\n    return this.directive(name, factory);\n  };\n\n\n  /**\n   * @ngdoc method\n   * @name $compileProvider#aHrefSanitizationWhitelist\n   * @kind function\n   *\n   * @description\n   * Retrieves or overrides the default regular expression that is used for whitelisting of safe\n   * urls during a[href] sanitization.\n   *\n   * The sanitization is a security measure aimed at preventing XSS attacks via html links.\n   *\n   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into\n   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`\n   * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n   *\n   * @param {RegExp=} regexp New regexp to whitelist urls with.\n   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for\n   *    chaining otherwise.\n   */\n  this.aHrefSanitizationWhitelist = function(regexp) {\n    if (isDefined(regexp)) {\n      $$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);\n      return this;\n    } else {\n      return $$sanitizeUriProvider.aHrefSanitizationWhitelist();\n    }\n  };\n\n\n  /**\n   * @ngdoc method\n   * @name $compileProvider#imgSrcSanitizationWhitelist\n   * @kind function\n   *\n   * @description\n   * Retrieves or overrides the default regular expression that is used for whitelisting of safe\n   * urls during img[src] sanitization.\n   *\n   * The sanitization is a security measure aimed at prevent XSS attacks via html links.\n   *\n   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into\n   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`\n   * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n   *\n   * @param {RegExp=} regexp New regexp to whitelist urls with.\n   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for\n   *    chaining otherwise.\n   */\n  this.imgSrcSanitizationWhitelist = function(regexp) {\n    if (isDefined(regexp)) {\n      $$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);\n      return this;\n    } else {\n      return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();\n    }\n  };\n\n  /**\n   * @ngdoc method\n   * @name  $compileProvider#debugInfoEnabled\n   *\n   * @param {boolean=} enabled update the debugInfoEnabled state if provided, otherwise just return the\n   * current debugInfoEnabled state\n   * @returns {*} current value if used as getter or itself (chaining) if used as setter\n   *\n   * @kind function\n   *\n   * @description\n   * Call this method to enable/disable various debug runtime information in the compiler such as adding\n   * binding information and a reference to the current scope on to DOM elements.\n   * If enabled, the compiler will add the following to DOM elements that have been bound to the scope\n   * * `ng-binding` CSS class\n   * * `$binding` data property containing an array of the binding expressions\n   *\n   * You may want to disable this in production for a significant performance boost. See\n   * {@link guide/production#disabling-debug-data Disabling Debug Data} for more.\n   *\n   * The default value is true.\n   */\n  var debugInfoEnabled = true;\n  this.debugInfoEnabled = function(enabled) {\n    if (isDefined(enabled)) {\n      debugInfoEnabled = enabled;\n      return this;\n    }\n    return debugInfoEnabled;\n  };\n\n  /**\n   * @ngdoc method\n   * @name  $compileProvider#preAssignBindingsEnabled\n   *\n   * @param {boolean=} enabled update the preAssignBindingsEnabled state if provided, otherwise just return the\n   * current preAssignBindingsEnabled state\n   * @returns {*} current value if used as getter or itself (chaining) if used as setter\n   *\n   * @kind function\n   *\n   * @description\n   * Call this method to enable/disable whether directive controllers are assigned bindings before\n   * calling the controller's constructor.\n   * If enabled (true), the compiler assigns the value of each of the bindings to the\n   * properties of the controller object before the constructor of this object is called.\n   *\n   * If disabled (false), the compiler calls the constructor first before assigning bindings.\n   *\n   * The default value is true in Angular 1.5.x but will switch to false in Angular 1.6.x.\n   */\n  var preAssignBindingsEnabled = false;\n  this.preAssignBindingsEnabled = function(enabled) {\n    if (isDefined(enabled)) {\n      preAssignBindingsEnabled = enabled;\n      return this;\n    }\n    return preAssignBindingsEnabled;\n  };\n\n\n  var TTL = 10;\n  /**\n   * @ngdoc method\n   * @name $compileProvider#onChangesTtl\n   * @description\n   *\n   * Sets the number of times `$onChanges` hooks can trigger new changes before giving up and\n   * assuming that the model is unstable.\n   *\n   * The current default is 10 iterations.\n   *\n   * In complex applications it's possible that dependencies between `$onChanges` hooks and bindings will result\n   * in several iterations of calls to these hooks. However if an application needs more than the default 10\n   * iterations to stabilize then you should investigate what is causing the model to continuously change during\n   * the `$onChanges` hook execution.\n   *\n   * Increasing the TTL could have performance implications, so you should not change it without proper justification.\n   *\n   * @param {number} limit The number of `$onChanges` hook iterations.\n   * @returns {number|object} the current limit (or `this` if called as a setter for chaining)\n   */\n  this.onChangesTtl = function(value) {\n    if (arguments.length) {\n      TTL = value;\n      return this;\n    }\n    return TTL;\n  };\n\n  var commentDirectivesEnabledConfig = true;\n  /**\n   * @ngdoc method\n   * @name $compileProvider#commentDirectivesEnabled\n   * @description\n   *\n   * It indicates to the compiler\n   * whether or not directives on comments should be compiled.\n   * Defaults to `true`.\n   *\n   * Calling this function with false disables the compilation of directives\n   * on comments for the whole application.\n   * This results in a compilation performance gain,\n   * as the compiler doesn't have to check comments when looking for directives.\n   * This should however only be used if you are sure that no comment directives are used in\n   * the application (including any 3rd party directives).\n   *\n   * @param {boolean} enabled `false` if the compiler may ignore directives on comments\n   * @returns {boolean|object} the current value (or `this` if called as a setter for chaining)\n   */\n  this.commentDirectivesEnabled = function(value) {\n    if (arguments.length) {\n      commentDirectivesEnabledConfig = value;\n      return this;\n    }\n    return commentDirectivesEnabledConfig;\n  };\n\n\n  var cssClassDirectivesEnabledConfig = true;\n  /**\n   * @ngdoc method\n   * @name $compileProvider#cssClassDirectivesEnabled\n   * @description\n   *\n   * It indicates to the compiler\n   * whether or not directives on element classes should be compiled.\n   * Defaults to `true`.\n   *\n   * Calling this function with false disables the compilation of directives\n   * on element classes for the whole application.\n   * This results in a compilation performance gain,\n   * as the compiler doesn't have to check element classes when looking for directives.\n   * This should however only be used if you are sure that no class directives are used in\n   * the application (including any 3rd party directives).\n   *\n   * @param {boolean} enabled `false` if the compiler may ignore directives on element classes\n   * @returns {boolean|object} the current value (or `this` if called as a setter for chaining)\n   */\n  this.cssClassDirectivesEnabled = function(value) {\n    if (arguments.length) {\n      cssClassDirectivesEnabledConfig = value;\n      return this;\n    }\n    return cssClassDirectivesEnabledConfig;\n  };\n\n  this.$get = [\n            '$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',\n            '$controller', '$rootScope', '$sce', '$animate', '$$sanitizeUri',\n    function($injector,   $interpolate,   $exceptionHandler,   $templateRequest,   $parse,\n             $controller,   $rootScope,   $sce,   $animate,   $$sanitizeUri) {\n\n    var SIMPLE_ATTR_NAME = /^\\w/;\n    var specialAttrHolder = window.document.createElement('div');\n\n\n    var commentDirectivesEnabled = commentDirectivesEnabledConfig;\n    var cssClassDirectivesEnabled = cssClassDirectivesEnabledConfig;\n\n\n    var onChangesTtl = TTL;\n    // The onChanges hooks should all be run together in a single digest\n    // When changes occur, the call to trigger their hooks will be added to this queue\n    var onChangesQueue;\n\n    // This function is called in a $$postDigest to trigger all the onChanges hooks in a single digest\n    function flushOnChangesQueue() {\n      try {\n        if (!(--onChangesTtl)) {\n          // We have hit the TTL limit so reset everything\n          onChangesQueue = undefined;\n          throw $compileMinErr('infchng', '{0} $onChanges() iterations reached. Aborting!\\n', TTL);\n        }\n        // We must run this hook in an apply since the $$postDigest runs outside apply\n        $rootScope.$apply(function() {\n          var errors = [];\n          for (var i = 0, ii = onChangesQueue.length; i < ii; ++i) {\n            try {\n              onChangesQueue[i]();\n            } catch (e) {\n              errors.push(e);\n            }\n          }\n          // Reset the queue to trigger a new schedule next time there is a change\n          onChangesQueue = undefined;\n          if (errors.length) {\n            throw errors;\n          }\n        });\n      } finally {\n        onChangesTtl++;\n      }\n    }\n\n\n    function Attributes(element, attributesToCopy) {\n      if (attributesToCopy) {\n        var keys = Object.keys(attributesToCopy);\n        var i, l, key;\n\n        for (i = 0, l = keys.length; i < l; i++) {\n          key = keys[i];\n          this[key] = attributesToCopy[key];\n        }\n      } else {\n        this.$attr = {};\n      }\n\n      this.$$element = element;\n    }\n\n    Attributes.prototype = {\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$normalize\n       * @kind function\n       *\n       * @description\n       * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with `x-` or\n       * `data-`) to its normalized, camelCase form.\n       *\n       * Also there is special case for Moz prefix starting with upper case letter.\n       *\n       * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}\n       *\n       * @param {string} name Name to normalize\n       */\n      $normalize: directiveNormalize,\n\n\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$addClass\n       * @kind function\n       *\n       * @description\n       * Adds the CSS class value specified by the classVal parameter to the element. If animations\n       * are enabled then an animation will be triggered for the class addition.\n       *\n       * @param {string} classVal The className value that will be added to the element\n       */\n      $addClass: function(classVal) {\n        if (classVal && classVal.length > 0) {\n          $animate.addClass(this.$$element, classVal);\n        }\n      },\n\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$removeClass\n       * @kind function\n       *\n       * @description\n       * Removes the CSS class value specified by the classVal parameter from the element. If\n       * animations are enabled then an animation will be triggered for the class removal.\n       *\n       * @param {string} classVal The className value that will be removed from the element\n       */\n      $removeClass: function(classVal) {\n        if (classVal && classVal.length > 0) {\n          $animate.removeClass(this.$$element, classVal);\n        }\n      },\n\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$updateClass\n       * @kind function\n       *\n       * @description\n       * Adds and removes the appropriate CSS class values to the element based on the difference\n       * between the new and old CSS class values (specified as newClasses and oldClasses).\n       *\n       * @param {string} newClasses The current CSS className value\n       * @param {string} oldClasses The former CSS className value\n       */\n      $updateClass: function(newClasses, oldClasses) {\n        var toAdd = tokenDifference(newClasses, oldClasses);\n        if (toAdd && toAdd.length) {\n          $animate.addClass(this.$$element, toAdd);\n        }\n\n        var toRemove = tokenDifference(oldClasses, newClasses);\n        if (toRemove && toRemove.length) {\n          $animate.removeClass(this.$$element, toRemove);\n        }\n      },\n\n      /**\n       * Set a normalized attribute on the element in a way such that all directives\n       * can share the attribute. This function properly handles boolean attributes.\n       * @param {string} key Normalized key. (ie ngAttribute)\n       * @param {string|boolean} value The value to set. If `null` attribute will be deleted.\n       * @param {boolean=} writeAttr If false, does not write the value to DOM element attribute.\n       *     Defaults to true.\n       * @param {string=} attrName Optional none normalized name. Defaults to key.\n       */\n      $set: function(key, value, writeAttr, attrName) {\n        // TODO: decide whether or not to throw an error if \"class\"\n        //is set through this function since it may cause $updateClass to\n        //become unstable.\n\n        var node = this.$$element[0],\n            booleanKey = getBooleanAttrName(node, key),\n            aliasedKey = getAliasedAttrName(key),\n            observer = key,\n            nodeName;\n\n        if (booleanKey) {\n          this.$$element.prop(key, value);\n          attrName = booleanKey;\n        } else if (aliasedKey) {\n          this[aliasedKey] = value;\n          observer = aliasedKey;\n        }\n\n        this[key] = value;\n\n        // translate normalized key to actual key\n        if (attrName) {\n          this.$attr[key] = attrName;\n        } else {\n          attrName = this.$attr[key];\n          if (!attrName) {\n            this.$attr[key] = attrName = snake_case(key, '-');\n          }\n        }\n\n        nodeName = nodeName_(this.$$element);\n\n        if ((nodeName === 'a' && (key === 'href' || key === 'xlinkHref')) ||\n            (nodeName === 'img' && key === 'src')) {\n          // sanitize a[href] and img[src] values\n          this[key] = value = $$sanitizeUri(value, key === 'src');\n        } else if (nodeName === 'img' && key === 'srcset' && isDefined(value)) {\n          // sanitize img[srcset] values\n          var result = '';\n\n          // first check if there are spaces because it's not the same pattern\n          var trimmedSrcset = trim(value);\n          //                (   999x   ,|   999w   ,|   ,|,   )\n          var srcPattern = /(\\s+\\d+x\\s*,|\\s+\\d+w\\s*,|\\s+,|,\\s+)/;\n          var pattern = /\\s/.test(trimmedSrcset) ? srcPattern : /(,)/;\n\n          // split srcset into tuple of uri and descriptor except for the last item\n          var rawUris = trimmedSrcset.split(pattern);\n\n          // for each tuples\n          var nbrUrisWith2parts = Math.floor(rawUris.length / 2);\n          for (var i = 0; i < nbrUrisWith2parts; i++) {\n            var innerIdx = i * 2;\n            // sanitize the uri\n            result += $$sanitizeUri(trim(rawUris[innerIdx]), true);\n            // add the descriptor\n            result += (' ' + trim(rawUris[innerIdx + 1]));\n          }\n\n          // split the last item into uri and descriptor\n          var lastTuple = trim(rawUris[i * 2]).split(/\\s/);\n\n          // sanitize the last uri\n          result += $$sanitizeUri(trim(lastTuple[0]), true);\n\n          // and add the last descriptor if any\n          if (lastTuple.length === 2) {\n            result += (' ' + trim(lastTuple[1]));\n          }\n          this[key] = value = result;\n        }\n\n        if (writeAttr !== false) {\n          if (value === null || isUndefined(value)) {\n            this.$$element.removeAttr(attrName);\n          } else {\n            if (SIMPLE_ATTR_NAME.test(attrName)) {\n              this.$$element.attr(attrName, value);\n            } else {\n              setSpecialAttr(this.$$element[0], attrName, value);\n            }\n          }\n        }\n\n        // fire observers\n        var $$observers = this.$$observers;\n        if ($$observers) {\n          forEach($$observers[observer], function(fn) {\n            try {\n              fn(value);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          });\n        }\n      },\n\n\n      /**\n       * @ngdoc method\n       * @name $compile.directive.Attributes#$observe\n       * @kind function\n       *\n       * @description\n       * Observes an interpolated attribute.\n       *\n       * The observer function will be invoked once during the next `$digest` following\n       * compilation. The observer is then invoked whenever the interpolated value\n       * changes.\n       *\n       * @param {string} key Normalized key. (ie ngAttribute) .\n       * @param {function(interpolatedValue)} fn Function that will be called whenever\n                the interpolated value of the attribute changes.\n       *        See the {@link guide/interpolation#how-text-and-attribute-bindings-work Interpolation\n       *        guide} for more info.\n       * @returns {function()} Returns a deregistration function for this observer.\n       */\n      $observe: function(key, fn) {\n        var attrs = this,\n            $$observers = (attrs.$$observers || (attrs.$$observers = createMap())),\n            listeners = ($$observers[key] || ($$observers[key] = []));\n\n        listeners.push(fn);\n        $rootScope.$evalAsync(function() {\n          if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) {\n            // no one registered attribute interpolation function, so lets call it manually\n            fn(attrs[key]);\n          }\n        });\n\n        return function() {\n          arrayRemove(listeners, fn);\n        };\n      }\n    };\n\n    function setSpecialAttr(element, attrName, value) {\n      // Attributes names that do not start with letters (such as `(click)`) cannot be set using `setAttribute`\n      // so we have to jump through some hoops to get such an attribute\n      // https://github.com/angular/angular.js/pull/13318\n      specialAttrHolder.innerHTML = '<span ' + attrName + '>';\n      var attributes = specialAttrHolder.firstChild.attributes;\n      var attribute = attributes[0];\n      // We have to remove the attribute from its container element before we can add it to the destination element\n      attributes.removeNamedItem(attribute.name);\n      attribute.value = value;\n      element.attributes.setNamedItem(attribute);\n    }\n\n    function safeAddClass($element, className) {\n      try {\n        $element.addClass(className);\n      } catch (e) {\n        // ignore, since it means that we are trying to set class on\n        // SVG element, where class name is read-only.\n      }\n    }\n\n\n    var startSymbol = $interpolate.startSymbol(),\n        endSymbol = $interpolate.endSymbol(),\n        denormalizeTemplate = (startSymbol === '{{' && endSymbol  === '}}')\n            ? identity\n            : function denormalizeTemplate(template) {\n              return template.replace(/\\{\\{/g, startSymbol).replace(/}}/g, endSymbol);\n        },\n        NG_ATTR_BINDING = /^ngAttr[A-Z]/;\n    var MULTI_ELEMENT_DIR_RE = /^(.+)Start$/;\n\n    compile.$$addBindingInfo = debugInfoEnabled ? function $$addBindingInfo($element, binding) {\n      var bindings = $element.data('$binding') || [];\n\n      if (isArray(binding)) {\n        bindings = bindings.concat(binding);\n      } else {\n        bindings.push(binding);\n      }\n\n      $element.data('$binding', bindings);\n    } : noop;\n\n    compile.$$addBindingClass = debugInfoEnabled ? function $$addBindingClass($element) {\n      safeAddClass($element, 'ng-binding');\n    } : noop;\n\n    compile.$$addScopeInfo = debugInfoEnabled ? function $$addScopeInfo($element, scope, isolated, noTemplate) {\n      var dataName = isolated ? (noTemplate ? '$isolateScopeNoTemplate' : '$isolateScope') : '$scope';\n      $element.data(dataName, scope);\n    } : noop;\n\n    compile.$$addScopeClass = debugInfoEnabled ? function $$addScopeClass($element, isolated) {\n      safeAddClass($element, isolated ? 'ng-isolate-scope' : 'ng-scope');\n    } : noop;\n\n    compile.$$createComment = function(directiveName, comment) {\n      var content = '';\n      if (debugInfoEnabled) {\n        content = ' ' + (directiveName || '') + ': ';\n        if (comment) content += comment + ' ';\n      }\n      return window.document.createComment(content);\n    };\n\n    return compile;\n\n    //================================\n\n    function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective,\n                        previousCompileContext) {\n      if (!($compileNodes instanceof jqLite)) {\n        // jquery always rewraps, whereas we need to preserve the original selector so that we can\n        // modify it.\n        $compileNodes = jqLite($compileNodes);\n      }\n      var compositeLinkFn =\n              compileNodes($compileNodes, transcludeFn, $compileNodes,\n                           maxPriority, ignoreDirective, previousCompileContext);\n      compile.$$addScopeClass($compileNodes);\n      var namespace = null;\n      return function publicLinkFn(scope, cloneConnectFn, options) {\n        if (!$compileNodes) {\n          throw $compileMinErr('multilink', 'This element has already been linked.');\n        }\n        assertArg(scope, 'scope');\n\n        if (previousCompileContext && previousCompileContext.needsNewScope) {\n          // A parent directive did a replace and a directive on this element asked\n          // for transclusion, which caused us to lose a layer of element on which\n          // we could hold the new transclusion scope, so we will create it manually\n          // here.\n          scope = scope.$parent.$new();\n        }\n\n        options = options || {};\n        var parentBoundTranscludeFn = options.parentBoundTranscludeFn,\n          transcludeControllers = options.transcludeControllers,\n          futureParentElement = options.futureParentElement;\n\n        // When `parentBoundTranscludeFn` is passed, it is a\n        // `controllersBoundTransclude` function (it was previously passed\n        // as `transclude` to directive.link) so we must unwrap it to get\n        // its `boundTranscludeFn`\n        if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) {\n          parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude;\n        }\n\n        if (!namespace) {\n          namespace = detectNamespaceForChildElements(futureParentElement);\n        }\n        var $linkNode;\n        if (namespace !== 'html') {\n          // When using a directive with replace:true and templateUrl the $compileNodes\n          // (or a child element inside of them)\n          // might change, so we need to recreate the namespace adapted compileNodes\n          // for call to the link function.\n          // Note: This will already clone the nodes...\n          $linkNode = jqLite(\n            wrapTemplate(namespace, jqLite('<div>').append($compileNodes).html())\n          );\n        } else if (cloneConnectFn) {\n          // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart\n          // and sometimes changes the structure of the DOM.\n          $linkNode = JQLitePrototype.clone.call($compileNodes);\n        } else {\n          $linkNode = $compileNodes;\n        }\n\n        if (transcludeControllers) {\n          for (var controllerName in transcludeControllers) {\n            $linkNode.data('$' + controllerName + 'Controller', transcludeControllers[controllerName].instance);\n          }\n        }\n\n        compile.$$addScopeInfo($linkNode, scope);\n\n        if (cloneConnectFn) cloneConnectFn($linkNode, scope);\n        if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);\n\n        if (!cloneConnectFn) {\n          $compileNodes = compositeLinkFn = null;\n        }\n        return $linkNode;\n      };\n    }\n\n    function detectNamespaceForChildElements(parentElement) {\n      // TODO: Make this detect MathML as well...\n      var node = parentElement && parentElement[0];\n      if (!node) {\n        return 'html';\n      } else {\n        return nodeName_(node) !== 'foreignobject' && toString.call(node).match(/SVG/) ? 'svg' : 'html';\n      }\n    }\n\n    /**\n     * Compile function matches each node in nodeList against the directives. Once all directives\n     * for a particular node are collected their compile functions are executed. The compile\n     * functions return values - the linking functions - are combined into a composite linking\n     * function, which is the a linking function for the node.\n     *\n     * @param {NodeList} nodeList an array of nodes or NodeList to compile\n     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the\n     *        scope argument is auto-generated to the new child of the transcluded parent scope.\n     * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then\n     *        the rootElement must be set the jqLite collection of the compile root. This is\n     *        needed so that the jqLite collection items can be replaced with widgets.\n     * @param {number=} maxPriority Max directive priority.\n     * @returns {Function} A composite linking function of all of the matched directives or null.\n     */\n    function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,\n                            previousCompileContext) {\n      var linkFns = [],\n          // `nodeList` can be either an element's `.childNodes` (live NodeList)\n          // or a jqLite/jQuery collection or an array\n          notLiveList = isArray(nodeList) || (nodeList instanceof jqLite),\n          attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound;\n\n\n      for (var i = 0; i < nodeList.length; i++) {\n        attrs = new Attributes();\n\n        // Support: IE 11 only\n        // Workaround for #11781 and #14924\n        if (msie === 11) {\n          mergeConsecutiveTextNodes(nodeList, i, notLiveList);\n        }\n\n        // We must always refer to `nodeList[i]` hereafter,\n        // since the nodes can be replaced underneath us.\n        directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined,\n                                        ignoreDirective);\n\n        nodeLinkFn = (directives.length)\n            ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement,\n                                      null, [], [], previousCompileContext)\n            : null;\n\n        if (nodeLinkFn && nodeLinkFn.scope) {\n          compile.$$addScopeClass(attrs.$$element);\n        }\n\n        childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||\n                      !(childNodes = nodeList[i].childNodes) ||\n                      !childNodes.length)\n            ? null\n            : compileNodes(childNodes,\n                 nodeLinkFn ? (\n                  (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement)\n                     && nodeLinkFn.transclude) : transcludeFn);\n\n        if (nodeLinkFn || childLinkFn) {\n          linkFns.push(i, nodeLinkFn, childLinkFn);\n          linkFnFound = true;\n          nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;\n        }\n\n        //use the previous context only for the first element in the virtual group\n        previousCompileContext = null;\n      }\n\n      // return a linking function if we have found anything, null otherwise\n      return linkFnFound ? compositeLinkFn : null;\n\n      function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {\n        var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn;\n        var stableNodeList;\n\n\n        if (nodeLinkFnFound) {\n          // copy nodeList so that if a nodeLinkFn removes or adds an element at this DOM level our\n          // offsets don't get screwed up\n          var nodeListLength = nodeList.length;\n          stableNodeList = new Array(nodeListLength);\n\n          // create a sparse array by only copying the elements which have a linkFn\n          for (i = 0; i < linkFns.length; i += 3) {\n            idx = linkFns[i];\n            stableNodeList[idx] = nodeList[idx];\n          }\n        } else {\n          stableNodeList = nodeList;\n        }\n\n        for (i = 0, ii = linkFns.length; i < ii;) {\n          node = stableNodeList[linkFns[i++]];\n          nodeLinkFn = linkFns[i++];\n          childLinkFn = linkFns[i++];\n\n          if (nodeLinkFn) {\n            if (nodeLinkFn.scope) {\n              childScope = scope.$new();\n              compile.$$addScopeInfo(jqLite(node), childScope);\n            } else {\n              childScope = scope;\n            }\n\n            if (nodeLinkFn.transcludeOnThisElement) {\n              childBoundTranscludeFn = createBoundTranscludeFn(\n                  scope, nodeLinkFn.transclude, parentBoundTranscludeFn);\n\n            } else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {\n              childBoundTranscludeFn = parentBoundTranscludeFn;\n\n            } else if (!parentBoundTranscludeFn && transcludeFn) {\n              childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn);\n\n            } else {\n              childBoundTranscludeFn = null;\n            }\n\n            nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);\n\n          } else if (childLinkFn) {\n            childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn);\n          }\n        }\n      }\n    }\n\n    function mergeConsecutiveTextNodes(nodeList, idx, notLiveList) {\n      var node = nodeList[idx];\n      var parent = node.parentNode;\n      var sibling;\n\n      if (node.nodeType !== NODE_TYPE_TEXT) {\n        return;\n      }\n\n      while (true) {\n        sibling = parent ? node.nextSibling : nodeList[idx + 1];\n        if (!sibling || sibling.nodeType !== NODE_TYPE_TEXT) {\n          break;\n        }\n\n        node.nodeValue = node.nodeValue + sibling.nodeValue;\n\n        if (sibling.parentNode) {\n          sibling.parentNode.removeChild(sibling);\n        }\n        if (notLiveList && sibling === nodeList[idx + 1]) {\n          nodeList.splice(idx + 1, 1);\n        }\n      }\n    }\n\n    function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {\n      function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {\n\n        if (!transcludedScope) {\n          transcludedScope = scope.$new(false, containingScope);\n          transcludedScope.$$transcluded = true;\n        }\n\n        return transcludeFn(transcludedScope, cloneFn, {\n          parentBoundTranscludeFn: previousBoundTranscludeFn,\n          transcludeControllers: controllers,\n          futureParentElement: futureParentElement\n        });\n      }\n\n      // We need  to attach the transclusion slots onto the `boundTranscludeFn`\n      // so that they are available inside the `controllersBoundTransclude` function\n      var boundSlots = boundTranscludeFn.$$slots = createMap();\n      for (var slotName in transcludeFn.$$slots) {\n        if (transcludeFn.$$slots[slotName]) {\n          boundSlots[slotName] = createBoundTranscludeFn(scope, transcludeFn.$$slots[slotName], previousBoundTranscludeFn);\n        } else {\n          boundSlots[slotName] = null;\n        }\n      }\n\n      return boundTranscludeFn;\n    }\n\n    /**\n     * Looks for directives on the given node and adds them to the directive collection which is\n     * sorted.\n     *\n     * @param node Node to search.\n     * @param directives An array to which the directives are added to. This array is sorted before\n     *        the function returns.\n     * @param attrs The shared attrs object which is used to populate the normalized attributes.\n     * @param {number=} maxPriority Max directive priority.\n     */\n    function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {\n      var nodeType = node.nodeType,\n          attrsMap = attrs.$attr,\n          match,\n          nodeName,\n          className;\n\n      switch (nodeType) {\n        case NODE_TYPE_ELEMENT: /* Element */\n\n          nodeName = nodeName_(node);\n\n          // use the node name: <directive>\n          addDirective(directives,\n              directiveNormalize(nodeName), 'E', maxPriority, ignoreDirective);\n\n          // iterate over the attributes\n          for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,\n                   j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {\n            var attrStartName = false;\n            var attrEndName = false;\n\n            attr = nAttrs[j];\n            name = attr.name;\n            value = attr.value;\n\n            // support ngAttr attribute binding\n            ngAttrName = directiveNormalize(name);\n            isNgAttr = NG_ATTR_BINDING.test(ngAttrName);\n            if (isNgAttr) {\n              name = name.replace(PREFIX_REGEXP, '')\n                .substr(8).replace(/_(.)/g, function(match, letter) {\n                  return letter.toUpperCase();\n                });\n            }\n\n            var multiElementMatch = ngAttrName.match(MULTI_ELEMENT_DIR_RE);\n            if (multiElementMatch && directiveIsMultiElement(multiElementMatch[1])) {\n              attrStartName = name;\n              attrEndName = name.substr(0, name.length - 5) + 'end';\n              name = name.substr(0, name.length - 6);\n            }\n\n            nName = directiveNormalize(name.toLowerCase());\n            attrsMap[nName] = name;\n            if (isNgAttr || !attrs.hasOwnProperty(nName)) {\n                attrs[nName] = value;\n                if (getBooleanAttrName(node, nName)) {\n                  attrs[nName] = true; // presence means true\n                }\n            }\n            addAttrInterpolateDirective(node, directives, value, nName, isNgAttr);\n            addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName,\n                          attrEndName);\n          }\n\n          if (nodeName === 'input' && node.getAttribute('type') === 'hidden') {\n            // Hidden input elements can have strange behaviour when navigating back to the page\n            // This tells the browser not to try to cache and reinstate previous values\n            node.setAttribute('autocomplete', 'off');\n          }\n\n          // use class as directive\n          if (!cssClassDirectivesEnabled) break;\n          className = node.className;\n          if (isObject(className)) {\n              // Maybe SVGAnimatedString\n              className = className.animVal;\n          }\n          if (isString(className) && className !== '') {\n            while ((match = CLASS_DIRECTIVE_REGEXP.exec(className))) {\n              nName = directiveNormalize(match[2]);\n              if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) {\n                attrs[nName] = trim(match[3]);\n              }\n              className = className.substr(match.index + match[0].length);\n            }\n          }\n          break;\n        case NODE_TYPE_TEXT: /* Text Node */\n          addTextInterpolateDirective(directives, node.nodeValue);\n          break;\n        case NODE_TYPE_COMMENT: /* Comment */\n          if (!commentDirectivesEnabled) break;\n          collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective);\n          break;\n      }\n\n      directives.sort(byPriority);\n      return directives;\n    }\n\n    function collectCommentDirectives(node, directives, attrs, maxPriority, ignoreDirective) {\n      // function created because of performance, try/catch disables\n      // the optimization of the whole function #14848\n      try {\n        var match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue);\n        if (match) {\n          var nName = directiveNormalize(match[1]);\n          if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) {\n            attrs[nName] = trim(match[2]);\n          }\n        }\n      } catch (e) {\n        // turns out that under some circumstances IE9 throws errors when one attempts to read\n        // comment's node value.\n        // Just ignore it and continue. (Can't seem to reproduce in test case.)\n      }\n    }\n\n    /**\n     * Given a node with a directive-start it collects all of the siblings until it finds\n     * directive-end.\n     * @param node\n     * @param attrStart\n     * @param attrEnd\n     * @returns {*}\n     */\n    function groupScan(node, attrStart, attrEnd) {\n      var nodes = [];\n      var depth = 0;\n      if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {\n        do {\n          if (!node) {\n            throw $compileMinErr('uterdir',\n                      'Unterminated attribute, found \\'{0}\\' but no matching \\'{1}\\' found.',\n                      attrStart, attrEnd);\n          }\n          if (node.nodeType === NODE_TYPE_ELEMENT) {\n            if (node.hasAttribute(attrStart)) depth++;\n            if (node.hasAttribute(attrEnd)) depth--;\n          }\n          nodes.push(node);\n          node = node.nextSibling;\n        } while (depth > 0);\n      } else {\n        nodes.push(node);\n      }\n\n      return jqLite(nodes);\n    }\n\n    /**\n     * Wrapper for linking function which converts normal linking function into a grouped\n     * linking function.\n     * @param linkFn\n     * @param attrStart\n     * @param attrEnd\n     * @returns {Function}\n     */\n    function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {\n      return function groupedElementsLink(scope, element, attrs, controllers, transcludeFn) {\n        element = groupScan(element[0], attrStart, attrEnd);\n        return linkFn(scope, element, attrs, controllers, transcludeFn);\n      };\n    }\n\n    /**\n     * A function generator that is used to support both eager and lazy compilation\n     * linking function.\n     * @param eager\n     * @param $compileNodes\n     * @param transcludeFn\n     * @param maxPriority\n     * @param ignoreDirective\n     * @param previousCompileContext\n     * @returns {Function}\n     */\n    function compilationGenerator(eager, $compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) {\n      var compiled;\n\n      if (eager) {\n        return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);\n      }\n      return /** @this */ function lazyCompilation() {\n        if (!compiled) {\n          compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);\n\n          // Null out all of these references in order to make them eligible for garbage collection\n          // since this is a potentially long lived closure\n          $compileNodes = transcludeFn = previousCompileContext = null;\n        }\n        return compiled.apply(this, arguments);\n      };\n    }\n\n    /**\n     * Once the directives have been collected, their compile functions are executed. This method\n     * is responsible for inlining directive templates as well as terminating the application\n     * of the directives if the terminal directive has been reached.\n     *\n     * @param {Array} directives Array of collected directives to execute their compile function.\n     *        this needs to be pre-sorted by priority order.\n     * @param {Node} compileNode The raw DOM node to apply the compile functions to\n     * @param {Object} templateAttrs The shared attribute function\n     * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the\n     *                                                  scope argument is auto-generated to the new\n     *                                                  child of the transcluded parent scope.\n     * @param {JQLite} jqCollection If we are working on the root of the compile tree then this\n     *                              argument has the root jqLite array so that we can replace nodes\n     *                              on it.\n     * @param {Object=} originalReplaceDirective An optional directive that will be ignored when\n     *                                           compiling the transclusion.\n     * @param {Array.<Function>} preLinkFns\n     * @param {Array.<Function>} postLinkFns\n     * @param {Object} previousCompileContext Context used for previous compilation of the current\n     *                                        node\n     * @returns {Function} linkFn\n     */\n    function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn,\n                                   jqCollection, originalReplaceDirective, preLinkFns, postLinkFns,\n                                   previousCompileContext) {\n      previousCompileContext = previousCompileContext || {};\n\n      var terminalPriority = -Number.MAX_VALUE,\n          newScopeDirective = previousCompileContext.newScopeDirective,\n          controllerDirectives = previousCompileContext.controllerDirectives,\n          newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,\n          templateDirective = previousCompileContext.templateDirective,\n          nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,\n          hasTranscludeDirective = false,\n          hasTemplate = false,\n          hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,\n          $compileNode = templateAttrs.$$element = jqLite(compileNode),\n          directive,\n          directiveName,\n          $template,\n          replaceDirective = originalReplaceDirective,\n          childTranscludeFn = transcludeFn,\n          linkFn,\n          didScanForMultipleTransclusion = false,\n          mightHaveMultipleTransclusionError = false,\n          directiveValue;\n\n      // executes all directives on the current element\n      for (var i = 0, ii = directives.length; i < ii; i++) {\n        directive = directives[i];\n        var attrStart = directive.$$start;\n        var attrEnd = directive.$$end;\n\n        // collect multiblock sections\n        if (attrStart) {\n          $compileNode = groupScan(compileNode, attrStart, attrEnd);\n        }\n        $template = undefined;\n\n        if (terminalPriority > directive.priority) {\n          break; // prevent further processing of directives\n        }\n\n        directiveValue = directive.scope;\n\n        if (directiveValue) {\n\n          // skip the check for directives with async templates, we'll check the derived sync\n          // directive when the template arrives\n          if (!directive.templateUrl) {\n            if (isObject(directiveValue)) {\n              // This directive is trying to add an isolated scope.\n              // Check that there is no scope of any kind already\n              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective || newScopeDirective,\n                                directive, $compileNode);\n              newIsolateScopeDirective = directive;\n            } else {\n              // This directive is trying to add a child scope.\n              // Check that there is no isolated scope already\n              assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive,\n                                $compileNode);\n            }\n          }\n\n          newScopeDirective = newScopeDirective || directive;\n        }\n\n        directiveName = directive.name;\n\n        // If we encounter a condition that can result in transclusion on the directive,\n        // then scan ahead in the remaining directives for others that may cause a multiple\n        // transclusion error to be thrown during the compilation process.  If a matching directive\n        // is found, then we know that when we encounter a transcluded directive, we need to eagerly\n        // compile the `transclude` function rather than doing it lazily in order to throw\n        // exceptions at the correct time\n        if (!didScanForMultipleTransclusion && ((directive.replace && (directive.templateUrl || directive.template))\n            || (directive.transclude && !directive.$$tlb))) {\n                var candidateDirective;\n\n                for (var scanningIndex = i + 1; (candidateDirective = directives[scanningIndex++]);) {\n                    if ((candidateDirective.transclude && !candidateDirective.$$tlb)\n                        || (candidateDirective.replace && (candidateDirective.templateUrl || candidateDirective.template))) {\n                        mightHaveMultipleTransclusionError = true;\n                        break;\n                    }\n                }\n\n                didScanForMultipleTransclusion = true;\n        }\n\n        if (!directive.templateUrl && directive.controller) {\n          controllerDirectives = controllerDirectives || createMap();\n          assertNoDuplicate('\\'' + directiveName + '\\' controller',\n              controllerDirectives[directiveName], directive, $compileNode);\n          controllerDirectives[directiveName] = directive;\n        }\n\n        directiveValue = directive.transclude;\n\n        if (directiveValue) {\n          hasTranscludeDirective = true;\n\n          // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.\n          // This option should only be used by directives that know how to safely handle element transclusion,\n          // where the transcluded nodes are added or replaced after linking.\n          if (!directive.$$tlb) {\n            assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);\n            nonTlbTranscludeDirective = directive;\n          }\n\n          if (directiveValue === 'element') {\n            hasElementTranscludeDirective = true;\n            terminalPriority = directive.priority;\n            $template = $compileNode;\n            $compileNode = templateAttrs.$$element =\n                jqLite(compile.$$createComment(directiveName, templateAttrs[directiveName]));\n            compileNode = $compileNode[0];\n            replaceWith(jqCollection, sliceArgs($template), compileNode);\n\n            // Support: Chrome < 50\n            // https://github.com/angular/angular.js/issues/14041\n\n            // In the versions of V8 prior to Chrome 50, the document fragment that is created\n            // in the `replaceWith` function is improperly garbage collected despite still\n            // being referenced by the `parentNode` property of all of the child nodes.  By adding\n            // a reference to the fragment via a different property, we can avoid that incorrect\n            // behavior.\n            // TODO: remove this line after Chrome 50 has been released\n            $template[0].$$parentNode = $template[0].parentNode;\n\n            childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority,\n                                        replaceDirective && replaceDirective.name, {\n                                          // Don't pass in:\n                                          // - controllerDirectives - otherwise we'll create duplicates controllers\n                                          // - newIsolateScopeDirective or templateDirective - combining templates with\n                                          //   element transclusion doesn't make sense.\n                                          //\n                                          // We need only nonTlbTranscludeDirective so that we prevent putting transclusion\n                                          // on the same element more than once.\n                                          nonTlbTranscludeDirective: nonTlbTranscludeDirective\n                                        });\n          } else {\n\n            var slots = createMap();\n\n            if (!isObject(directiveValue)) {\n              $template = jqLite(jqLiteClone(compileNode)).contents();\n            } else {\n\n              // We have transclusion slots,\n              // collect them up, compile them and store their transclusion functions\n              $template = [];\n\n              var slotMap = createMap();\n              var filledSlots = createMap();\n\n              // Parse the element selectors\n              forEach(directiveValue, function(elementSelector, slotName) {\n                // If an element selector starts with a ? then it is optional\n                var optional = (elementSelector.charAt(0) === '?');\n                elementSelector = optional ? elementSelector.substring(1) : elementSelector;\n\n                slotMap[elementSelector] = slotName;\n\n                // We explicitly assign `null` since this implies that a slot was defined but not filled.\n                // Later when calling boundTransclusion functions with a slot name we only error if the\n                // slot is `undefined`\n                slots[slotName] = null;\n\n                // filledSlots contains `true` for all slots that are either optional or have been\n                // filled. This is used to check that we have not missed any required slots\n                filledSlots[slotName] = optional;\n              });\n\n              // Add the matching elements into their slot\n              forEach($compileNode.contents(), function(node) {\n                var slotName = slotMap[directiveNormalize(nodeName_(node))];\n                if (slotName) {\n                  filledSlots[slotName] = true;\n                  slots[slotName] = slots[slotName] || [];\n                  slots[slotName].push(node);\n                } else {\n                  $template.push(node);\n                }\n              });\n\n              // Check for required slots that were not filled\n              forEach(filledSlots, function(filled, slotName) {\n                if (!filled) {\n                  throw $compileMinErr('reqslot', 'Required transclusion slot `{0}` was not filled.', slotName);\n                }\n              });\n\n              for (var slotName in slots) {\n                if (slots[slotName]) {\n                  // Only define a transclusion function if the slot was filled\n                  slots[slotName] = compilationGenerator(mightHaveMultipleTransclusionError, slots[slotName], transcludeFn);\n                }\n              }\n            }\n\n            $compileNode.empty(); // clear contents\n            childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, undefined,\n                undefined, { needsNewScope: directive.$$isolateScope || directive.$$newScope});\n            childTranscludeFn.$$slots = slots;\n          }\n        }\n\n        if (directive.template) {\n          hasTemplate = true;\n          assertNoDuplicate('template', templateDirective, directive, $compileNode);\n          templateDirective = directive;\n\n          directiveValue = (isFunction(directive.template))\n              ? directive.template($compileNode, templateAttrs)\n              : directive.template;\n\n          directiveValue = denormalizeTemplate(directiveValue);\n\n          if (directive.replace) {\n            replaceDirective = directive;\n            if (jqLiteIsTextNode(directiveValue)) {\n              $template = [];\n            } else {\n              $template = removeComments(wrapTemplate(directive.templateNamespace, trim(directiveValue)));\n            }\n            compileNode = $template[0];\n\n            if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {\n              throw $compileMinErr('tplrt',\n                  'Template for directive \\'{0}\\' must have exactly one root element. {1}',\n                  directiveName, '');\n            }\n\n            replaceWith(jqCollection, $compileNode, compileNode);\n\n            var newTemplateAttrs = {$attr: {}};\n\n            // combine directives from the original node and from the template:\n            // - take the array of directives for this element\n            // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed)\n            // - collect directives from the template and sort them by priority\n            // - combine directives as: processed + template + unprocessed\n            var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs);\n            var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1));\n\n            if (newIsolateScopeDirective || newScopeDirective) {\n              // The original directive caused the current element to be replaced but this element\n              // also needs to have a new scope, so we need to tell the template directives\n              // that they would need to get their scope from further up, if they require transclusion\n              markDirectiveScope(templateDirectives, newIsolateScopeDirective, newScopeDirective);\n            }\n            directives = directives.concat(templateDirectives).concat(unprocessedDirectives);\n            mergeTemplateAttributes(templateAttrs, newTemplateAttrs);\n\n            ii = directives.length;\n          } else {\n            $compileNode.html(directiveValue);\n          }\n        }\n\n        if (directive.templateUrl) {\n          hasTemplate = true;\n          assertNoDuplicate('template', templateDirective, directive, $compileNode);\n          templateDirective = directive;\n\n          if (directive.replace) {\n            replaceDirective = directive;\n          }\n\n          // eslint-disable-next-line no-func-assign\n          nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,\n              templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, {\n                controllerDirectives: controllerDirectives,\n                newScopeDirective: (newScopeDirective !== directive) && newScopeDirective,\n                newIsolateScopeDirective: newIsolateScopeDirective,\n                templateDirective: templateDirective,\n                nonTlbTranscludeDirective: nonTlbTranscludeDirective\n              });\n          ii = directives.length;\n        } else if (directive.compile) {\n          try {\n            linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn);\n            var context = directive.$$originalDirective || directive;\n            if (isFunction(linkFn)) {\n              addLinkFns(null, bind(context, linkFn), attrStart, attrEnd);\n            } else if (linkFn) {\n              addLinkFns(bind(context, linkFn.pre), bind(context, linkFn.post), attrStart, attrEnd);\n            }\n          } catch (e) {\n            $exceptionHandler(e, startingTag($compileNode));\n          }\n        }\n\n        if (directive.terminal) {\n          nodeLinkFn.terminal = true;\n          terminalPriority = Math.max(terminalPriority, directive.priority);\n        }\n\n      }\n\n      nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;\n      nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;\n      nodeLinkFn.templateOnThisElement = hasTemplate;\n      nodeLinkFn.transclude = childTranscludeFn;\n\n      previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;\n\n      // might be normal or delayed nodeLinkFn depending on if templateUrl is present\n      return nodeLinkFn;\n\n      ////////////////////\n\n      function addLinkFns(pre, post, attrStart, attrEnd) {\n        if (pre) {\n          if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);\n          pre.require = directive.require;\n          pre.directiveName = directiveName;\n          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {\n            pre = cloneAndAnnotateFn(pre, {isolateScope: true});\n          }\n          preLinkFns.push(pre);\n        }\n        if (post) {\n          if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);\n          post.require = directive.require;\n          post.directiveName = directiveName;\n          if (newIsolateScopeDirective === directive || directive.$$isolateScope) {\n            post = cloneAndAnnotateFn(post, {isolateScope: true});\n          }\n          postLinkFns.push(post);\n        }\n      }\n\n      function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {\n        var i, ii, linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,\n            attrs, scopeBindingInfo;\n\n        if (compileNode === linkNode) {\n          attrs = templateAttrs;\n          $element = templateAttrs.$$element;\n        } else {\n          $element = jqLite(linkNode);\n          attrs = new Attributes($element, templateAttrs);\n        }\n\n        controllerScope = scope;\n        if (newIsolateScopeDirective) {\n          isolateScope = scope.$new(true);\n        } else if (newScopeDirective) {\n          controllerScope = scope.$parent;\n        }\n\n        if (boundTranscludeFn) {\n          // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`\n          // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`\n          transcludeFn = controllersBoundTransclude;\n          transcludeFn.$$boundTransclude = boundTranscludeFn;\n          // expose the slots on the `$transclude` function\n          transcludeFn.isSlotFilled = function(slotName) {\n            return !!boundTranscludeFn.$$slots[slotName];\n          };\n        }\n\n        if (controllerDirectives) {\n          elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective);\n        }\n\n        if (newIsolateScopeDirective) {\n          // Initialize isolate scope bindings for new isolate scope directive.\n          compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective ||\n              templateDirective === newIsolateScopeDirective.$$originalDirective)));\n          compile.$$addScopeClass($element, true);\n          isolateScope.$$isolateBindings =\n              newIsolateScopeDirective.$$isolateBindings;\n          scopeBindingInfo = initializeDirectiveBindings(scope, attrs, isolateScope,\n                                        isolateScope.$$isolateBindings,\n                                        newIsolateScopeDirective);\n          if (scopeBindingInfo.removeWatches) {\n            isolateScope.$on('$destroy', scopeBindingInfo.removeWatches);\n          }\n        }\n\n        // Initialize bindToController bindings\n        for (var name in elementControllers) {\n          var controllerDirective = controllerDirectives[name];\n          var controller = elementControllers[name];\n          var bindings = controllerDirective.$$bindings.bindToController;\n\n          if (preAssignBindingsEnabled) {\n            if (bindings) {\n              controller.bindingInfo =\n                initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);\n            } else {\n              controller.bindingInfo = {};\n            }\n\n            var controllerResult = controller();\n            if (controllerResult !== controller.instance) {\n              // If the controller constructor has a return value, overwrite the instance\n              // from setupControllers\n              controller.instance = controllerResult;\n              $element.data('$' + controllerDirective.name + 'Controller', controllerResult);\n              if (controller.bindingInfo.removeWatches) {\n                controller.bindingInfo.removeWatches();\n              }\n              controller.bindingInfo =\n                initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);\n            }\n          } else {\n            controller.instance = controller();\n            $element.data('$' + controllerDirective.name + 'Controller', controller.instance);\n            controller.bindingInfo =\n              initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);\n          }\n        }\n\n        // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy\n        forEach(controllerDirectives, function(controllerDirective, name) {\n          var require = controllerDirective.require;\n          if (controllerDirective.bindToController && !isArray(require) && isObject(require)) {\n            extend(elementControllers[name].instance, getControllers(name, require, $element, elementControllers));\n          }\n        });\n\n        // Handle the init and destroy lifecycle hooks on all controllers that have them\n        forEach(elementControllers, function(controller) {\n          var controllerInstance = controller.instance;\n          if (isFunction(controllerInstance.$onChanges)) {\n            try {\n              controllerInstance.$onChanges(controller.bindingInfo.initialChanges);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          }\n          if (isFunction(controllerInstance.$onInit)) {\n            try {\n              controllerInstance.$onInit();\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          }\n          if (isFunction(controllerInstance.$doCheck)) {\n            controllerScope.$watch(function() { controllerInstance.$doCheck(); });\n            controllerInstance.$doCheck();\n          }\n          if (isFunction(controllerInstance.$onDestroy)) {\n            controllerScope.$on('$destroy', function callOnDestroyHook() {\n              controllerInstance.$onDestroy();\n            });\n          }\n        });\n\n        // PRELINKING\n        for (i = 0, ii = preLinkFns.length; i < ii; i++) {\n          linkFn = preLinkFns[i];\n          invokeLinkFn(linkFn,\n              linkFn.isolateScope ? isolateScope : scope,\n              $element,\n              attrs,\n              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),\n              transcludeFn\n          );\n        }\n\n        // RECURSION\n        // We only pass the isolate scope, if the isolate directive has a template,\n        // otherwise the child elements do not belong to the isolate directive.\n        var scopeToChild = scope;\n        if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) {\n          scopeToChild = isolateScope;\n        }\n        if (childLinkFn) {\n          childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);\n        }\n\n        // POSTLINKING\n        for (i = postLinkFns.length - 1; i >= 0; i--) {\n          linkFn = postLinkFns[i];\n          invokeLinkFn(linkFn,\n              linkFn.isolateScope ? isolateScope : scope,\n              $element,\n              attrs,\n              linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),\n              transcludeFn\n          );\n        }\n\n        // Trigger $postLink lifecycle hooks\n        forEach(elementControllers, function(controller) {\n          var controllerInstance = controller.instance;\n          if (isFunction(controllerInstance.$postLink)) {\n            controllerInstance.$postLink();\n          }\n        });\n\n        // This is the function that is injected as `$transclude`.\n        // Note: all arguments are optional!\n        function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) {\n          var transcludeControllers;\n          // No scope passed in:\n          if (!isScope(scope)) {\n            slotName = futureParentElement;\n            futureParentElement = cloneAttachFn;\n            cloneAttachFn = scope;\n            scope = undefined;\n          }\n\n          if (hasElementTranscludeDirective) {\n            transcludeControllers = elementControllers;\n          }\n          if (!futureParentElement) {\n            futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;\n          }\n          if (slotName) {\n            // slotTranscludeFn can be one of three things:\n            //  * a transclude function - a filled slot\n            //  * `null` - an optional slot that was not filled\n            //  * `undefined` - a slot that was not declared (i.e. invalid)\n            var slotTranscludeFn = boundTranscludeFn.$$slots[slotName];\n            if (slotTranscludeFn) {\n              return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);\n            } else if (isUndefined(slotTranscludeFn)) {\n              throw $compileMinErr('noslot',\n               'No parent directive that requires a transclusion with slot name \"{0}\". ' +\n               'Element: {1}',\n               slotName, startingTag($element));\n            }\n          } else {\n            return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);\n          }\n        }\n      }\n    }\n\n    function getControllers(directiveName, require, $element, elementControllers) {\n      var value;\n\n      if (isString(require)) {\n        var match = require.match(REQUIRE_PREFIX_REGEXP);\n        var name = require.substring(match[0].length);\n        var inheritType = match[1] || match[3];\n        var optional = match[2] === '?';\n\n        //If only parents then start at the parent element\n        if (inheritType === '^^') {\n          $element = $element.parent();\n        //Otherwise attempt getting the controller from elementControllers in case\n        //the element is transcluded (and has no data) and to avoid .data if possible\n        } else {\n          value = elementControllers && elementControllers[name];\n          value = value && value.instance;\n        }\n\n        if (!value) {\n          var dataName = '$' + name + 'Controller';\n          value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);\n        }\n\n        if (!value && !optional) {\n          throw $compileMinErr('ctreq',\n              'Controller \\'{0}\\', required by directive \\'{1}\\', can\\'t be found!',\n              name, directiveName);\n        }\n      } else if (isArray(require)) {\n        value = [];\n        for (var i = 0, ii = require.length; i < ii; i++) {\n          value[i] = getControllers(directiveName, require[i], $element, elementControllers);\n        }\n      } else if (isObject(require)) {\n        value = {};\n        forEach(require, function(controller, property) {\n          value[property] = getControllers(directiveName, controller, $element, elementControllers);\n        });\n      }\n\n      return value || null;\n    }\n\n    function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective) {\n      var elementControllers = createMap();\n      for (var controllerKey in controllerDirectives) {\n        var directive = controllerDirectives[controllerKey];\n        var locals = {\n          $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,\n          $element: $element,\n          $attrs: attrs,\n          $transclude: transcludeFn\n        };\n\n        var controller = directive.controller;\n        if (controller === '@') {\n          controller = attrs[directive.name];\n        }\n\n        var controllerInstance = $controller(controller, locals, true, directive.controllerAs);\n\n        // For directives with element transclusion the element is a comment.\n        // In this case .data will not attach any data.\n        // Instead, we save the controllers for the element in a local hash and attach to .data\n        // later, once we have the actual element.\n        elementControllers[directive.name] = controllerInstance;\n        $element.data('$' + directive.name + 'Controller', controllerInstance.instance);\n      }\n      return elementControllers;\n    }\n\n    // Depending upon the context in which a directive finds itself it might need to have a new isolated\n    // or child scope created. For instance:\n    // * if the directive has been pulled into a template because another directive with a higher priority\n    // asked for element transclusion\n    // * if the directive itself asks for transclusion but it is at the root of a template and the original\n    // element was replaced. See https://github.com/angular/angular.js/issues/12936\n    function markDirectiveScope(directives, isolateScope, newScope) {\n      for (var j = 0, jj = directives.length; j < jj; j++) {\n        directives[j] = inherit(directives[j], {$$isolateScope: isolateScope, $$newScope: newScope});\n      }\n    }\n\n    /**\n     * looks up the directive and decorates it with exception handling and proper parameters. We\n     * call this the boundDirective.\n     *\n     * @param {string} name name of the directive to look up.\n     * @param {string} location The directive must be found in specific format.\n     *   String containing any of theses characters:\n     *\n     *   * `E`: element name\n     *   * `A': attribute\n     *   * `C`: class\n     *   * `M`: comment\n     * @returns {boolean} true if directive was added.\n     */\n    function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName,\n                          endAttrName) {\n      if (name === ignoreDirective) return null;\n      var match = null;\n      if (hasDirectives.hasOwnProperty(name)) {\n        for (var directive, directives = $injector.get(name + Suffix),\n            i = 0, ii = directives.length; i < ii; i++) {\n          directive = directives[i];\n          if ((isUndefined(maxPriority) || maxPriority > directive.priority) &&\n               directive.restrict.indexOf(location) !== -1) {\n            if (startAttrName) {\n              directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});\n            }\n            if (!directive.$$bindings) {\n              var bindings = directive.$$bindings =\n                  parseDirectiveBindings(directive, directive.name);\n              if (isObject(bindings.isolateScope)) {\n                directive.$$isolateBindings = bindings.isolateScope;\n              }\n            }\n            tDirectives.push(directive);\n            match = directive;\n          }\n        }\n      }\n      return match;\n    }\n\n\n    /**\n     * looks up the directive and returns true if it is a multi-element directive,\n     * and therefore requires DOM nodes between -start and -end markers to be grouped\n     * together.\n     *\n     * @param {string} name name of the directive to look up.\n     * @returns true if directive was registered as multi-element.\n     */\n    function directiveIsMultiElement(name) {\n      if (hasDirectives.hasOwnProperty(name)) {\n        for (var directive, directives = $injector.get(name + Suffix),\n            i = 0, ii = directives.length; i < ii; i++) {\n          directive = directives[i];\n          if (directive.multiElement) {\n            return true;\n          }\n        }\n      }\n      return false;\n    }\n\n    /**\n     * When the element is replaced with HTML template then the new attributes\n     * on the template need to be merged with the existing attributes in the DOM.\n     * The desired effect is to have both of the attributes present.\n     *\n     * @param {object} dst destination attributes (original DOM)\n     * @param {object} src source attributes (from the directive template)\n     */\n    function mergeTemplateAttributes(dst, src) {\n      var srcAttr = src.$attr,\n          dstAttr = dst.$attr;\n\n      // reapply the old attributes to the new element\n      forEach(dst, function(value, key) {\n        if (key.charAt(0) !== '$') {\n          if (src[key] && src[key] !== value) {\n            if (value.length) {\n              value += (key === 'style' ? ';' : ' ') + src[key];\n            } else {\n              value = src[key];\n            }\n          }\n          dst.$set(key, value, true, srcAttr[key]);\n        }\n      });\n\n      // copy the new attributes on the old attrs object\n      forEach(src, function(value, key) {\n        // Check if we already set this attribute in the loop above.\n        // `dst` will never contain hasOwnProperty as DOM parser won't let it.\n        // You will get an \"InvalidCharacterError: DOM Exception 5\" error if you\n        // have an attribute like \"has-own-property\" or \"data-has-own-property\", etc.\n        if (!dst.hasOwnProperty(key) && key.charAt(0) !== '$') {\n          dst[key] = value;\n\n          if (key !== 'class' && key !== 'style') {\n            dstAttr[key] = srcAttr[key];\n          }\n        }\n      });\n    }\n\n\n    function compileTemplateUrl(directives, $compileNode, tAttrs,\n        $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {\n      var linkQueue = [],\n          afterTemplateNodeLinkFn,\n          afterTemplateChildLinkFn,\n          beforeTemplateCompileNode = $compileNode[0],\n          origAsyncDirective = directives.shift(),\n          derivedSyncDirective = inherit(origAsyncDirective, {\n            templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective\n          }),\n          templateUrl = (isFunction(origAsyncDirective.templateUrl))\n              ? origAsyncDirective.templateUrl($compileNode, tAttrs)\n              : origAsyncDirective.templateUrl,\n          templateNamespace = origAsyncDirective.templateNamespace;\n\n      $compileNode.empty();\n\n      $templateRequest(templateUrl)\n        .then(function(content) {\n          var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;\n\n          content = denormalizeTemplate(content);\n\n          if (origAsyncDirective.replace) {\n            if (jqLiteIsTextNode(content)) {\n              $template = [];\n            } else {\n              $template = removeComments(wrapTemplate(templateNamespace, trim(content)));\n            }\n            compileNode = $template[0];\n\n            if ($template.length !== 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {\n              throw $compileMinErr('tplrt',\n                  'Template for directive \\'{0}\\' must have exactly one root element. {1}',\n                  origAsyncDirective.name, templateUrl);\n            }\n\n            tempTemplateAttrs = {$attr: {}};\n            replaceWith($rootElement, $compileNode, compileNode);\n            var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs);\n\n            if (isObject(origAsyncDirective.scope)) {\n              // the original directive that caused the template to be loaded async required\n              // an isolate scope\n              markDirectiveScope(templateDirectives, true);\n            }\n            directives = templateDirectives.concat(directives);\n            mergeTemplateAttributes(tAttrs, tempTemplateAttrs);\n          } else {\n            compileNode = beforeTemplateCompileNode;\n            $compileNode.html(content);\n          }\n\n          directives.unshift(derivedSyncDirective);\n\n          afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs,\n              childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns,\n              previousCompileContext);\n          forEach($rootElement, function(node, i) {\n            if (node === compileNode) {\n              $rootElement[i] = $compileNode[0];\n            }\n          });\n          afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);\n\n          while (linkQueue.length) {\n            var scope = linkQueue.shift(),\n                beforeTemplateLinkNode = linkQueue.shift(),\n                linkRootElement = linkQueue.shift(),\n                boundTranscludeFn = linkQueue.shift(),\n                linkNode = $compileNode[0];\n\n            if (scope.$$destroyed) continue;\n\n            if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {\n              var oldClasses = beforeTemplateLinkNode.className;\n\n              if (!(previousCompileContext.hasElementTranscludeDirective &&\n                  origAsyncDirective.replace)) {\n                // it was cloned therefore we have to clone as well.\n                linkNode = jqLiteClone(compileNode);\n              }\n              replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);\n\n              // Copy in CSS classes from original node\n              safeAddClass(jqLite(linkNode), oldClasses);\n            }\n            if (afterTemplateNodeLinkFn.transcludeOnThisElement) {\n              childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);\n            } else {\n              childBoundTranscludeFn = boundTranscludeFn;\n            }\n            afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,\n              childBoundTranscludeFn);\n          }\n          linkQueue = null;\n        }).catch(function(error) {\n          if (error instanceof Error) {\n            $exceptionHandler(error);\n          }\n        });\n\n      return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {\n        var childBoundTranscludeFn = boundTranscludeFn;\n        if (scope.$$destroyed) return;\n        if (linkQueue) {\n          linkQueue.push(scope,\n                         node,\n                         rootElement,\n                         childBoundTranscludeFn);\n        } else {\n          if (afterTemplateNodeLinkFn.transcludeOnThisElement) {\n            childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);\n          }\n          afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn);\n        }\n      };\n    }\n\n\n    /**\n     * Sorting function for bound directives.\n     */\n    function byPriority(a, b) {\n      var diff = b.priority - a.priority;\n      if (diff !== 0) return diff;\n      if (a.name !== b.name) return (a.name < b.name) ? -1 : 1;\n      return a.index - b.index;\n    }\n\n    function assertNoDuplicate(what, previousDirective, directive, element) {\n\n      function wrapModuleNameIfDefined(moduleName) {\n        return moduleName ?\n          (' (module: ' + moduleName + ')') :\n          '';\n      }\n\n      if (previousDirective) {\n        throw $compileMinErr('multidir', 'Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}',\n            previousDirective.name, wrapModuleNameIfDefined(previousDirective.$$moduleName),\n            directive.name, wrapModuleNameIfDefined(directive.$$moduleName), what, startingTag(element));\n      }\n    }\n\n\n    function addTextInterpolateDirective(directives, text) {\n      var interpolateFn = $interpolate(text, true);\n      if (interpolateFn) {\n        directives.push({\n          priority: 0,\n          compile: function textInterpolateCompileFn(templateNode) {\n            var templateNodeParent = templateNode.parent(),\n                hasCompileParent = !!templateNodeParent.length;\n\n            // When transcluding a template that has bindings in the root\n            // we don't have a parent and thus need to add the class during linking fn.\n            if (hasCompileParent) compile.$$addBindingClass(templateNodeParent);\n\n            return function textInterpolateLinkFn(scope, node) {\n              var parent = node.parent();\n              if (!hasCompileParent) compile.$$addBindingClass(parent);\n              compile.$$addBindingInfo(parent, interpolateFn.expressions);\n              scope.$watch(interpolateFn, function interpolateFnWatchAction(value) {\n                node[0].nodeValue = value;\n              });\n            };\n          }\n        });\n      }\n    }\n\n\n    function wrapTemplate(type, template) {\n      type = lowercase(type || 'html');\n      switch (type) {\n      case 'svg':\n      case 'math':\n        var wrapper = window.document.createElement('div');\n        wrapper.innerHTML = '<' + type + '>' + template + '</' + type + '>';\n        return wrapper.childNodes[0].childNodes;\n      default:\n        return template;\n      }\n    }\n\n\n    function getTrustedContext(node, attrNormalizedName) {\n      if (attrNormalizedName === 'srcdoc') {\n        return $sce.HTML;\n      }\n      var tag = nodeName_(node);\n      // All tags with src attributes require a RESOURCE_URL value, except for\n      // img and various html5 media tags.\n      if (attrNormalizedName === 'src' || attrNormalizedName === 'ngSrc') {\n        if (['img', 'video', 'audio', 'source', 'track'].indexOf(tag) === -1) {\n          return $sce.RESOURCE_URL;\n        }\n      // maction[xlink:href] can source SVG.  It's not limited to <maction>.\n      } else if (attrNormalizedName === 'xlinkHref' ||\n          (tag === 'form' && attrNormalizedName === 'action') ||\n          // links can be stylesheets or imports, which can run script in the current origin\n          (tag === 'link' && attrNormalizedName === 'href')\n      ) {\n        return $sce.RESOURCE_URL;\n      }\n    }\n\n\n    function addAttrInterpolateDirective(node, directives, value, name, isNgAttr) {\n      var trustedContext = getTrustedContext(node, name);\n      var mustHaveExpression = !isNgAttr;\n      var allOrNothing = ALL_OR_NOTHING_ATTRS[name] || isNgAttr;\n\n      var interpolateFn = $interpolate(value, mustHaveExpression, trustedContext, allOrNothing);\n\n      // no interpolation found -> ignore\n      if (!interpolateFn) return;\n\n      if (name === 'multiple' && nodeName_(node) === 'select') {\n        throw $compileMinErr('selmulti',\n            'Binding to the \\'multiple\\' attribute is not supported. Element: {0}',\n            startingTag(node));\n      }\n\n      if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {\n        throw $compileMinErr('nodomevents',\n            'Interpolations for HTML DOM event attributes are disallowed.  Please use the ' +\n                'ng- versions (such as ng-click instead of onclick) instead.');\n      }\n\n      directives.push({\n        priority: 100,\n        compile: function() {\n            return {\n              pre: function attrInterpolatePreLinkFn(scope, element, attr) {\n                var $$observers = (attr.$$observers || (attr.$$observers = createMap()));\n\n                // If the attribute has changed since last $interpolate()ed\n                var newValue = attr[name];\n                if (newValue !== value) {\n                  // we need to interpolate again since the attribute value has been updated\n                  // (e.g. by another directive's compile function)\n                  // ensure unset/empty values make interpolateFn falsy\n                  interpolateFn = newValue && $interpolate(newValue, true, trustedContext, allOrNothing);\n                  value = newValue;\n                }\n\n                // if attribute was updated so that there is no interpolation going on we don't want to\n                // register any observers\n                if (!interpolateFn) return;\n\n                // initialize attr object so that it's ready in case we need the value for isolate\n                // scope initialization, otherwise the value would not be available from isolate\n                // directive's linking fn during linking phase\n                attr[name] = interpolateFn(scope);\n\n                ($$observers[name] || ($$observers[name] = [])).$$inter = true;\n                (attr.$$observers && attr.$$observers[name].$$scope || scope).\n                  $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {\n                    //special case for class attribute addition + removal\n                    //so that class changes can tap into the animation\n                    //hooks provided by the $animate service. Be sure to\n                    //skip animations when the first digest occurs (when\n                    //both the new and the old values are the same) since\n                    //the CSS classes are the non-interpolated values\n                    if (name === 'class' && newValue !== oldValue) {\n                      attr.$updateClass(newValue, oldValue);\n                    } else {\n                      attr.$set(name, newValue);\n                    }\n                  });\n              }\n            };\n          }\n      });\n    }\n\n\n    /**\n     * This is a special jqLite.replaceWith, which can replace items which\n     * have no parents, provided that the containing jqLite collection is provided.\n     *\n     * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes\n     *                               in the root of the tree.\n     * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep\n     *                                  the shell, but replace its DOM node reference.\n     * @param {Node} newNode The new DOM node.\n     */\n    function replaceWith($rootElement, elementsToRemove, newNode) {\n      var firstElementToRemove = elementsToRemove[0],\n          removeCount = elementsToRemove.length,\n          parent = firstElementToRemove.parentNode,\n          i, ii;\n\n      if ($rootElement) {\n        for (i = 0, ii = $rootElement.length; i < ii; i++) {\n          if ($rootElement[i] === firstElementToRemove) {\n            $rootElement[i++] = newNode;\n            for (var j = i, j2 = j + removeCount - 1,\n                     jj = $rootElement.length;\n                 j < jj; j++, j2++) {\n              if (j2 < jj) {\n                $rootElement[j] = $rootElement[j2];\n              } else {\n                delete $rootElement[j];\n              }\n            }\n            $rootElement.length -= removeCount - 1;\n\n            // If the replaced element is also the jQuery .context then replace it\n            // .context is a deprecated jQuery api, so we should set it only when jQuery set it\n            // http://api.jquery.com/context/\n            if ($rootElement.context === firstElementToRemove) {\n              $rootElement.context = newNode;\n            }\n            break;\n          }\n        }\n      }\n\n      if (parent) {\n        parent.replaceChild(newNode, firstElementToRemove);\n      }\n\n      // Append all the `elementsToRemove` to a fragment. This will...\n      // - remove them from the DOM\n      // - allow them to still be traversed with .nextSibling\n      // - allow a single fragment.qSA to fetch all elements being removed\n      var fragment = window.document.createDocumentFragment();\n      for (i = 0; i < removeCount; i++) {\n        fragment.appendChild(elementsToRemove[i]);\n      }\n\n      if (jqLite.hasData(firstElementToRemove)) {\n        // Copy over user data (that includes Angular's $scope etc.). Don't copy private\n        // data here because there's no public interface in jQuery to do that and copying over\n        // event listeners (which is the main use of private data) wouldn't work anyway.\n        jqLite.data(newNode, jqLite.data(firstElementToRemove));\n\n        // Remove $destroy event listeners from `firstElementToRemove`\n        jqLite(firstElementToRemove).off('$destroy');\n      }\n\n      // Cleanup any data/listeners on the elements and children.\n      // This includes invoking the $destroy event on any elements with listeners.\n      jqLite.cleanData(fragment.querySelectorAll('*'));\n\n      // Update the jqLite collection to only contain the `newNode`\n      for (i = 1; i < removeCount; i++) {\n        delete elementsToRemove[i];\n      }\n      elementsToRemove[0] = newNode;\n      elementsToRemove.length = 1;\n    }\n\n\n    function cloneAndAnnotateFn(fn, annotation) {\n      return extend(function() { return fn.apply(null, arguments); }, fn, annotation);\n    }\n\n\n    function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) {\n      try {\n        linkFn(scope, $element, attrs, controllers, transcludeFn);\n      } catch (e) {\n        $exceptionHandler(e, startingTag($element));\n      }\n    }\n\n\n    // Set up $watches for isolate scope and controller bindings.\n    function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) {\n      var removeWatchCollection = [];\n      var initialChanges = {};\n      var changes;\n      forEach(bindings, function initializeBinding(definition, scopeName) {\n        var attrName = definition.attrName,\n        optional = definition.optional,\n        mode = definition.mode, // @, =, <, or &\n        lastValue,\n        parentGet, parentSet, compare, removeWatch;\n\n        switch (mode) {\n\n          case '@':\n            if (!optional && !hasOwnProperty.call(attrs, attrName)) {\n              destination[scopeName] = attrs[attrName] = undefined;\n            }\n            removeWatch = attrs.$observe(attrName, function(value) {\n              if (isString(value) || isBoolean(value)) {\n                var oldValue = destination[scopeName];\n                recordChanges(scopeName, value, oldValue);\n                destination[scopeName] = value;\n              }\n            });\n            attrs.$$observers[attrName].$$scope = scope;\n            lastValue = attrs[attrName];\n            if (isString(lastValue)) {\n              // If the attribute has been provided then we trigger an interpolation to ensure\n              // the value is there for use in the link fn\n              destination[scopeName] = $interpolate(lastValue)(scope);\n            } else if (isBoolean(lastValue)) {\n              // If the attributes is one of the BOOLEAN_ATTR then Angular will have converted\n              // the value to boolean rather than a string, so we special case this situation\n              destination[scopeName] = lastValue;\n            }\n            initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);\n            removeWatchCollection.push(removeWatch);\n            break;\n\n          case '=':\n            if (!hasOwnProperty.call(attrs, attrName)) {\n              if (optional) break;\n              attrs[attrName] = undefined;\n            }\n            if (optional && !attrs[attrName]) break;\n\n            parentGet = $parse(attrs[attrName]);\n            if (parentGet.literal) {\n              compare = equals;\n            } else {\n              // eslint-disable-next-line no-self-compare\n              compare = function simpleCompare(a, b) { return a === b || (a !== a && b !== b); };\n            }\n            parentSet = parentGet.assign || function() {\n              // reset the change, or we will throw this exception on every $digest\n              lastValue = destination[scopeName] = parentGet(scope);\n              throw $compileMinErr('nonassign',\n                  'Expression \\'{0}\\' in attribute \\'{1}\\' used with directive \\'{2}\\' is non-assignable!',\n                  attrs[attrName], attrName, directive.name);\n            };\n            lastValue = destination[scopeName] = parentGet(scope);\n            var parentValueWatch = function parentValueWatch(parentValue) {\n              if (!compare(parentValue, destination[scopeName])) {\n                // we are out of sync and need to copy\n                if (!compare(parentValue, lastValue)) {\n                  // parent changed and it has precedence\n                  destination[scopeName] = parentValue;\n                } else {\n                  // if the parent can be assigned then do so\n                  parentSet(scope, parentValue = destination[scopeName]);\n                }\n              }\n              lastValue = parentValue;\n              return lastValue;\n            };\n            parentValueWatch.$stateful = true;\n            if (definition.collection) {\n              removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch);\n            } else {\n              removeWatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);\n            }\n            removeWatchCollection.push(removeWatch);\n            break;\n\n          case '<':\n            if (!hasOwnProperty.call(attrs, attrName)) {\n              if (optional) break;\n              attrs[attrName] = undefined;\n            }\n            if (optional && !attrs[attrName]) break;\n\n            parentGet = $parse(attrs[attrName]);\n            var deepWatch = parentGet.literal;\n\n            var initialValue = destination[scopeName] = parentGet(scope);\n            initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);\n\n            removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newValue, oldValue) {\n              if (oldValue === newValue) {\n                if (oldValue === initialValue || (deepWatch && equals(oldValue, initialValue))) {\n                  return;\n                }\n                oldValue = initialValue;\n              }\n              recordChanges(scopeName, newValue, oldValue);\n              destination[scopeName] = newValue;\n            }, deepWatch);\n\n            removeWatchCollection.push(removeWatch);\n            break;\n\n          case '&':\n            // Don't assign Object.prototype method to scope\n            parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop;\n\n            // Don't assign noop to destination if expression is not valid\n            if (parentGet === noop && optional) break;\n\n            destination[scopeName] = function(locals) {\n              return parentGet(scope, locals);\n            };\n            break;\n        }\n      });\n\n      function recordChanges(key, currentValue, previousValue) {\n        if (isFunction(destination.$onChanges) && currentValue !== previousValue &&\n            // eslint-disable-next-line no-self-compare\n            (currentValue === currentValue || previousValue === previousValue)) {\n          // If we have not already scheduled the top level onChangesQueue handler then do so now\n          if (!onChangesQueue) {\n            scope.$$postDigest(flushOnChangesQueue);\n            onChangesQueue = [];\n          }\n          // If we have not already queued a trigger of onChanges for this controller then do so now\n          if (!changes) {\n            changes = {};\n            onChangesQueue.push(triggerOnChangesHook);\n          }\n          // If the has been a change on this property already then we need to reuse the previous value\n          if (changes[key]) {\n            previousValue = changes[key].previousValue;\n          }\n          // Store this change\n          changes[key] = new SimpleChange(previousValue, currentValue);\n        }\n      }\n\n      function triggerOnChangesHook() {\n        destination.$onChanges(changes);\n        // Now clear the changes so that we schedule onChanges when more changes arrive\n        changes = undefined;\n      }\n\n      return {\n        initialChanges: initialChanges,\n        removeWatches: removeWatchCollection.length && function removeWatches() {\n          for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) {\n            removeWatchCollection[i]();\n          }\n        }\n      };\n    }\n  }];\n}\n\nfunction SimpleChange(previous, current) {\n  this.previousValue = previous;\n  this.currentValue = current;\n}\nSimpleChange.prototype.isFirstChange = function() { return this.previousValue === _UNINITIALIZED_VALUE; };\n\n\nvar PREFIX_REGEXP = /^((?:x|data)[:\\-_])/i;\nvar SPECIAL_CHARS_REGEXP = /[:\\-_]+(.)/g;\n\n/**\n * Converts all accepted directives format into proper directive name.\n * @param name Name to normalize\n */\nfunction directiveNormalize(name) {\n  return name\n    .replace(PREFIX_REGEXP, '')\n    .replace(SPECIAL_CHARS_REGEXP, fnCamelCaseReplace);\n}\n\n/**\n * @ngdoc type\n * @name $compile.directive.Attributes\n *\n * @description\n * A shared object between directive compile / linking functions which contains normalized DOM\n * element attributes. The values reflect current binding state `{{ }}`. The normalization is\n * needed since all of these are treated as equivalent in Angular:\n *\n * ```\n *    <span ng:bind=\"a\" ng-bind=\"a\" data-ng-bind=\"a\" x-ng-bind=\"a\">\n * ```\n */\n\n/**\n * @ngdoc property\n * @name $compile.directive.Attributes#$attr\n *\n * @description\n * A map of DOM element attribute names to the normalized name. This is\n * needed to do reverse lookup from normalized name back to actual name.\n */\n\n\n/**\n * @ngdoc method\n * @name $compile.directive.Attributes#$set\n * @kind function\n *\n * @description\n * Set DOM element attribute value.\n *\n *\n * @param {string} name Normalized element attribute name of the property to modify. The name is\n *          reverse-translated using the {@link ng.$compile.directive.Attributes#$attr $attr}\n *          property to the original name.\n * @param {string} value Value to set the attribute to. The value can be an interpolated string.\n */\n\n\n\n/**\n * Closure compiler type information\n */\n\nfunction nodesetLinkingFn(\n  /* angular.Scope */ scope,\n  /* NodeList */ nodeList,\n  /* Element */ rootElement,\n  /* function(Function) */ boundTranscludeFn\n) {}\n\nfunction directiveLinkingFn(\n  /* nodesetLinkingFn */ nodesetLinkingFn,\n  /* angular.Scope */ scope,\n  /* Node */ node,\n  /* Element */ rootElement,\n  /* function(Function) */ boundTranscludeFn\n) {}\n\nfunction tokenDifference(str1, str2) {\n  var values = '',\n      tokens1 = str1.split(/\\s+/),\n      tokens2 = str2.split(/\\s+/);\n\n  outer:\n  for (var i = 0; i < tokens1.length; i++) {\n    var token = tokens1[i];\n    for (var j = 0; j < tokens2.length; j++) {\n      if (token === tokens2[j]) continue outer;\n    }\n    values += (values.length > 0 ? ' ' : '') + token;\n  }\n  return values;\n}\n\nfunction removeComments(jqNodes) {\n  jqNodes = jqLite(jqNodes);\n  var i = jqNodes.length;\n\n  if (i <= 1) {\n    return jqNodes;\n  }\n\n  while (i--) {\n    var node = jqNodes[i];\n    if (node.nodeType === NODE_TYPE_COMMENT ||\n       (node.nodeType === NODE_TYPE_TEXT && node.nodeValue.trim() === '')) {\n         splice.call(jqNodes, i, 1);\n    }\n  }\n  return jqNodes;\n}\n\nvar $controllerMinErr = minErr('$controller');\n\n\nvar CNTRL_REG = /^(\\S+)(\\s+as\\s+([\\w$]+))?$/;\nfunction identifierForController(controller, ident) {\n  if (ident && isString(ident)) return ident;\n  if (isString(controller)) {\n    var match = CNTRL_REG.exec(controller);\n    if (match) return match[3];\n  }\n}\n\n\n/**\n * @ngdoc provider\n * @name $controllerProvider\n * @this\n *\n * @description\n * The {@link ng.$controller $controller service} is used by Angular to create new\n * controllers.\n *\n * This provider allows controller registration via the\n * {@link ng.$controllerProvider#register register} method.\n */\nfunction $ControllerProvider() {\n  var controllers = {},\n      globals = false;\n\n  /**\n   * @ngdoc method\n   * @name $controllerProvider#has\n   * @param {string} name Controller name to check.\n   */\n  this.has = function(name) {\n    return controllers.hasOwnProperty(name);\n  };\n\n  /**\n   * @ngdoc method\n   * @name $controllerProvider#register\n   * @param {string|Object} name Controller name, or an object map of controllers where the keys are\n   *    the names and the values are the constructors.\n   * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI\n   *    annotations in the array notation).\n   */\n  this.register = function(name, constructor) {\n    assertNotHasOwnProperty(name, 'controller');\n    if (isObject(name)) {\n      extend(controllers, name);\n    } else {\n      controllers[name] = constructor;\n    }\n  };\n\n  /**\n   * @ngdoc method\n   * @name $controllerProvider#allowGlobals\n   * @description If called, allows `$controller` to find controller constructors on `window`\n   *\n   * @deprecated\n   * sinceVersion=\"v1.3.0\"\n   * removeVersion=\"v1.7.0\"\n   * This method of finding controllers has been deprecated.\n   */\n  this.allowGlobals = function() {\n    globals = true;\n  };\n\n\n  this.$get = ['$injector', '$window', function($injector, $window) {\n\n    /**\n     * @ngdoc service\n     * @name $controller\n     * @requires $injector\n     *\n     * @param {Function|string} constructor If called with a function then it's considered to be the\n     *    controller constructor function. Otherwise it's considered to be a string which is used\n     *    to retrieve the controller constructor using the following steps:\n     *\n     *    * check if a controller with given name is registered via `$controllerProvider`\n     *    * check if evaluating the string on the current scope returns a constructor\n     *    * if $controllerProvider#allowGlobals, check `window[constructor]` on the global\n     *      `window` object (deprecated, not recommended)\n     *\n     *    The string can use the `controller as property` syntax, where the controller instance is published\n     *    as the specified property on the `scope`; the `scope` must be injected into `locals` param for this\n     *    to work correctly.\n     *\n     * @param {Object} locals Injection locals for Controller.\n     * @return {Object} Instance of given controller.\n     *\n     * @description\n     * `$controller` service is responsible for instantiating controllers.\n     *\n     * It's just a simple call to {@link auto.$injector $injector}, but extracted into\n     * a service, so that one can override this service with [BC version](https://gist.github.com/1649788).\n     */\n    return function $controller(expression, locals, later, ident) {\n      // PRIVATE API:\n      //   param `later` --- indicates that the controller's constructor is invoked at a later time.\n      //                     If true, $controller will allocate the object with the correct\n      //                     prototype chain, but will not invoke the controller until a returned\n      //                     callback is invoked.\n      //   param `ident` --- An optional label which overrides the label parsed from the controller\n      //                     expression, if any.\n      var instance, match, constructor, identifier;\n      later = later === true;\n      if (ident && isString(ident)) {\n        identifier = ident;\n      }\n\n      if (isString(expression)) {\n        match = expression.match(CNTRL_REG);\n        if (!match) {\n          throw $controllerMinErr('ctrlfmt',\n            'Badly formed controller string \\'{0}\\'. ' +\n            'Must match `__name__ as __id__` or `__name__`.', expression);\n        }\n        constructor = match[1];\n        identifier = identifier || match[3];\n        expression = controllers.hasOwnProperty(constructor)\n            ? controllers[constructor]\n            : getter(locals.$scope, constructor, true) ||\n                (globals ? getter($window, constructor, true) : undefined);\n\n        if (!expression) {\n          throw $controllerMinErr('ctrlreg',\n            'The controller with the name \\'{0}\\' is not registered.', constructor);\n        }\n\n        assertArgFn(expression, constructor, true);\n      }\n\n      if (later) {\n        // Instantiate controller later:\n        // This machinery is used to create an instance of the object before calling the\n        // controller's constructor itself.\n        //\n        // This allows properties to be added to the controller before the constructor is\n        // invoked. Primarily, this is used for isolate scope bindings in $compile.\n        //\n        // This feature is not intended for use by applications, and is thus not documented\n        // publicly.\n        // Object creation: http://jsperf.com/create-constructor/2\n        var controllerPrototype = (isArray(expression) ?\n          expression[expression.length - 1] : expression).prototype;\n        instance = Object.create(controllerPrototype || null);\n\n        if (identifier) {\n          addIdentifier(locals, identifier, instance, constructor || expression.name);\n        }\n\n        return extend(function $controllerInit() {\n          var result = $injector.invoke(expression, instance, locals, constructor);\n          if (result !== instance && (isObject(result) || isFunction(result))) {\n            instance = result;\n            if (identifier) {\n              // If result changed, re-assign controllerAs value to scope.\n              addIdentifier(locals, identifier, instance, constructor || expression.name);\n            }\n          }\n          return instance;\n        }, {\n          instance: instance,\n          identifier: identifier\n        });\n      }\n\n      instance = $injector.instantiate(expression, locals, constructor);\n\n      if (identifier) {\n        addIdentifier(locals, identifier, instance, constructor || expression.name);\n      }\n\n      return instance;\n    };\n\n    function addIdentifier(locals, identifier, instance, name) {\n      if (!(locals && isObject(locals.$scope))) {\n        throw minErr('$controller')('noscp',\n          'Cannot export controller \\'{0}\\' as \\'{1}\\'! No $scope object provided via `locals`.',\n          name, identifier);\n      }\n\n      locals.$scope[identifier] = instance;\n    }\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $document\n * @requires $window\n * @this\n *\n * @description\n * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object.\n *\n * @example\n   <example module=\"documentExample\" name=\"document\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <p>$document title: <b ng-bind=\"title\"></b></p>\n         <p>window.document title: <b ng-bind=\"windowTitle\"></b></p>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('documentExample', [])\n         .controller('ExampleController', ['$scope', '$document', function($scope, $document) {\n           $scope.title = $document[0].title;\n           $scope.windowTitle = angular.element(window.document)[0].title;\n         }]);\n     </file>\n   </example>\n */\nfunction $DocumentProvider() {\n  this.$get = ['$window', function(window) {\n    return jqLite(window.document);\n  }];\n}\n\n\n/**\n * @private\n * @this\n * Listens for document visibility change and makes the current status accessible.\n */\nfunction $$IsDocumentHiddenProvider() {\n  this.$get = ['$document', '$rootScope', function($document, $rootScope) {\n    var doc = $document[0];\n    var hidden = doc && doc.hidden;\n\n    $document.on('visibilitychange', changeListener);\n\n    $rootScope.$on('$destroy', function() {\n      $document.off('visibilitychange', changeListener);\n    });\n\n    function changeListener() {\n      hidden = doc.hidden;\n    }\n\n    return function() {\n      return hidden;\n    };\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $exceptionHandler\n * @requires ng.$log\n * @this\n *\n * @description\n * Any uncaught exception in angular expressions is delegated to this service.\n * The default implementation simply delegates to `$log.error` which logs it into\n * the browser console.\n *\n * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by\n * {@link ngMock.$exceptionHandler mock $exceptionHandler} which aids in testing.\n *\n * ## Example:\n *\n * The example below will overwrite the default `$exceptionHandler` in order to (a) log uncaught\n * errors to the backend for later inspection by the developers and (b) to use `$log.warn()` instead\n * of `$log.error()`.\n *\n * ```js\n *   angular.\n *     module('exceptionOverwrite', []).\n *     factory('$exceptionHandler', ['$log', 'logErrorsToBackend', function($log, logErrorsToBackend) {\n *       return function myExceptionHandler(exception, cause) {\n *         logErrorsToBackend(exception, cause);\n *         $log.warn(exception, cause);\n *       };\n *     }]);\n * ```\n *\n * <hr />\n * Note, that code executed in event-listeners (even those registered using jqLite's `on`/`bind`\n * methods) does not delegate exceptions to the {@link ng.$exceptionHandler $exceptionHandler}\n * (unless executed during a digest).\n *\n * If you wish, you can manually delegate exceptions, e.g.\n * `try { ... } catch(e) { $exceptionHandler(e); }`\n *\n * @param {Error} exception Exception associated with the error.\n * @param {string=} cause Optional information about the context in which\n *       the error was thrown.\n *\n */\nfunction $ExceptionHandlerProvider() {\n  this.$get = ['$log', function($log) {\n    return function(exception, cause) {\n      $log.error.apply($log, arguments);\n    };\n  }];\n}\n\nvar $$ForceReflowProvider = /** @this */ function() {\n  this.$get = ['$document', function($document) {\n    return function(domNode) {\n      //the line below will force the browser to perform a repaint so\n      //that all the animated elements within the animation frame will\n      //be properly updated and drawn on screen. This is required to\n      //ensure that the preparation animation is properly flushed so that\n      //the active state picks up from there. DO NOT REMOVE THIS LINE.\n      //DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH\n      //WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND\n      //WILL TAKE YEARS AWAY FROM YOUR LIFE.\n      if (domNode) {\n        if (!domNode.nodeType && domNode instanceof jqLite) {\n          domNode = domNode[0];\n        }\n      } else {\n        domNode = $document[0].body;\n      }\n      return domNode.offsetWidth + 1;\n    };\n  }];\n};\n\nvar APPLICATION_JSON = 'application/json';\nvar CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};\nvar JSON_START = /^\\[|^\\{(?!\\{)/;\nvar JSON_ENDS = {\n  '[': /]$/,\n  '{': /}$/\n};\nvar JSON_PROTECTION_PREFIX = /^\\)]\\}',?\\n/;\nvar $httpMinErr = minErr('$http');\n\nfunction serializeValue(v) {\n  if (isObject(v)) {\n    return isDate(v) ? v.toISOString() : toJson(v);\n  }\n  return v;\n}\n\n\n/** @this */\nfunction $HttpParamSerializerProvider() {\n  /**\n   * @ngdoc service\n   * @name $httpParamSerializer\n   * @description\n   *\n   * Default {@link $http `$http`} params serializer that converts objects to strings\n   * according to the following rules:\n   *\n   * * `{'foo': 'bar'}` results in `foo=bar`\n   * * `{'foo': Date.now()}` results in `foo=2015-04-01T09%3A50%3A49.262Z` (`toISOString()` and encoded representation of a Date object)\n   * * `{'foo': ['bar', 'baz']}` results in `foo=bar&foo=baz` (repeated key for each array element)\n   * * `{'foo': {'bar':'baz'}}` results in `foo=%7B%22bar%22%3A%22baz%22%7D` (stringified and encoded representation of an object)\n   *\n   * Note that serializer will sort the request parameters alphabetically.\n   * */\n\n  this.$get = function() {\n    return function ngParamSerializer(params) {\n      if (!params) return '';\n      var parts = [];\n      forEachSorted(params, function(value, key) {\n        if (value === null || isUndefined(value)) return;\n        if (isArray(value)) {\n          forEach(value, function(v) {\n            parts.push(encodeUriQuery(key)  + '=' + encodeUriQuery(serializeValue(v)));\n          });\n        } else {\n          parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value)));\n        }\n      });\n\n      return parts.join('&');\n    };\n  };\n}\n\n/** @this */\nfunction $HttpParamSerializerJQLikeProvider() {\n  /**\n   * @ngdoc service\n   * @name $httpParamSerializerJQLike\n   *\n   * @description\n   *\n   * Alternative {@link $http `$http`} params serializer that follows\n   * jQuery's [`param()`](http://api.jquery.com/jquery.param/) method logic.\n   * The serializer will also sort the params alphabetically.\n   *\n   * To use it for serializing `$http` request parameters, set it as the `paramSerializer` property:\n   *\n   * ```js\n   * $http({\n   *   url: myUrl,\n   *   method: 'GET',\n   *   params: myParams,\n   *   paramSerializer: '$httpParamSerializerJQLike'\n   * });\n   * ```\n   *\n   * It is also possible to set it as the default `paramSerializer` in the\n   * {@link $httpProvider#defaults `$httpProvider`}.\n   *\n   * Additionally, you can inject the serializer and use it explicitly, for example to serialize\n   * form data for submission:\n   *\n   * ```js\n   * .controller(function($http, $httpParamSerializerJQLike) {\n   *   //...\n   *\n   *   $http({\n   *     url: myUrl,\n   *     method: 'POST',\n   *     data: $httpParamSerializerJQLike(myData),\n   *     headers: {\n   *       'Content-Type': 'application/x-www-form-urlencoded'\n   *     }\n   *   });\n   *\n   * });\n   * ```\n   *\n   * */\n  this.$get = function() {\n    return function jQueryLikeParamSerializer(params) {\n      if (!params) return '';\n      var parts = [];\n      serialize(params, '', true);\n      return parts.join('&');\n\n      function serialize(toSerialize, prefix, topLevel) {\n        if (toSerialize === null || isUndefined(toSerialize)) return;\n        if (isArray(toSerialize)) {\n          forEach(toSerialize, function(value, index) {\n            serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');\n          });\n        } else if (isObject(toSerialize) && !isDate(toSerialize)) {\n          forEachSorted(toSerialize, function(value, key) {\n            serialize(value, prefix +\n                (topLevel ? '' : '[') +\n                key +\n                (topLevel ? '' : ']'));\n          });\n        } else {\n          parts.push(encodeUriQuery(prefix) + '=' + encodeUriQuery(serializeValue(toSerialize)));\n        }\n      }\n    };\n  };\n}\n\nfunction defaultHttpResponseTransform(data, headers) {\n  if (isString(data)) {\n    // Strip json vulnerability protection prefix and trim whitespace\n    var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim();\n\n    if (tempData) {\n      var contentType = headers('Content-Type');\n      if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {\n        data = fromJson(tempData);\n      }\n    }\n  }\n\n  return data;\n}\n\nfunction isJsonLike(str) {\n    var jsonStart = str.match(JSON_START);\n    return jsonStart && JSON_ENDS[jsonStart[0]].test(str);\n}\n\n/**\n * Parse headers into key value object\n *\n * @param {string} headers Raw headers as a string\n * @returns {Object} Parsed headers as key value object\n */\nfunction parseHeaders(headers) {\n  var parsed = createMap(), i;\n\n  function fillInParsed(key, val) {\n    if (key) {\n      parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n    }\n  }\n\n  if (isString(headers)) {\n    forEach(headers.split('\\n'), function(line) {\n      i = line.indexOf(':');\n      fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1)));\n    });\n  } else if (isObject(headers)) {\n    forEach(headers, function(headerVal, headerKey) {\n      fillInParsed(lowercase(headerKey), trim(headerVal));\n    });\n  }\n\n  return parsed;\n}\n\n\n/**\n * Returns a function that provides access to parsed headers.\n *\n * Headers are lazy parsed when first requested.\n * @see parseHeaders\n *\n * @param {(string|Object)} headers Headers to provide access to.\n * @returns {function(string=)} Returns a getter function which if called with:\n *\n *   - if called with an argument returns a single header value or null\n *   - if called with no arguments returns an object containing all headers.\n */\nfunction headersGetter(headers) {\n  var headersObj;\n\n  return function(name) {\n    if (!headersObj) headersObj =  parseHeaders(headers);\n\n    if (name) {\n      var value = headersObj[lowercase(name)];\n      if (value === undefined) {\n        value = null;\n      }\n      return value;\n    }\n\n    return headersObj;\n  };\n}\n\n\n/**\n * Chain all given functions\n *\n * This function is used for both request and response transforming\n *\n * @param {*} data Data to transform.\n * @param {function(string=)} headers HTTP headers getter fn.\n * @param {number} status HTTP status code of the response.\n * @param {(Function|Array.<Function>)} fns Function or an array of functions.\n * @returns {*} Transformed data.\n */\nfunction transformData(data, headers, status, fns) {\n  if (isFunction(fns)) {\n    return fns(data, headers, status);\n  }\n\n  forEach(fns, function(fn) {\n    data = fn(data, headers, status);\n  });\n\n  return data;\n}\n\n\nfunction isSuccess(status) {\n  return 200 <= status && status < 300;\n}\n\n\n/**\n * @ngdoc provider\n * @name $httpProvider\n * @this\n *\n * @description\n * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.\n * */\nfunction $HttpProvider() {\n  /**\n   * @ngdoc property\n   * @name $httpProvider#defaults\n   * @description\n   *\n   * Object containing default values for all {@link ng.$http $http} requests.\n   *\n   * - **`defaults.cache`** - {boolean|Object} - A boolean value or object created with\n   * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of HTTP responses\n   * by default. See {@link $http#caching $http Caching} for more information.\n   *\n   * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.\n   * Defaults value is `'XSRF-TOKEN'`.\n   *\n   * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the\n   * XSRF token. Defaults value is `'X-XSRF-TOKEN'`.\n   *\n   * - **`defaults.headers`** - {Object} - Default headers for all $http requests.\n   * Refer to {@link ng.$http#setting-http-headers $http} for documentation on\n   * setting default headers.\n   *     - **`defaults.headers.common`**\n   *     - **`defaults.headers.post`**\n   *     - **`defaults.headers.put`**\n   *     - **`defaults.headers.patch`**\n   *\n   *\n   * - **`defaults.paramSerializer`** - `{string|function(Object<string,string>):string}` - A function\n   *  used to the prepare string representation of request parameters (specified as an object).\n   *  If specified as string, it is interpreted as a function registered with the {@link auto.$injector $injector}.\n   *  Defaults to {@link ng.$httpParamSerializer $httpParamSerializer}.\n   *\n   * - **`defaults.jsonpCallbackParam`** - `{string}` - the name of the query parameter that passes the name of the\n   * callback in a JSONP request. The value of this parameter will be replaced with the expression generated by the\n   * {@link $jsonpCallbacks} service. Defaults to `'callback'`.\n   *\n   **/\n  var defaults = this.defaults = {\n    // transform incoming response data\n    transformResponse: [defaultHttpResponseTransform],\n\n    // transform outgoing request data\n    transformRequest: [function(d) {\n      return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d;\n    }],\n\n    // default headers\n    headers: {\n      common: {\n        'Accept': 'application/json, text/plain, */*'\n      },\n      post:   shallowCopy(CONTENT_TYPE_APPLICATION_JSON),\n      put:    shallowCopy(CONTENT_TYPE_APPLICATION_JSON),\n      patch:  shallowCopy(CONTENT_TYPE_APPLICATION_JSON)\n    },\n\n    xsrfCookieName: 'XSRF-TOKEN',\n    xsrfHeaderName: 'X-XSRF-TOKEN',\n\n    paramSerializer: '$httpParamSerializer',\n\n    jsonpCallbackParam: 'callback'\n  };\n\n  var useApplyAsync = false;\n  /**\n   * @ngdoc method\n   * @name $httpProvider#useApplyAsync\n   * @description\n   *\n   * Configure $http service to combine processing of multiple http responses received at around\n   * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in\n   * significant performance improvement for bigger applications that make many HTTP requests\n   * concurrently (common during application bootstrap).\n   *\n   * Defaults to false. If no value is specified, returns the current configured value.\n   *\n   * @param {boolean=} value If true, when requests are loaded, they will schedule a deferred\n   *    \"apply\" on the next tick, giving time for subsequent requests in a roughly ~10ms window\n   *    to load and share the same digest cycle.\n   *\n   * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.\n   *    otherwise, returns the current configured value.\n   **/\n  this.useApplyAsync = function(value) {\n    if (isDefined(value)) {\n      useApplyAsync = !!value;\n      return this;\n    }\n    return useApplyAsync;\n  };\n\n  /**\n   * @ngdoc property\n   * @name $httpProvider#interceptors\n   * @description\n   *\n   * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http}\n   * pre-processing of request or postprocessing of responses.\n   *\n   * These service factories are ordered by request, i.e. they are applied in the same order as the\n   * array, on request, but reverse order, on response.\n   *\n   * {@link ng.$http#interceptors Interceptors detailed info}\n   **/\n  var interceptorFactories = this.interceptors = [];\n\n  this.$get = ['$browser', '$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector', '$sce',\n      function($browser, $httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector, $sce) {\n\n    var defaultCache = $cacheFactory('$http');\n\n    /**\n     * Make sure that default param serializer is exposed as a function\n     */\n    defaults.paramSerializer = isString(defaults.paramSerializer) ?\n      $injector.get(defaults.paramSerializer) : defaults.paramSerializer;\n\n    /**\n     * Interceptors stored in reverse order. Inner interceptors before outer interceptors.\n     * The reversal is needed so that we can build up the interception chain around the\n     * server request.\n     */\n    var reversedInterceptors = [];\n\n    forEach(interceptorFactories, function(interceptorFactory) {\n      reversedInterceptors.unshift(isString(interceptorFactory)\n          ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));\n    });\n\n    /**\n     * @ngdoc service\n     * @kind function\n     * @name $http\n     * @requires ng.$httpBackend\n     * @requires $cacheFactory\n     * @requires $rootScope\n     * @requires $q\n     * @requires $injector\n     *\n     * @description\n     * The `$http` service is a core Angular service that facilitates communication with the remote\n     * HTTP servers via the browser's [XMLHttpRequest](https://developer.mozilla.org/en/xmlhttprequest)\n     * object or via [JSONP](http://en.wikipedia.org/wiki/JSONP).\n     *\n     * For unit testing applications that use `$http` service, see\n     * {@link ngMock.$httpBackend $httpBackend mock}.\n     *\n     * For a higher level of abstraction, please check out the {@link ngResource.$resource\n     * $resource} service.\n     *\n     * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by\n     * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage\n     * it is important to familiarize yourself with these APIs and the guarantees they provide.\n     *\n     *\n     * ## General usage\n     * The `$http` service is a function which takes a single argument — a {@link $http#usage configuration object} —\n     * that is used to generate an HTTP request and returns  a {@link ng.$q promise}.\n     *\n     * ```js\n     *   // Simple GET request example:\n     *   $http({\n     *     method: 'GET',\n     *     url: '/someUrl'\n     *   }).then(function successCallback(response) {\n     *       // this callback will be called asynchronously\n     *       // when the response is available\n     *     }, function errorCallback(response) {\n     *       // called asynchronously if an error occurs\n     *       // or server returns response with an error status.\n     *     });\n     * ```\n     *\n     * The response object has these properties:\n     *\n     *   - **data** – `{string|Object}` – The response body transformed with the transform\n     *     functions.\n     *   - **status** – `{number}` – HTTP status code of the response.\n     *   - **headers** – `{function([headerName])}` – Header getter function.\n     *   - **config** – `{Object}` – The configuration object that was used to generate the request.\n     *   - **statusText** – `{string}` – HTTP status text of the response.\n     *\n     * A response status code between 200 and 299 is considered a success status and will result in\n     * the success callback being called. Any response status code outside of that range is\n     * considered an error status and will result in the error callback being called.\n     * Also, status codes less than -1 are normalized to zero. -1 usually means the request was\n     * aborted, e.g. using a `config.timeout`.\n     * Note that if the response is a redirect, XMLHttpRequest will transparently follow it, meaning\n     * that the outcome (success or error) will be determined by the final response status code.\n     *\n     *\n     * ## Shortcut methods\n     *\n     * Shortcut methods are also available. All shortcut methods require passing in the URL, and\n     * request data must be passed in for POST/PUT requests. An optional config can be passed as the\n     * last argument.\n     *\n     * ```js\n     *   $http.get('/someUrl', config).then(successCallback, errorCallback);\n     *   $http.post('/someUrl', data, config).then(successCallback, errorCallback);\n     * ```\n     *\n     * Complete list of shortcut methods:\n     *\n     * - {@link ng.$http#get $http.get}\n     * - {@link ng.$http#head $http.head}\n     * - {@link ng.$http#post $http.post}\n     * - {@link ng.$http#put $http.put}\n     * - {@link ng.$http#delete $http.delete}\n     * - {@link ng.$http#jsonp $http.jsonp}\n     * - {@link ng.$http#patch $http.patch}\n     *\n     *\n     * ## Writing Unit Tests that use $http\n     * When unit testing (using {@link ngMock ngMock}), it is necessary to call\n     * {@link ngMock.$httpBackend#flush $httpBackend.flush()} to flush each pending\n     * request using trained responses.\n     *\n     * ```\n     * $httpBackend.expectGET(...);\n     * $http.get(...);\n     * $httpBackend.flush();\n     * ```\n     *\n     * ## Setting HTTP Headers\n     *\n     * The $http service will automatically add certain HTTP headers to all requests. These defaults\n     * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration\n     * object, which currently contains this default configuration:\n     *\n     * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):\n     *   - <code>Accept: application/json, text/plain, \\*&#65279;/&#65279;\\*</code>\n     * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)\n     *   - `Content-Type: application/json`\n     * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)\n     *   - `Content-Type: application/json`\n     *\n     * To add or overwrite these defaults, simply add or remove a property from these configuration\n     * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object\n     * with the lowercased HTTP method name as the key, e.g.\n     * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }`.\n     *\n     * The defaults can also be set at runtime via the `$http.defaults` object in the same\n     * fashion. For example:\n     *\n     * ```\n     * module.run(function($http) {\n     *   $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w';\n     * });\n     * ```\n     *\n     * In addition, you can supply a `headers` property in the config object passed when\n     * calling `$http(config)`, which overrides the defaults without changing them globally.\n     *\n     * To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis,\n     * Use the `headers` property, setting the desired header to `undefined`. For example:\n     *\n     * ```js\n     * var req = {\n     *  method: 'POST',\n     *  url: 'http://example.com',\n     *  headers: {\n     *    'Content-Type': undefined\n     *  },\n     *  data: { test: 'test' }\n     * }\n     *\n     * $http(req).then(function(){...}, function(){...});\n     * ```\n     *\n     * ## Transforming Requests and Responses\n     *\n     * Both requests and responses can be transformed using transformation functions: `transformRequest`\n     * and `transformResponse`. These properties can be a single function that returns\n     * the transformed value (`function(data, headersGetter, status)`) or an array of such transformation functions,\n     * which allows you to `push` or `unshift` a new transformation function into the transformation chain.\n     *\n     * <div class=\"alert alert-warning\">\n     * **Note:** Angular does not make a copy of the `data` parameter before it is passed into the `transformRequest` pipeline.\n     * That means changes to the properties of `data` are not local to the transform function (since Javascript passes objects by reference).\n     * For example, when calling `$http.get(url, $scope.myObject)`, modifications to the object's properties in a transformRequest\n     * function will be reflected on the scope and in any templates where the object is data-bound.\n     * To prevent this, transform functions should have no side-effects.\n     * If you need to modify properties, it is recommended to make a copy of the data, or create new object to return.\n     * </div>\n     *\n     * ### Default Transformations\n     *\n     * The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and\n     * `defaults.transformResponse` properties. If a request does not provide its own transformations\n     * then these will be applied.\n     *\n     * You can augment or replace the default transformations by modifying these properties by adding to or\n     * replacing the array.\n     *\n     * Angular provides the following default transformations:\n     *\n     * Request transformations (`$httpProvider.defaults.transformRequest` and `$http.defaults.transformRequest`):\n     *\n     * - If the `data` property of the request configuration object contains an object, serialize it\n     *   into JSON format.\n     *\n     * Response transformations (`$httpProvider.defaults.transformResponse` and `$http.defaults.transformResponse`):\n     *\n     *  - If XSRF prefix is detected, strip it (see Security Considerations section below).\n     *  - If JSON response is detected, deserialize it using a JSON parser.\n     *\n     *\n     * ### Overriding the Default Transformations Per Request\n     *\n     * If you wish to override the request/response transformations only for a single request then provide\n     * `transformRequest` and/or `transformResponse` properties on the configuration object passed\n     * into `$http`.\n     *\n     * Note that if you provide these properties on the config object the default transformations will be\n     * overwritten. If you wish to augment the default transformations then you must include them in your\n     * local transformation array.\n     *\n     * The following code demonstrates adding a new response transformation to be run after the default response\n     * transformations have been run.\n     *\n     * ```js\n     * function appendTransform(defaults, transform) {\n     *\n     *   // We can't guarantee that the default transformation is an array\n     *   defaults = angular.isArray(defaults) ? defaults : [defaults];\n     *\n     *   // Append the new transformation to the defaults\n     *   return defaults.concat(transform);\n     * }\n     *\n     * $http({\n     *   url: '...',\n     *   method: 'GET',\n     *   transformResponse: appendTransform($http.defaults.transformResponse, function(value) {\n     *     return doTransform(value);\n     *   })\n     * });\n     * ```\n     *\n     *\n     * ## Caching\n     *\n     * {@link ng.$http `$http`} responses are not cached by default. To enable caching, you must\n     * set the config.cache value or the default cache value to TRUE or to a cache object (created\n     * with {@link ng.$cacheFactory `$cacheFactory`}). If defined, the value of config.cache takes\n     * precedence over the default cache value.\n     *\n     * In order to:\n     *   * cache all responses - set the default cache value to TRUE or to a cache object\n     *   * cache a specific response - set config.cache value to TRUE or to a cache object\n     *\n     * If caching is enabled, but neither the default cache nor config.cache are set to a cache object,\n     * then the default `$cacheFactory(\"$http\")` object is used.\n     *\n     * The default cache value can be set by updating the\n     * {@link ng.$http#defaults `$http.defaults.cache`} property or the\n     * {@link $httpProvider#defaults `$httpProvider.defaults.cache`} property.\n     *\n     * When caching is enabled, {@link ng.$http `$http`} stores the response from the server using\n     * the relevant cache object. The next time the same request is made, the response is returned\n     * from the cache without sending a request to the server.\n     *\n     * Take note that:\n     *\n     *   * Only GET and JSONP requests are cached.\n     *   * The cache key is the request URL including search parameters; headers are not considered.\n     *   * Cached responses are returned asynchronously, in the same way as responses from the server.\n     *   * If multiple identical requests are made using the same cache, which is not yet populated,\n     *     one request will be made to the server and remaining requests will return the same response.\n     *   * A cache-control header on the response does not affect if or how responses are cached.\n     *\n     *\n     * ## Interceptors\n     *\n     * Before you start creating interceptors, be sure to understand the\n     * {@link ng.$q $q and deferred/promise APIs}.\n     *\n     * For purposes of global error handling, authentication, or any kind of synchronous or\n     * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be\n     * able to intercept requests before they are handed to the server and\n     * responses before they are handed over to the application code that\n     * initiated these requests. The interceptors leverage the {@link ng.$q\n     * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing.\n     *\n     * The interceptors are service factories that are registered with the `$httpProvider` by\n     * adding them to the `$httpProvider.interceptors` array. The factory is called and\n     * injected with dependencies (if specified) and returns the interceptor.\n     *\n     * There are two kinds of interceptors (and two kinds of rejection interceptors):\n     *\n     *   * `request`: interceptors get called with a http {@link $http#usage config} object. The function is free to\n     *     modify the `config` object or create a new one. The function needs to return the `config`\n     *     object directly, or a promise containing the `config` or a new `config` object.\n     *   * `requestError`: interceptor gets called when a previous interceptor threw an error or\n     *     resolved with a rejection.\n     *   * `response`: interceptors get called with http `response` object. The function is free to\n     *     modify the `response` object or create a new one. The function needs to return the `response`\n     *     object directly, or as a promise containing the `response` or a new `response` object.\n     *   * `responseError`: interceptor gets called when a previous interceptor threw an error or\n     *     resolved with a rejection.\n     *\n     *\n     * ```js\n     *   // register the interceptor as a service\n     *   $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {\n     *     return {\n     *       // optional method\n     *       'request': function(config) {\n     *         // do something on success\n     *         return config;\n     *       },\n     *\n     *       // optional method\n     *      'requestError': function(rejection) {\n     *         // do something on error\n     *         if (canRecover(rejection)) {\n     *           return responseOrNewPromise\n     *         }\n     *         return $q.reject(rejection);\n     *       },\n     *\n     *\n     *\n     *       // optional method\n     *       'response': function(response) {\n     *         // do something on success\n     *         return response;\n     *       },\n     *\n     *       // optional method\n     *      'responseError': function(rejection) {\n     *         // do something on error\n     *         if (canRecover(rejection)) {\n     *           return responseOrNewPromise\n     *         }\n     *         return $q.reject(rejection);\n     *       }\n     *     };\n     *   });\n     *\n     *   $httpProvider.interceptors.push('myHttpInterceptor');\n     *\n     *\n     *   // alternatively, register the interceptor via an anonymous factory\n     *   $httpProvider.interceptors.push(function($q, dependency1, dependency2) {\n     *     return {\n     *      'request': function(config) {\n     *          // same as above\n     *       },\n     *\n     *       'response': function(response) {\n     *          // same as above\n     *       }\n     *     };\n     *   });\n     * ```\n     *\n     * ## Security Considerations\n     *\n     * When designing web applications, consider security threats from:\n     *\n     * - [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)\n     * - [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery)\n     *\n     * Both server and the client must cooperate in order to eliminate these threats. Angular comes\n     * pre-configured with strategies that address these issues, but for this to work backend server\n     * cooperation is required.\n     *\n     * ### JSON Vulnerability Protection\n     *\n     * A [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)\n     * allows third party website to turn your JSON resource URL into\n     * [JSONP](http://en.wikipedia.org/wiki/JSONP) request under some conditions. To\n     * counter this your server can prefix all JSON requests with following string `\")]}',\\n\"`.\n     * Angular will automatically strip the prefix before processing it as JSON.\n     *\n     * For example if your server needs to return:\n     * ```js\n     * ['one','two']\n     * ```\n     *\n     * which is vulnerable to attack, your server can return:\n     * ```js\n     * )]}',\n     * ['one','two']\n     * ```\n     *\n     * Angular will strip the prefix, before processing the JSON.\n     *\n     *\n     * ### Cross Site Request Forgery (XSRF) Protection\n     *\n     * [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by\n     * which the attacker can trick an authenticated user into unknowingly executing actions on your\n     * website. Angular provides a mechanism to counter XSRF. When performing XHR requests, the\n     * $http service reads a token from a cookie (by default, `XSRF-TOKEN`) and sets it as an HTTP\n     * header (`X-XSRF-TOKEN`). Since only JavaScript that runs on your domain could read the\n     * cookie, your server can be assured that the XHR came from JavaScript running on your domain.\n     * The header will not be set for cross-domain requests.\n     *\n     * To take advantage of this, your server needs to set a token in a JavaScript readable session\n     * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the\n     * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure\n     * that only JavaScript running on your domain could have sent the request. The token must be\n     * unique for each user and must be verifiable by the server (to prevent the JavaScript from\n     * making up its own tokens). We recommend that the token is a digest of your site's\n     * authentication cookie with a [salt](https://en.wikipedia.org/wiki/Salt_(cryptography&#41;)\n     * for added security.\n     *\n     * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName\n     * properties of either $httpProvider.defaults at config-time, $http.defaults at run-time,\n     * or the per-request config object.\n     *\n     * In order to prevent collisions in environments where multiple Angular apps share the\n     * same domain or subdomain, we recommend that each application uses unique cookie name.\n     *\n     * @param {object} config Object describing the request to be made and how it should be\n     *    processed. The object has following properties:\n     *\n     *    - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)\n     *    - **url** – `{string|TrustedObject}` – Absolute or relative URL of the resource that is being requested;\n     *      or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     *    - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be serialized\n     *      with the `paramSerializer` and appended as GET parameters.\n     *    - **data** – `{string|Object}` – Data to be sent as the request message data.\n     *    - **headers** – `{Object}` – Map of strings or functions which return strings representing\n     *      HTTP headers to send to the server. If the return value of a function is null, the\n     *      header will not be sent. Functions accept a config object as an argument.\n     *    - **eventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest object.\n     *      To bind events to the XMLHttpRequest upload object, use `uploadEventHandlers`.\n     *      The handler will be called in the context of a `$apply` block.\n     *    - **uploadEventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest upload\n     *      object. To bind events to the XMLHttpRequest object, use `eventHandlers`.\n     *      The handler will be called in the context of a `$apply` block.\n     *    - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.\n     *    - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.\n     *    - **transformRequest** –\n     *      `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –\n     *      transform function or an array of such functions. The transform function takes the http\n     *      request body and headers and returns its transformed (typically serialized) version.\n     *      See {@link ng.$http#overriding-the-default-transformations-per-request\n     *      Overriding the Default Transformations}\n     *    - **transformResponse** –\n     *      `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –\n     *      transform function or an array of such functions. The transform function takes the http\n     *      response body, headers and status and returns its transformed (typically deserialized) version.\n     *      See {@link ng.$http#overriding-the-default-transformations-per-request\n     *      Overriding the Default Transformations}\n     *    - **paramSerializer** - `{string|function(Object<string,string>):string}` - A function used to\n     *      prepare the string representation of request parameters (specified as an object).\n     *      If specified as string, it is interpreted as function registered with the\n     *      {@link $injector $injector}, which means you can create your own serializer\n     *      by registering it as a {@link auto.$provide#service service}.\n     *      The default serializer is the {@link $httpParamSerializer $httpParamSerializer};\n     *      alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike}\n     *    - **cache** – `{boolean|Object}` – A boolean value or object created with\n     *      {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response.\n     *      See {@link $http#caching $http Caching} for more information.\n     *    - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}\n     *      that should abort the request when resolved.\n     *    - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the\n     *      XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials)\n     *      for more information.\n     *    - **responseType** - `{string}` - see\n     *      [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype).\n     *\n     * @returns {HttpPromise} Returns a {@link ng.$q `Promise}` that will be resolved to a response object\n     *                        when the request succeeds or fails.\n     *\n     *\n     * @property {Array.<Object>} pendingRequests Array of config objects for currently pending\n     *   requests. This is primarily meant to be used for debugging purposes.\n     *\n     *\n     * @example\n<example module=\"httpExample\" name=\"http-service\">\n<file name=\"index.html\">\n  <div ng-controller=\"FetchController\">\n    <select ng-model=\"method\" aria-label=\"Request method\">\n      <option>GET</option>\n      <option>JSONP</option>\n    </select>\n    <input type=\"text\" ng-model=\"url\" size=\"80\" aria-label=\"URL\" />\n    <button id=\"fetchbtn\" ng-click=\"fetch()\">fetch</button><br>\n    <button id=\"samplegetbtn\" ng-click=\"updateModel('GET', 'http-hello.html')\">Sample GET</button>\n    <button id=\"samplejsonpbtn\"\n      ng-click=\"updateModel('JSONP',\n                    'https://angularjs.org/greet.php?name=Super%20Hero')\">\n      Sample JSONP\n    </button>\n    <button id=\"invalidjsonpbtn\"\n      ng-click=\"updateModel('JSONP', 'https://angularjs.org/doesntexist')\">\n        Invalid JSONP\n      </button>\n    <pre>http status code: {{status}}</pre>\n    <pre>http response data: {{data}}</pre>\n  </div>\n</file>\n<file name=\"script.js\">\n  angular.module('httpExample', [])\n    .config(['$sceDelegateProvider', function($sceDelegateProvider) {\n      // We must whitelist the JSONP endpoint that we are using to show that we trust it\n      $sceDelegateProvider.resourceUrlWhitelist([\n        'self',\n        'https://angularjs.org/**'\n      ]);\n    }])\n    .controller('FetchController', ['$scope', '$http', '$templateCache',\n      function($scope, $http, $templateCache) {\n        $scope.method = 'GET';\n        $scope.url = 'http-hello.html';\n\n        $scope.fetch = function() {\n          $scope.code = null;\n          $scope.response = null;\n\n          $http({method: $scope.method, url: $scope.url, cache: $templateCache}).\n            then(function(response) {\n              $scope.status = response.status;\n              $scope.data = response.data;\n            }, function(response) {\n              $scope.data = response.data || 'Request failed';\n              $scope.status = response.status;\n          });\n        };\n\n        $scope.updateModel = function(method, url) {\n          $scope.method = method;\n          $scope.url = url;\n        };\n      }]);\n</file>\n<file name=\"http-hello.html\">\n  Hello, $http!\n</file>\n<file name=\"protractor.js\" type=\"protractor\">\n  var status = element(by.binding('status'));\n  var data = element(by.binding('data'));\n  var fetchBtn = element(by.id('fetchbtn'));\n  var sampleGetBtn = element(by.id('samplegetbtn'));\n  var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));\n\n  it('should make an xhr GET request', function() {\n    sampleGetBtn.click();\n    fetchBtn.click();\n    expect(status.getText()).toMatch('200');\n    expect(data.getText()).toMatch(/Hello, \\$http!/);\n  });\n\n// Commented out due to flakes. See https://github.com/angular/angular.js/issues/9185\n// it('should make a JSONP request to angularjs.org', function() {\n//   var sampleJsonpBtn = element(by.id('samplejsonpbtn'));\n//   sampleJsonpBtn.click();\n//   fetchBtn.click();\n//   expect(status.getText()).toMatch('200');\n//   expect(data.getText()).toMatch(/Super Hero!/);\n// });\n\n  it('should make JSONP request to invalid URL and invoke the error handler',\n      function() {\n    invalidJsonpBtn.click();\n    fetchBtn.click();\n    expect(status.getText()).toMatch('0');\n    expect(data.getText()).toMatch('Request failed');\n  });\n</file>\n</example>\n     */\n    function $http(requestConfig) {\n\n      if (!isObject(requestConfig)) {\n        throw minErr('$http')('badreq', 'Http request configuration must be an object.  Received: {0}', requestConfig);\n      }\n\n      if (!isString($sce.valueOf(requestConfig.url))) {\n        throw minErr('$http')('badreq', 'Http request configuration url must be a string or a $sce trusted object.  Received: {0}', requestConfig.url);\n      }\n\n      var config = extend({\n        method: 'get',\n        transformRequest: defaults.transformRequest,\n        transformResponse: defaults.transformResponse,\n        paramSerializer: defaults.paramSerializer,\n        jsonpCallbackParam: defaults.jsonpCallbackParam\n      }, requestConfig);\n\n      config.headers = mergeHeaders(requestConfig);\n      config.method = uppercase(config.method);\n      config.paramSerializer = isString(config.paramSerializer) ?\n          $injector.get(config.paramSerializer) : config.paramSerializer;\n\n      $browser.$$incOutstandingRequestCount();\n\n      var requestInterceptors = [];\n      var responseInterceptors = [];\n      var promise = $q.resolve(config);\n\n      // apply interceptors\n      forEach(reversedInterceptors, function(interceptor) {\n        if (interceptor.request || interceptor.requestError) {\n          requestInterceptors.unshift(interceptor.request, interceptor.requestError);\n        }\n        if (interceptor.response || interceptor.responseError) {\n          responseInterceptors.push(interceptor.response, interceptor.responseError);\n        }\n      });\n\n      promise = chainInterceptors(promise, requestInterceptors);\n      promise = promise.then(serverRequest);\n      promise = chainInterceptors(promise, responseInterceptors);\n      promise = promise.finally(completeOutstandingRequest);\n\n      return promise;\n\n\n      function chainInterceptors(promise, interceptors) {\n        for (var i = 0, ii = interceptors.length; i < ii;) {\n          var thenFn = interceptors[i++];\n          var rejectFn = interceptors[i++];\n\n          promise = promise.then(thenFn, rejectFn);\n        }\n\n        interceptors.length = 0;\n\n        return promise;\n      }\n\n      function completeOutstandingRequest() {\n        $browser.$$completeOutstandingRequest(noop);\n      }\n\n      function executeHeaderFns(headers, config) {\n        var headerContent, processedHeaders = {};\n\n        forEach(headers, function(headerFn, header) {\n          if (isFunction(headerFn)) {\n            headerContent = headerFn(config);\n            if (headerContent != null) {\n              processedHeaders[header] = headerContent;\n            }\n          } else {\n            processedHeaders[header] = headerFn;\n          }\n        });\n\n        return processedHeaders;\n      }\n\n      function mergeHeaders(config) {\n        var defHeaders = defaults.headers,\n            reqHeaders = extend({}, config.headers),\n            defHeaderName, lowercaseDefHeaderName, reqHeaderName;\n\n        defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);\n\n        // using for-in instead of forEach to avoid unnecessary iteration after header has been found\n        defaultHeadersIteration:\n        for (defHeaderName in defHeaders) {\n          lowercaseDefHeaderName = lowercase(defHeaderName);\n\n          for (reqHeaderName in reqHeaders) {\n            if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {\n              continue defaultHeadersIteration;\n            }\n          }\n\n          reqHeaders[defHeaderName] = defHeaders[defHeaderName];\n        }\n\n        // execute if header value is a function for merged headers\n        return executeHeaderFns(reqHeaders, shallowCopy(config));\n      }\n\n      function serverRequest(config) {\n        var headers = config.headers;\n        var reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest);\n\n        // strip content-type if data is undefined\n        if (isUndefined(reqData)) {\n          forEach(headers, function(value, header) {\n            if (lowercase(header) === 'content-type') {\n              delete headers[header];\n            }\n          });\n        }\n\n        if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {\n          config.withCredentials = defaults.withCredentials;\n        }\n\n        // send request\n        return sendReq(config, reqData).then(transformResponse, transformResponse);\n      }\n\n      function transformResponse(response) {\n        // make a copy since the response must be cacheable\n        var resp = extend({}, response);\n        resp.data = transformData(response.data, response.headers, response.status,\n                                  config.transformResponse);\n        return (isSuccess(response.status))\n          ? resp\n          : $q.reject(resp);\n      }\n    }\n\n    $http.pendingRequests = [];\n\n    /**\n     * @ngdoc method\n     * @name $http#get\n     *\n     * @description\n     * Shortcut method to perform `GET` request.\n     *\n     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;\n     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n    /**\n     * @ngdoc method\n     * @name $http#delete\n     *\n     * @description\n     * Shortcut method to perform `DELETE` request.\n     *\n     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;\n     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n    /**\n     * @ngdoc method\n     * @name $http#head\n     *\n     * @description\n     * Shortcut method to perform `HEAD` request.\n     *\n     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;\n     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n    /**\n     * @ngdoc method\n     * @name $http#jsonp\n     *\n     * @description\n     * Shortcut method to perform `JSONP` request.\n     *\n     * Note that, since JSONP requests are sensitive because the response is given full access to the browser,\n     * the url must be declared, via {@link $sce} as a trusted resource URL.\n     * You can trust a URL by adding it to the whitelist via\n     * {@link $sceDelegateProvider#resourceUrlWhitelist  `$sceDelegateProvider.resourceUrlWhitelist`} or\n     * by explicitly trusting the URL via {@link $sce#trustAsResourceUrl `$sce.trustAsResourceUrl(url)`}.\n     *\n     * JSONP requests must specify a callback to be used in the response from the server. This callback\n     * is passed as a query parameter in the request. You must specify the name of this parameter by\n     * setting the `jsonpCallbackParam` property on the request config object.\n     *\n     * ```\n     * $http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'})\n     * ```\n     *\n     * You can also specify a default callback parameter name in `$http.defaults.jsonpCallbackParam`.\n     * Initially this is set to `'callback'`.\n     *\n     * <div class=\"alert alert-danger\">\n     * You can no longer use the `JSON_CALLBACK` string as a placeholder for specifying where the callback\n     * parameter value should go.\n     * </div>\n     *\n     * If you would like to customise where and how the callbacks are stored then try overriding\n     * or decorating the {@link $jsonpCallbacks} service.\n     *\n     * @param {string|TrustedObject} url Absolute or relative URL of the resource that is being requested;\n     *                                   or an object created by a call to `$sce.trustAsResourceUrl(url)`.\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n    createShortMethods('get', 'delete', 'head', 'jsonp');\n\n    /**\n     * @ngdoc method\n     * @name $http#post\n     *\n     * @description\n     * Shortcut method to perform `POST` request.\n     *\n     * @param {string} url Relative or absolute URL specifying the destination of the request\n     * @param {*} data Request content\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n    /**\n     * @ngdoc method\n     * @name $http#put\n     *\n     * @description\n     * Shortcut method to perform `PUT` request.\n     *\n     * @param {string} url Relative or absolute URL specifying the destination of the request\n     * @param {*} data Request content\n     * @param {Object=} config Optional configuration object\n     * @returns {HttpPromise} Future object\n     */\n\n     /**\n      * @ngdoc method\n      * @name $http#patch\n      *\n      * @description\n      * Shortcut method to perform `PATCH` request.\n      *\n      * @param {string} url Relative or absolute URL specifying the destination of the request\n      * @param {*} data Request content\n      * @param {Object=} config Optional configuration object\n      * @returns {HttpPromise} Future object\n      */\n    createShortMethodsWithData('post', 'put', 'patch');\n\n        /**\n         * @ngdoc property\n         * @name $http#defaults\n         *\n         * @description\n         * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of\n         * default headers, withCredentials as well as request and response transformations.\n         *\n         * See \"Setting HTTP Headers\" and \"Transforming Requests and Responses\" sections above.\n         */\n    $http.defaults = defaults;\n\n\n    return $http;\n\n\n    function createShortMethods(names) {\n      forEach(arguments, function(name) {\n        $http[name] = function(url, config) {\n          return $http(extend({}, config || {}, {\n            method: name,\n            url: url\n          }));\n        };\n      });\n    }\n\n\n    function createShortMethodsWithData(name) {\n      forEach(arguments, function(name) {\n        $http[name] = function(url, data, config) {\n          return $http(extend({}, config || {}, {\n            method: name,\n            url: url,\n            data: data\n          }));\n        };\n      });\n    }\n\n\n    /**\n     * Makes the request.\n     *\n     * !!! ACCESSES CLOSURE VARS:\n     * $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests\n     */\n    function sendReq(config, reqData) {\n      var deferred = $q.defer(),\n          promise = deferred.promise,\n          cache,\n          cachedResp,\n          reqHeaders = config.headers,\n          isJsonp = lowercase(config.method) === 'jsonp',\n          url = config.url;\n\n      if (isJsonp) {\n        // JSONP is a pretty sensitive operation where we're allowing a script to have full access to\n        // our DOM and JS space.  So we require that the URL satisfies SCE.RESOURCE_URL.\n        url = $sce.getTrustedResourceUrl(url);\n      } else if (!isString(url)) {\n        // If it is not a string then the URL must be a $sce trusted object\n        url = $sce.valueOf(url);\n      }\n\n      url = buildUrl(url, config.paramSerializer(config.params));\n\n      if (isJsonp) {\n        // Check the url and add the JSONP callback placeholder\n        url = sanitizeJsonpCallbackParam(url, config.jsonpCallbackParam);\n      }\n\n      $http.pendingRequests.push(config);\n      promise.then(removePendingReq, removePendingReq);\n\n      if ((config.cache || defaults.cache) && config.cache !== false &&\n          (config.method === 'GET' || config.method === 'JSONP')) {\n        cache = isObject(config.cache) ? config.cache\n            : isObject(/** @type {?} */ (defaults).cache)\n              ? /** @type {?} */ (defaults).cache\n              : defaultCache;\n      }\n\n      if (cache) {\n        cachedResp = cache.get(url);\n        if (isDefined(cachedResp)) {\n          if (isPromiseLike(cachedResp)) {\n            // cached request has already been sent, but there is no response yet\n            cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult);\n          } else {\n            // serving from cache\n            if (isArray(cachedResp)) {\n              resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3]);\n            } else {\n              resolvePromise(cachedResp, 200, {}, 'OK');\n            }\n          }\n        } else {\n          // put the promise for the non-transformed response into cache as a placeholder\n          cache.put(url, promise);\n        }\n      }\n\n\n      // if we won't have the response in cache, set the xsrf headers and\n      // send the request to the backend\n      if (isUndefined(cachedResp)) {\n        var xsrfValue = urlIsSameOrigin(config.url)\n            ? $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName]\n            : undefined;\n        if (xsrfValue) {\n          reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;\n        }\n\n        $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,\n            config.withCredentials, config.responseType,\n            createApplyHandlers(config.eventHandlers),\n            createApplyHandlers(config.uploadEventHandlers));\n      }\n\n      return promise;\n\n      function createApplyHandlers(eventHandlers) {\n        if (eventHandlers) {\n          var applyHandlers = {};\n          forEach(eventHandlers, function(eventHandler, key) {\n            applyHandlers[key] = function(event) {\n              if (useApplyAsync) {\n                $rootScope.$applyAsync(callEventHandler);\n              } else if ($rootScope.$$phase) {\n                callEventHandler();\n              } else {\n                $rootScope.$apply(callEventHandler);\n              }\n\n              function callEventHandler() {\n                eventHandler(event);\n              }\n            };\n          });\n          return applyHandlers;\n        }\n      }\n\n\n      /**\n       * Callback registered to $httpBackend():\n       *  - caches the response if desired\n       *  - resolves the raw $http promise\n       *  - calls $apply\n       */\n      function done(status, response, headersString, statusText) {\n        if (cache) {\n          if (isSuccess(status)) {\n            cache.put(url, [status, response, parseHeaders(headersString), statusText]);\n          } else {\n            // remove promise from the cache\n            cache.remove(url);\n          }\n        }\n\n        function resolveHttpPromise() {\n          resolvePromise(response, status, headersString, statusText);\n        }\n\n        if (useApplyAsync) {\n          $rootScope.$applyAsync(resolveHttpPromise);\n        } else {\n          resolveHttpPromise();\n          if (!$rootScope.$$phase) $rootScope.$apply();\n        }\n      }\n\n\n      /**\n       * Resolves the raw $http promise.\n       */\n      function resolvePromise(response, status, headers, statusText) {\n        //status: HTTP response status code, 0, -1 (aborted by timeout / promise)\n        status = status >= -1 ? status : 0;\n\n        (isSuccess(status) ? deferred.resolve : deferred.reject)({\n          data: response,\n          status: status,\n          headers: headersGetter(headers),\n          config: config,\n          statusText: statusText\n        });\n      }\n\n      function resolvePromiseWithResult(result) {\n        resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText);\n      }\n\n      function removePendingReq() {\n        var idx = $http.pendingRequests.indexOf(config);\n        if (idx !== -1) $http.pendingRequests.splice(idx, 1);\n      }\n    }\n\n\n    function buildUrl(url, serializedParams) {\n      if (serializedParams.length > 0) {\n        url += ((url.indexOf('?') === -1) ? '?' : '&') + serializedParams;\n      }\n      return url;\n    }\n\n    function sanitizeJsonpCallbackParam(url, key) {\n      if (/[&?][^=]+=JSON_CALLBACK/.test(url)) {\n        // Throw if the url already contains a reference to JSON_CALLBACK\n        throw $httpMinErr('badjsonp', 'Illegal use of JSON_CALLBACK in url, \"{0}\"', url);\n      }\n\n      var callbackParamRegex = new RegExp('[&?]' + key + '=');\n      if (callbackParamRegex.test(url)) {\n        // Throw if the callback param was already provided\n        throw $httpMinErr('badjsonp', 'Illegal use of callback param, \"{0}\", in url, \"{1}\"', key, url);\n      }\n\n      // Add in the JSON_CALLBACK callback param value\n      url += ((url.indexOf('?') === -1) ? '?' : '&') + key + '=JSON_CALLBACK';\n\n      return url;\n    }\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $xhrFactory\n * @this\n *\n * @description\n * Factory function used to create XMLHttpRequest objects.\n *\n * Replace or decorate this service to create your own custom XMLHttpRequest objects.\n *\n * ```\n * angular.module('myApp', [])\n * .factory('$xhrFactory', function() {\n *   return function createXhr(method, url) {\n *     return new window.XMLHttpRequest({mozSystem: true});\n *   };\n * });\n * ```\n *\n * @param {string} method HTTP method of the request (GET, POST, PUT, ..)\n * @param {string} url URL of the request.\n */\nfunction $xhrFactoryProvider() {\n  this.$get = function() {\n    return function createXhr() {\n      return new window.XMLHttpRequest();\n    };\n  };\n}\n\n/**\n * @ngdoc service\n * @name $httpBackend\n * @requires $jsonpCallbacks\n * @requires $document\n * @requires $xhrFactory\n * @this\n *\n * @description\n * HTTP backend used by the {@link ng.$http service} that delegates to\n * XMLHttpRequest object or JSONP and deals with browser incompatibilities.\n *\n * You should never need to use this service directly, instead use the higher-level abstractions:\n * {@link ng.$http $http} or {@link ngResource.$resource $resource}.\n *\n * During testing this implementation is swapped with {@link ngMock.$httpBackend mock\n * $httpBackend} which can be trained with responses.\n */\nfunction $HttpBackendProvider() {\n  this.$get = ['$browser', '$jsonpCallbacks', '$document', '$xhrFactory', function($browser, $jsonpCallbacks, $document, $xhrFactory) {\n    return createHttpBackend($browser, $xhrFactory, $browser.defer, $jsonpCallbacks, $document[0]);\n  }];\n}\n\nfunction createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {\n  // TODO(vojta): fix the signature\n  return function(method, url, post, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers) {\n    url = url || $browser.url();\n\n    if (lowercase(method) === 'jsonp') {\n      var callbackPath = callbacks.createCallback(url);\n      var jsonpDone = jsonpReq(url, callbackPath, function(status, text) {\n        // jsonpReq only ever sets status to 200 (OK), 404 (ERROR) or -1 (WAITING)\n        var response = (status === 200) && callbacks.getResponse(callbackPath);\n        completeRequest(callback, status, response, '', text);\n        callbacks.removeCallback(callbackPath);\n      });\n    } else {\n\n      var xhr = createXhr(method, url);\n\n      xhr.open(method, url, true);\n      forEach(headers, function(value, key) {\n        if (isDefined(value)) {\n            xhr.setRequestHeader(key, value);\n        }\n      });\n\n      xhr.onload = function requestLoaded() {\n        var statusText = xhr.statusText || '';\n\n        // responseText is the old-school way of retrieving response (supported by IE9)\n        // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)\n        var response = ('response' in xhr) ? xhr.response : xhr.responseText;\n\n        // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)\n        var status = xhr.status === 1223 ? 204 : xhr.status;\n\n        // fix status code when it is 0 (0 status is undocumented).\n        // Occurs when accessing file resources or on Android 4.1 stock browser\n        // while retrieving files from application cache.\n        if (status === 0) {\n          status = response ? 200 : urlResolve(url).protocol === 'file' ? 404 : 0;\n        }\n\n        completeRequest(callback,\n            status,\n            response,\n            xhr.getAllResponseHeaders(),\n            statusText);\n      };\n\n      var requestError = function() {\n        // The response is always empty\n        // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error\n        completeRequest(callback, -1, null, null, '');\n      };\n\n      xhr.onerror = requestError;\n      xhr.onabort = requestError;\n      xhr.ontimeout = requestError;\n\n      forEach(eventHandlers, function(value, key) {\n          xhr.addEventListener(key, value);\n      });\n\n      forEach(uploadEventHandlers, function(value, key) {\n        xhr.upload.addEventListener(key, value);\n      });\n\n      if (withCredentials) {\n        xhr.withCredentials = true;\n      }\n\n      if (responseType) {\n        try {\n          xhr.responseType = responseType;\n        } catch (e) {\n          // WebKit added support for the json responseType value on 09/03/2013\n          // https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are\n          // known to throw when setting the value \"json\" as the response type. Other older\n          // browsers implementing the responseType\n          //\n          // The json response type can be ignored if not supported, because JSON payloads are\n          // parsed on the client-side regardless.\n          if (responseType !== 'json') {\n            throw e;\n          }\n        }\n      }\n\n      xhr.send(isUndefined(post) ? null : post);\n    }\n\n    if (timeout > 0) {\n      var timeoutId = $browserDefer(timeoutRequest, timeout);\n    } else if (isPromiseLike(timeout)) {\n      timeout.then(timeoutRequest);\n    }\n\n\n    function timeoutRequest() {\n      if (jsonpDone) {\n        jsonpDone();\n      }\n      if (xhr) {\n        xhr.abort();\n      }\n    }\n\n    function completeRequest(callback, status, response, headersString, statusText) {\n      // cancel timeout and subsequent timeout promise resolution\n      if (isDefined(timeoutId)) {\n        $browserDefer.cancel(timeoutId);\n      }\n      jsonpDone = xhr = null;\n\n      callback(status, response, headersString, statusText);\n    }\n  };\n\n  function jsonpReq(url, callbackPath, done) {\n    url = url.replace('JSON_CALLBACK', callbackPath);\n    // we can't use jQuery/jqLite here because jQuery does crazy stuff with script elements, e.g.:\n    // - fetches local scripts via XHR and evals them\n    // - adds and immediately removes script elements from the document\n    var script = rawDocument.createElement('script'), callback = null;\n    script.type = 'text/javascript';\n    script.src = url;\n    script.async = true;\n\n    callback = function(event) {\n      script.removeEventListener('load', callback);\n      script.removeEventListener('error', callback);\n      rawDocument.body.removeChild(script);\n      script = null;\n      var status = -1;\n      var text = 'unknown';\n\n      if (event) {\n        if (event.type === 'load' && !callbacks.wasCalled(callbackPath)) {\n          event = { type: 'error' };\n        }\n        text = event.type;\n        status = event.type === 'error' ? 404 : 200;\n      }\n\n      if (done) {\n        done(status, text);\n      }\n    };\n\n    script.addEventListener('load', callback);\n    script.addEventListener('error', callback);\n    rawDocument.body.appendChild(script);\n    return callback;\n  }\n}\n\nvar $interpolateMinErr = angular.$interpolateMinErr = minErr('$interpolate');\n$interpolateMinErr.throwNoconcat = function(text) {\n  throw $interpolateMinErr('noconcat',\n      'Error while interpolating: {0}\\nStrict Contextual Escaping disallows ' +\n      'interpolations that concatenate multiple expressions when a trusted value is ' +\n      'required.  See http://docs.angularjs.org/api/ng.$sce', text);\n};\n\n$interpolateMinErr.interr = function(text, err) {\n  return $interpolateMinErr('interr', 'Can\\'t interpolate: {0}\\n{1}', text, err.toString());\n};\n\n/**\n * @ngdoc provider\n * @name $interpolateProvider\n * @this\n *\n * @description\n *\n * Used for configuring the interpolation markup. Defaults to `{{` and `}}`.\n *\n * <div class=\"alert alert-danger\">\n * This feature is sometimes used to mix different markup languages, e.g. to wrap an Angular\n * template within a Python Jinja template (or any other template language). Mixing templating\n * languages is **very dangerous**. The embedding template language will not safely escape Angular\n * expressions, so any user-controlled values in the template will cause Cross Site Scripting (XSS)\n * security bugs!\n * </div>\n *\n * @example\n<example name=\"custom-interpolation-markup\" module=\"customInterpolationApp\">\n<file name=\"index.html\">\n<script>\n  var customInterpolationApp = angular.module('customInterpolationApp', []);\n\n  customInterpolationApp.config(function($interpolateProvider) {\n    $interpolateProvider.startSymbol('//');\n    $interpolateProvider.endSymbol('//');\n  });\n\n\n  customInterpolationApp.controller('DemoController', function() {\n      this.label = \"This binding is brought you by // interpolation symbols.\";\n  });\n</script>\n<div ng-controller=\"DemoController as demo\">\n    //demo.label//\n</div>\n</file>\n<file name=\"protractor.js\" type=\"protractor\">\n  it('should interpolate binding with custom symbols', function() {\n    expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.');\n  });\n</file>\n</example>\n */\nfunction $InterpolateProvider() {\n  var startSymbol = '{{';\n  var endSymbol = '}}';\n\n  /**\n   * @ngdoc method\n   * @name $interpolateProvider#startSymbol\n   * @description\n   * Symbol to denote start of expression in the interpolated string. Defaults to `{{`.\n   *\n   * @param {string=} value new value to set the starting symbol to.\n   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.\n   */\n  this.startSymbol = function(value) {\n    if (value) {\n      startSymbol = value;\n      return this;\n    } else {\n      return startSymbol;\n    }\n  };\n\n  /**\n   * @ngdoc method\n   * @name $interpolateProvider#endSymbol\n   * @description\n   * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.\n   *\n   * @param {string=} value new value to set the ending symbol to.\n   * @returns {string|self} Returns the symbol when used as getter and self if used as setter.\n   */\n  this.endSymbol = function(value) {\n    if (value) {\n      endSymbol = value;\n      return this;\n    } else {\n      return endSymbol;\n    }\n  };\n\n\n  this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) {\n    var startSymbolLength = startSymbol.length,\n        endSymbolLength = endSymbol.length,\n        escapedStartRegexp = new RegExp(startSymbol.replace(/./g, escape), 'g'),\n        escapedEndRegexp = new RegExp(endSymbol.replace(/./g, escape), 'g');\n\n    function escape(ch) {\n      return '\\\\\\\\\\\\' + ch;\n    }\n\n    function unescapeText(text) {\n      return text.replace(escapedStartRegexp, startSymbol).\n        replace(escapedEndRegexp, endSymbol);\n    }\n\n    // TODO: this is the same as the constantWatchDelegate in parse.js\n    function constantWatchDelegate(scope, listener, objectEquality, constantInterp) {\n      var unwatch = scope.$watch(function constantInterpolateWatch(scope) {\n        unwatch();\n        return constantInterp(scope);\n      }, listener, objectEquality);\n      return unwatch;\n    }\n\n    /**\n     * @ngdoc service\n     * @name $interpolate\n     * @kind function\n     *\n     * @requires $parse\n     * @requires $sce\n     *\n     * @description\n     *\n     * Compiles a string with markup into an interpolation function. This service is used by the\n     * HTML {@link ng.$compile $compile} service for data binding. See\n     * {@link ng.$interpolateProvider $interpolateProvider} for configuring the\n     * interpolation markup.\n     *\n     *\n     * ```js\n     *   var $interpolate = ...; // injected\n     *   var exp = $interpolate('Hello {{name | uppercase}}!');\n     *   expect(exp({name:'Angular'})).toEqual('Hello ANGULAR!');\n     * ```\n     *\n     * `$interpolate` takes an optional fourth argument, `allOrNothing`. If `allOrNothing` is\n     * `true`, the interpolation function will return `undefined` unless all embedded expressions\n     * evaluate to a value other than `undefined`.\n     *\n     * ```js\n     *   var $interpolate = ...; // injected\n     *   var context = {greeting: 'Hello', name: undefined };\n     *\n     *   // default \"forgiving\" mode\n     *   var exp = $interpolate('{{greeting}} {{name}}!');\n     *   expect(exp(context)).toEqual('Hello !');\n     *\n     *   // \"allOrNothing\" mode\n     *   exp = $interpolate('{{greeting}} {{name}}!', false, null, true);\n     *   expect(exp(context)).toBeUndefined();\n     *   context.name = 'Angular';\n     *   expect(exp(context)).toEqual('Hello Angular!');\n     * ```\n     *\n     * `allOrNothing` is useful for interpolating URLs. `ngSrc` and `ngSrcset` use this behavior.\n     *\n     * #### Escaped Interpolation\n     * $interpolate provides a mechanism for escaping interpolation markers. Start and end markers\n     * can be escaped by preceding each of their characters with a REVERSE SOLIDUS U+005C (backslash).\n     * It will be rendered as a regular start/end marker, and will not be interpreted as an expression\n     * or binding.\n     *\n     * This enables web-servers to prevent script injection attacks and defacing attacks, to some\n     * degree, while also enabling code examples to work without relying on the\n     * {@link ng.directive:ngNonBindable ngNonBindable} directive.\n     *\n     * **For security purposes, it is strongly encouraged that web servers escape user-supplied data,\n     * replacing angle brackets (&lt;, &gt;) with &amp;lt; and &amp;gt; respectively, and replacing all\n     * interpolation start/end markers with their escaped counterparts.**\n     *\n     * Escaped interpolation markers are only replaced with the actual interpolation markers in rendered\n     * output when the $interpolate service processes the text. So, for HTML elements interpolated\n     * by {@link ng.$compile $compile}, or otherwise interpolated with the `mustHaveExpression` parameter\n     * set to `true`, the interpolated text must contain an unescaped interpolation expression. As such,\n     * this is typically useful only when user-data is used in rendering a template from the server, or\n     * when otherwise untrusted data is used by a directive.\n     *\n     * <example name=\"interpolation\">\n     *  <file name=\"index.html\">\n     *    <div ng-init=\"username='A user'\">\n     *      <p ng-init=\"apptitle='Escaping demo'\">{{apptitle}}: \\{\\{ username = \"defaced value\"; \\}\\}\n     *        </p>\n     *      <p><strong>{{username}}</strong> attempts to inject code which will deface the\n     *        application, but fails to accomplish their task, because the server has correctly\n     *        escaped the interpolation start/end markers with REVERSE SOLIDUS U+005C (backslash)\n     *        characters.</p>\n     *      <p>Instead, the result of the attempted script injection is visible, and can be removed\n     *        from the database by an administrator.</p>\n     *    </div>\n     *  </file>\n     * </example>\n     *\n     * @knownIssue\n     * It is currently not possible for an interpolated expression to contain the interpolation end\n     * symbol. For example, `{{ '}}' }}` will be incorrectly interpreted as `{{ ' }}` + `' }}`, i.e.\n     * an interpolated expression consisting of a single-quote (`'`) and the `' }}` string.\n     *\n     * @knownIssue\n     * All directives and components must use the standard `{{` `}}` interpolation symbols\n     * in their templates. If you change the application interpolation symbols the {@link $compile}\n     * service will attempt to denormalize the standard symbols to the custom symbols.\n     * The denormalization process is not clever enough to know not to replace instances of the standard\n     * symbols where they would not normally be treated as interpolation symbols. For example in the following\n     * code snippet the closing braces of the literal object will get incorrectly denormalized:\n     *\n     * ```\n     * <div data-context='{\"context\":{\"id\":3,\"type\":\"page\"}}\">\n     * ```\n     *\n     * The workaround is to ensure that such instances are separated by whitespace:\n     * ```\n     * <div data-context='{\"context\":{\"id\":3,\"type\":\"page\"} }\">\n     * ```\n     *\n     * See https://github.com/angular/angular.js/pull/14610#issuecomment-219401099 for more information.\n     *\n     * @param {string} text The text with markup to interpolate.\n     * @param {boolean=} mustHaveExpression if set to true then the interpolation string must have\n     *    embedded expression in order to return an interpolation function. Strings with no\n     *    embedded expression will return null for the interpolation function.\n     * @param {string=} trustedContext when provided, the returned function passes the interpolated\n     *    result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult,\n     *    trustedContext)} before returning it.  Refer to the {@link ng.$sce $sce} service that\n     *    provides Strict Contextual Escaping for details.\n     * @param {boolean=} allOrNothing if `true`, then the returned function returns undefined\n     *    unless all embedded expressions evaluate to a value other than `undefined`.\n     * @returns {function(context)} an interpolation function which is used to compute the\n     *    interpolated string. The function has these parameters:\n     *\n     * - `context`: evaluation context for all expressions embedded in the interpolated text\n     */\n    function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {\n      // Provide a quick exit and simplified result function for text with no interpolation\n      if (!text.length || text.indexOf(startSymbol) === -1) {\n        var constantInterp;\n        if (!mustHaveExpression) {\n          var unescapedText = unescapeText(text);\n          constantInterp = valueFn(unescapedText);\n          constantInterp.exp = text;\n          constantInterp.expressions = [];\n          constantInterp.$$watchDelegate = constantWatchDelegate;\n        }\n        return constantInterp;\n      }\n\n      allOrNothing = !!allOrNothing;\n      var startIndex,\n          endIndex,\n          index = 0,\n          expressions = [],\n          parseFns = [],\n          textLength = text.length,\n          exp,\n          concat = [],\n          expressionPositions = [];\n\n      while (index < textLength) {\n        if (((startIndex = text.indexOf(startSymbol, index)) !== -1) &&\n             ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) !== -1)) {\n          if (index !== startIndex) {\n            concat.push(unescapeText(text.substring(index, startIndex)));\n          }\n          exp = text.substring(startIndex + startSymbolLength, endIndex);\n          expressions.push(exp);\n          parseFns.push($parse(exp, parseStringifyInterceptor));\n          index = endIndex + endSymbolLength;\n          expressionPositions.push(concat.length);\n          concat.push('');\n        } else {\n          // we did not find an interpolation, so we have to add the remainder to the separators array\n          if (index !== textLength) {\n            concat.push(unescapeText(text.substring(index)));\n          }\n          break;\n        }\n      }\n\n      // Concatenating expressions makes it hard to reason about whether some combination of\n      // concatenated values are unsafe to use and could easily lead to XSS.  By requiring that a\n      // single expression be used for iframe[src], object[src], etc., we ensure that the value\n      // that's used is assigned or constructed by some JS code somewhere that is more testable or\n      // make it obvious that you bound the value to some user controlled value.  This helps reduce\n      // the load when auditing for XSS issues.\n      if (trustedContext && concat.length > 1) {\n          $interpolateMinErr.throwNoconcat(text);\n      }\n\n      if (!mustHaveExpression || expressions.length) {\n        var compute = function(values) {\n          for (var i = 0, ii = expressions.length; i < ii; i++) {\n            if (allOrNothing && isUndefined(values[i])) return;\n            concat[expressionPositions[i]] = values[i];\n          }\n          return concat.join('');\n        };\n\n        var getValue = function(value) {\n          return trustedContext ?\n            $sce.getTrusted(trustedContext, value) :\n            $sce.valueOf(value);\n        };\n\n        return extend(function interpolationFn(context) {\n            var i = 0;\n            var ii = expressions.length;\n            var values = new Array(ii);\n\n            try {\n              for (; i < ii; i++) {\n                values[i] = parseFns[i](context);\n              }\n\n              return compute(values);\n            } catch (err) {\n              $exceptionHandler($interpolateMinErr.interr(text, err));\n            }\n\n          }, {\n          // all of these properties are undocumented for now\n          exp: text, //just for compatibility with regular watchers created via $watch\n          expressions: expressions,\n          $$watchDelegate: function(scope, listener) {\n            var lastValue;\n            return scope.$watchGroup(parseFns, /** @this */ function interpolateFnWatcher(values, oldValues) {\n              var currValue = compute(values);\n              if (isFunction(listener)) {\n                listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope);\n              }\n              lastValue = currValue;\n            });\n          }\n        });\n      }\n\n      function parseStringifyInterceptor(value) {\n        try {\n          value = getValue(value);\n          return allOrNothing && !isDefined(value) ? value : stringify(value);\n        } catch (err) {\n          $exceptionHandler($interpolateMinErr.interr(text, err));\n        }\n      }\n    }\n\n\n    /**\n     * @ngdoc method\n     * @name $interpolate#startSymbol\n     * @description\n     * Symbol to denote the start of expression in the interpolated string. Defaults to `{{`.\n     *\n     * Use {@link ng.$interpolateProvider#startSymbol `$interpolateProvider.startSymbol`} to change\n     * the symbol.\n     *\n     * @returns {string} start symbol.\n     */\n    $interpolate.startSymbol = function() {\n      return startSymbol;\n    };\n\n\n    /**\n     * @ngdoc method\n     * @name $interpolate#endSymbol\n     * @description\n     * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.\n     *\n     * Use {@link ng.$interpolateProvider#endSymbol `$interpolateProvider.endSymbol`} to change\n     * the symbol.\n     *\n     * @returns {string} end symbol.\n     */\n    $interpolate.endSymbol = function() {\n      return endSymbol;\n    };\n\n    return $interpolate;\n  }];\n}\n\n/** @this */\nfunction $IntervalProvider() {\n  this.$get = ['$rootScope', '$window', '$q', '$$q', '$browser',\n       function($rootScope,   $window,   $q,   $$q,   $browser) {\n    var intervals = {};\n\n\n     /**\n      * @ngdoc service\n      * @name $interval\n      *\n      * @description\n      * Angular's wrapper for `window.setInterval`. The `fn` function is executed every `delay`\n      * milliseconds.\n      *\n      * The return value of registering an interval function is a promise. This promise will be\n      * notified upon each tick of the interval, and will be resolved after `count` iterations, or\n      * run indefinitely if `count` is not defined. The value of the notification will be the\n      * number of iterations that have run.\n      * To cancel an interval, call `$interval.cancel(promise)`.\n      *\n      * In tests you can use {@link ngMock.$interval#flush `$interval.flush(millis)`} to\n      * move forward by `millis` milliseconds and trigger any functions scheduled to run in that\n      * time.\n      *\n      * <div class=\"alert alert-warning\">\n      * **Note**: Intervals created by this service must be explicitly destroyed when you are finished\n      * with them.  In particular they are not automatically destroyed when a controller's scope or a\n      * directive's element are destroyed.\n      * You should take this into consideration and make sure to always cancel the interval at the\n      * appropriate moment.  See the example below for more details on how and when to do this.\n      * </div>\n      *\n      * @param {function()} fn A function that should be called repeatedly. If no additional arguments\n      *   are passed (see below), the function is called with the current iteration count.\n      * @param {number} delay Number of milliseconds between each function call.\n      * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat\n      *   indefinitely.\n      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise\n      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.\n      * @param {...*=} Pass additional parameters to the executed function.\n      * @returns {promise} A promise which will be notified on each iteration.\n      *\n      * @example\n      * <example module=\"intervalExample\" name=\"interval-service\">\n      * <file name=\"index.html\">\n      *   <script>\n      *     angular.module('intervalExample', [])\n      *       .controller('ExampleController', ['$scope', '$interval',\n      *         function($scope, $interval) {\n      *           $scope.format = 'M/d/yy h:mm:ss a';\n      *           $scope.blood_1 = 100;\n      *           $scope.blood_2 = 120;\n      *\n      *           var stop;\n      *           $scope.fight = function() {\n      *             // Don't start a new fight if we are already fighting\n      *             if ( angular.isDefined(stop) ) return;\n      *\n      *             stop = $interval(function() {\n      *               if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {\n      *                 $scope.blood_1 = $scope.blood_1 - 3;\n      *                 $scope.blood_2 = $scope.blood_2 - 4;\n      *               } else {\n      *                 $scope.stopFight();\n      *               }\n      *             }, 100);\n      *           };\n      *\n      *           $scope.stopFight = function() {\n      *             if (angular.isDefined(stop)) {\n      *               $interval.cancel(stop);\n      *               stop = undefined;\n      *             }\n      *           };\n      *\n      *           $scope.resetFight = function() {\n      *             $scope.blood_1 = 100;\n      *             $scope.blood_2 = 120;\n      *           };\n      *\n      *           $scope.$on('$destroy', function() {\n      *             // Make sure that the interval is destroyed too\n      *             $scope.stopFight();\n      *           });\n      *         }])\n      *       // Register the 'myCurrentTime' directive factory method.\n      *       // We inject $interval and dateFilter service since the factory method is DI.\n      *       .directive('myCurrentTime', ['$interval', 'dateFilter',\n      *         function($interval, dateFilter) {\n      *           // return the directive link function. (compile function not needed)\n      *           return function(scope, element, attrs) {\n      *             var format,  // date format\n      *                 stopTime; // so that we can cancel the time updates\n      *\n      *             // used to update the UI\n      *             function updateTime() {\n      *               element.text(dateFilter(new Date(), format));\n      *             }\n      *\n      *             // watch the expression, and update the UI on change.\n      *             scope.$watch(attrs.myCurrentTime, function(value) {\n      *               format = value;\n      *               updateTime();\n      *             });\n      *\n      *             stopTime = $interval(updateTime, 1000);\n      *\n      *             // listen on DOM destroy (removal) event, and cancel the next UI update\n      *             // to prevent updating time after the DOM element was removed.\n      *             element.on('$destroy', function() {\n      *               $interval.cancel(stopTime);\n      *             });\n      *           }\n      *         }]);\n      *   </script>\n      *\n      *   <div>\n      *     <div ng-controller=\"ExampleController\">\n      *       <label>Date format: <input ng-model=\"format\"></label> <hr/>\n      *       Current time is: <span my-current-time=\"format\"></span>\n      *       <hr/>\n      *       Blood 1 : <font color='red'>{{blood_1}}</font>\n      *       Blood 2 : <font color='red'>{{blood_2}}</font>\n      *       <button type=\"button\" data-ng-click=\"fight()\">Fight</button>\n      *       <button type=\"button\" data-ng-click=\"stopFight()\">StopFight</button>\n      *       <button type=\"button\" data-ng-click=\"resetFight()\">resetFight</button>\n      *     </div>\n      *   </div>\n      *\n      * </file>\n      * </example>\n      */\n    function interval(fn, delay, count, invokeApply) {\n      var hasParams = arguments.length > 4,\n          args = hasParams ? sliceArgs(arguments, 4) : [],\n          setInterval = $window.setInterval,\n          clearInterval = $window.clearInterval,\n          iteration = 0,\n          skipApply = (isDefined(invokeApply) && !invokeApply),\n          deferred = (skipApply ? $$q : $q).defer(),\n          promise = deferred.promise;\n\n      count = isDefined(count) ? count : 0;\n\n      promise.$$intervalId = setInterval(function tick() {\n        if (skipApply) {\n          $browser.defer(callback);\n        } else {\n          $rootScope.$evalAsync(callback);\n        }\n        deferred.notify(iteration++);\n\n        if (count > 0 && iteration >= count) {\n          deferred.resolve(iteration);\n          clearInterval(promise.$$intervalId);\n          delete intervals[promise.$$intervalId];\n        }\n\n        if (!skipApply) $rootScope.$apply();\n\n      }, delay);\n\n      intervals[promise.$$intervalId] = deferred;\n\n      return promise;\n\n      function callback() {\n        if (!hasParams) {\n          fn(iteration);\n        } else {\n          fn.apply(null, args);\n        }\n      }\n    }\n\n\n     /**\n      * @ngdoc method\n      * @name $interval#cancel\n      *\n      * @description\n      * Cancels a task associated with the `promise`.\n      *\n      * @param {Promise=} promise returned by the `$interval` function.\n      * @returns {boolean} Returns `true` if the task was successfully canceled.\n      */\n    interval.cancel = function(promise) {\n      if (promise && promise.$$intervalId in intervals) {\n        // Interval cancels should not report as unhandled promise.\n        intervals[promise.$$intervalId].promise.catch(noop);\n        intervals[promise.$$intervalId].reject('canceled');\n        $window.clearInterval(promise.$$intervalId);\n        delete intervals[promise.$$intervalId];\n        return true;\n      }\n      return false;\n    };\n\n    return interval;\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $jsonpCallbacks\n * @requires $window\n * @description\n * This service handles the lifecycle of callbacks to handle JSONP requests.\n * Override this service if you wish to customise where the callbacks are stored and\n * how they vary compared to the requested url.\n */\nvar $jsonpCallbacksProvider = /** @this */ function() {\n  this.$get = function() {\n    var callbacks = angular.callbacks;\n    var callbackMap = {};\n\n    function createCallback(callbackId) {\n      var callback = function(data) {\n        callback.data = data;\n        callback.called = true;\n      };\n      callback.id = callbackId;\n      return callback;\n    }\n\n    return {\n      /**\n       * @ngdoc method\n       * @name $jsonpCallbacks#createCallback\n       * @param {string} url the url of the JSONP request\n       * @returns {string} the callback path to send to the server as part of the JSONP request\n       * @description\n       * {@link $httpBackend} calls this method to create a callback and get hold of the path to the callback\n       * to pass to the server, which will be used to call the callback with its payload in the JSONP response.\n       */\n      createCallback: function(url) {\n        var callbackId = '_' + (callbacks.$$counter++).toString(36);\n        var callbackPath = 'angular.callbacks.' + callbackId;\n        var callback = createCallback(callbackId);\n        callbackMap[callbackPath] = callbacks[callbackId] = callback;\n        return callbackPath;\n      },\n      /**\n       * @ngdoc method\n       * @name $jsonpCallbacks#wasCalled\n       * @param {string} callbackPath the path to the callback that was sent in the JSONP request\n       * @returns {boolean} whether the callback has been called, as a result of the JSONP response\n       * @description\n       * {@link $httpBackend} calls this method to find out whether the JSONP response actually called the\n       * callback that was passed in the request.\n       */\n      wasCalled: function(callbackPath) {\n        return callbackMap[callbackPath].called;\n      },\n      /**\n       * @ngdoc method\n       * @name $jsonpCallbacks#getResponse\n       * @param {string} callbackPath the path to the callback that was sent in the JSONP request\n       * @returns {*} the data received from the response via the registered callback\n       * @description\n       * {@link $httpBackend} calls this method to get hold of the data that was provided to the callback\n       * in the JSONP response.\n       */\n      getResponse: function(callbackPath) {\n        return callbackMap[callbackPath].data;\n      },\n      /**\n       * @ngdoc method\n       * @name $jsonpCallbacks#removeCallback\n       * @param {string} callbackPath the path to the callback that was sent in the JSONP request\n       * @description\n       * {@link $httpBackend} calls this method to remove the callback after the JSONP request has\n       * completed or timed-out.\n       */\n      removeCallback: function(callbackPath) {\n        var callback = callbackMap[callbackPath];\n        delete callbacks[callback.id];\n        delete callbackMap[callbackPath];\n      }\n    };\n  };\n};\n\n/**\n * @ngdoc service\n * @name $locale\n *\n * @description\n * $locale service provides localization rules for various Angular components. As of right now the\n * only public api is:\n *\n * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)\n */\n\nvar PATH_MATCH = /^([^?#]*)(\\?([^#]*))?(#(.*))?$/,\n    DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};\nvar $locationMinErr = minErr('$location');\n\n\n/**\n * Encode path using encodeUriSegment, ignoring forward slashes\n *\n * @param {string} path Path to encode\n * @returns {string}\n */\nfunction encodePath(path) {\n  var segments = path.split('/'),\n      i = segments.length;\n\n  while (i--) {\n    segments[i] = encodeUriSegment(segments[i]);\n  }\n\n  return segments.join('/');\n}\n\nfunction parseAbsoluteUrl(absoluteUrl, locationObj) {\n  var parsedUrl = urlResolve(absoluteUrl);\n\n  locationObj.$$protocol = parsedUrl.protocol;\n  locationObj.$$host = parsedUrl.hostname;\n  locationObj.$$port = toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;\n}\n\nvar DOUBLE_SLASH_REGEX = /^\\s*[\\\\/]{2,}/;\nfunction parseAppUrl(url, locationObj) {\n\n  if (DOUBLE_SLASH_REGEX.test(url)) {\n    throw $locationMinErr('badpath', 'Invalid url \"{0}\".', url);\n  }\n\n  var prefixed = (url.charAt(0) !== '/');\n  if (prefixed) {\n    url = '/' + url;\n  }\n  var match = urlResolve(url);\n  locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?\n      match.pathname.substring(1) : match.pathname);\n  locationObj.$$search = parseKeyValue(match.search);\n  locationObj.$$hash = decodeURIComponent(match.hash);\n\n  // make sure path starts with '/';\n  if (locationObj.$$path && locationObj.$$path.charAt(0) !== '/') {\n    locationObj.$$path = '/' + locationObj.$$path;\n  }\n}\n\nfunction startsWith(str, search) {\n  return str.slice(0, search.length) === search;\n}\n\n/**\n *\n * @param {string} base\n * @param {string} url\n * @returns {string} returns text from `url` after `base` or `undefined` if it does not begin with\n *                   the expected string.\n */\nfunction stripBaseUrl(base, url) {\n  if (startsWith(url, base)) {\n    return url.substr(base.length);\n  }\n}\n\n\nfunction stripHash(url) {\n  var index = url.indexOf('#');\n  return index === -1 ? url : url.substr(0, index);\n}\n\nfunction trimEmptyHash(url) {\n  return url.replace(/(#.+)|#$/, '$1');\n}\n\n\nfunction stripFile(url) {\n  return url.substr(0, stripHash(url).lastIndexOf('/') + 1);\n}\n\n/* return the server only (scheme://host:port) */\nfunction serverBase(url) {\n  return url.substring(0, url.indexOf('/', url.indexOf('//') + 2));\n}\n\n\n/**\n * LocationHtml5Url represents a URL\n * This object is exposed as $location service when HTML5 mode is enabled and supported\n *\n * @constructor\n * @param {string} appBase application base URL\n * @param {string} appBaseNoFile application base URL stripped of any filename\n * @param {string} basePrefix URL path prefix\n */\nfunction LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {\n  this.$$html5 = true;\n  basePrefix = basePrefix || '';\n  parseAbsoluteUrl(appBase, this);\n\n\n  /**\n   * Parse given HTML5 (regular) URL string into properties\n   * @param {string} url HTML5 URL\n   * @private\n   */\n  this.$$parse = function(url) {\n    var pathUrl = stripBaseUrl(appBaseNoFile, url);\n    if (!isString(pathUrl)) {\n      throw $locationMinErr('ipthprfx', 'Invalid url \"{0}\", missing path prefix \"{1}\".', url,\n          appBaseNoFile);\n    }\n\n    parseAppUrl(pathUrl, this);\n\n    if (!this.$$path) {\n      this.$$path = '/';\n    }\n\n    this.$$compose();\n  };\n\n  /**\n   * Compose url and update `absUrl` property\n   * @private\n   */\n  this.$$compose = function() {\n    var search = toKeyValue(this.$$search),\n        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';\n\n    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;\n    this.$$absUrl = appBaseNoFile + this.$$url.substr(1); // first char is always '/'\n\n    this.$$urlUpdatedByLocation = true;\n  };\n\n  this.$$parseLinkUrl = function(url, relHref) {\n    if (relHref && relHref[0] === '#') {\n      // special case for links to hash fragments:\n      // keep the old url and only replace the hash fragment\n      this.hash(relHref.slice(1));\n      return true;\n    }\n    var appUrl, prevAppUrl;\n    var rewrittenUrl;\n\n\n    if (isDefined(appUrl = stripBaseUrl(appBase, url))) {\n      prevAppUrl = appUrl;\n      if (basePrefix && isDefined(appUrl = stripBaseUrl(basePrefix, appUrl))) {\n        rewrittenUrl = appBaseNoFile + (stripBaseUrl('/', appUrl) || appUrl);\n      } else {\n        rewrittenUrl = appBase + prevAppUrl;\n      }\n    } else if (isDefined(appUrl = stripBaseUrl(appBaseNoFile, url))) {\n      rewrittenUrl = appBaseNoFile + appUrl;\n    } else if (appBaseNoFile === url + '/') {\n      rewrittenUrl = appBaseNoFile;\n    }\n    if (rewrittenUrl) {\n      this.$$parse(rewrittenUrl);\n    }\n    return !!rewrittenUrl;\n  };\n}\n\n\n/**\n * LocationHashbangUrl represents URL\n * This object is exposed as $location service when developer doesn't opt into html5 mode.\n * It also serves as the base class for html5 mode fallback on legacy browsers.\n *\n * @constructor\n * @param {string} appBase application base URL\n * @param {string} appBaseNoFile application base URL stripped of any filename\n * @param {string} hashPrefix hashbang prefix\n */\nfunction LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) {\n\n  parseAbsoluteUrl(appBase, this);\n\n\n  /**\n   * Parse given hashbang URL into properties\n   * @param {string} url Hashbang URL\n   * @private\n   */\n  this.$$parse = function(url) {\n    var withoutBaseUrl = stripBaseUrl(appBase, url) || stripBaseUrl(appBaseNoFile, url);\n    var withoutHashUrl;\n\n    if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === '#') {\n\n      // The rest of the URL starts with a hash so we have\n      // got either a hashbang path or a plain hash fragment\n      withoutHashUrl = stripBaseUrl(hashPrefix, withoutBaseUrl);\n      if (isUndefined(withoutHashUrl)) {\n        // There was no hashbang prefix so we just have a hash fragment\n        withoutHashUrl = withoutBaseUrl;\n      }\n\n    } else {\n      // There was no hashbang path nor hash fragment:\n      // If we are in HTML5 mode we use what is left as the path;\n      // Otherwise we ignore what is left\n      if (this.$$html5) {\n        withoutHashUrl = withoutBaseUrl;\n      } else {\n        withoutHashUrl = '';\n        if (isUndefined(withoutBaseUrl)) {\n          appBase = url;\n          /** @type {?} */ (this).replace();\n        }\n      }\n    }\n\n    parseAppUrl(withoutHashUrl, this);\n\n    this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);\n\n    this.$$compose();\n\n    /*\n     * In Windows, on an anchor node on documents loaded from\n     * the filesystem, the browser will return a pathname\n     * prefixed with the drive name ('/C:/path') when a\n     * pathname without a drive is set:\n     *  * a.setAttribute('href', '/foo')\n     *   * a.pathname === '/C:/foo' //true\n     *\n     * Inside of Angular, we're always using pathnames that\n     * do not include drive names for routing.\n     */\n    function removeWindowsDriveName(path, url, base) {\n      /*\n      Matches paths for file protocol on windows,\n      such as /C:/foo/bar, and captures only /foo/bar.\n      */\n      var windowsFilePathExp = /^\\/[A-Z]:(\\/.*)/;\n\n      var firstPathSegmentMatch;\n\n      //Get the relative path from the input URL.\n      if (startsWith(url, base)) {\n        url = url.replace(base, '');\n      }\n\n      // The input URL intentionally contains a first path segment that ends with a colon.\n      if (windowsFilePathExp.exec(url)) {\n        return path;\n      }\n\n      firstPathSegmentMatch = windowsFilePathExp.exec(path);\n      return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;\n    }\n  };\n\n  /**\n   * Compose hashbang URL and update `absUrl` property\n   * @private\n   */\n  this.$$compose = function() {\n    var search = toKeyValue(this.$$search),\n        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';\n\n    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;\n    this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url : '');\n\n    this.$$urlUpdatedByLocation = true;\n  };\n\n  this.$$parseLinkUrl = function(url, relHref) {\n    if (stripHash(appBase) === stripHash(url)) {\n      this.$$parse(url);\n      return true;\n    }\n    return false;\n  };\n}\n\n\n/**\n * LocationHashbangUrl represents URL\n * This object is exposed as $location service when html5 history api is enabled but the browser\n * does not support it.\n *\n * @constructor\n * @param {string} appBase application base URL\n * @param {string} appBaseNoFile application base URL stripped of any filename\n * @param {string} hashPrefix hashbang prefix\n */\nfunction LocationHashbangInHtml5Url(appBase, appBaseNoFile, hashPrefix) {\n  this.$$html5 = true;\n  LocationHashbangUrl.apply(this, arguments);\n\n  this.$$parseLinkUrl = function(url, relHref) {\n    if (relHref && relHref[0] === '#') {\n      // special case for links to hash fragments:\n      // keep the old url and only replace the hash fragment\n      this.hash(relHref.slice(1));\n      return true;\n    }\n\n    var rewrittenUrl;\n    var appUrl;\n\n    if (appBase === stripHash(url)) {\n      rewrittenUrl = url;\n    } else if ((appUrl = stripBaseUrl(appBaseNoFile, url))) {\n      rewrittenUrl = appBase + hashPrefix + appUrl;\n    } else if (appBaseNoFile === url + '/') {\n      rewrittenUrl = appBaseNoFile;\n    }\n    if (rewrittenUrl) {\n      this.$$parse(rewrittenUrl);\n    }\n    return !!rewrittenUrl;\n  };\n\n  this.$$compose = function() {\n    var search = toKeyValue(this.$$search),\n        hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';\n\n    this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;\n    // include hashPrefix in $$absUrl when $$url is empty so IE9 does not reload page because of removal of '#'\n    this.$$absUrl = appBase + hashPrefix + this.$$url;\n\n    this.$$urlUpdatedByLocation = true;\n  };\n\n}\n\n\nvar locationPrototype = {\n\n  /**\n   * Ensure absolute URL is initialized.\n   * @private\n   */\n  $$absUrl:'',\n\n  /**\n   * Are we in html5 mode?\n   * @private\n   */\n  $$html5: false,\n\n  /**\n   * Has any change been replacing?\n   * @private\n   */\n  $$replace: false,\n\n  /**\n   * @ngdoc method\n   * @name $location#absUrl\n   *\n   * @description\n   * This method is getter only.\n   *\n   * Return full URL representation with all segments encoded according to rules specified in\n   * [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var absUrl = $location.absUrl();\n   * // => \"http://example.com/#/some/path?foo=bar&baz=xoxo\"\n   * ```\n   *\n   * @return {string} full URL\n   */\n  absUrl: locationGetter('$$absUrl'),\n\n  /**\n   * @ngdoc method\n   * @name $location#url\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Return URL (e.g. `/path?a=b#hash`) when called without any parameter.\n   *\n   * Change path, search and hash, when called with parameter and return `$location`.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var url = $location.url();\n   * // => \"/some/path?foo=bar&baz=xoxo\"\n   * ```\n   *\n   * @param {string=} url New URL without base prefix (e.g. `/path?a=b#hash`)\n   * @return {string} url\n   */\n  url: function(url) {\n    if (isUndefined(url)) {\n      return this.$$url;\n    }\n\n    var match = PATH_MATCH.exec(url);\n    if (match[1] || url === '') this.path(decodeURIComponent(match[1]));\n    if (match[2] || match[1] || url === '') this.search(match[3] || '');\n    this.hash(match[5] || '');\n\n    return this;\n  },\n\n  /**\n   * @ngdoc method\n   * @name $location#protocol\n   *\n   * @description\n   * This method is getter only.\n   *\n   * Return protocol of current URL.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var protocol = $location.protocol();\n   * // => \"http\"\n   * ```\n   *\n   * @return {string} protocol of current URL\n   */\n  protocol: locationGetter('$$protocol'),\n\n  /**\n   * @ngdoc method\n   * @name $location#host\n   *\n   * @description\n   * This method is getter only.\n   *\n   * Return host of current URL.\n   *\n   * Note: compared to the non-angular version `location.host` which returns `hostname:port`, this returns the `hostname` portion only.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var host = $location.host();\n   * // => \"example.com\"\n   *\n   * // given URL http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo\n   * host = $location.host();\n   * // => \"example.com\"\n   * host = location.host;\n   * // => \"example.com:8080\"\n   * ```\n   *\n   * @return {string} host of current URL.\n   */\n  host: locationGetter('$$host'),\n\n  /**\n   * @ngdoc method\n   * @name $location#port\n   *\n   * @description\n   * This method is getter only.\n   *\n   * Return port of current URL.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var port = $location.port();\n   * // => 80\n   * ```\n   *\n   * @return {Number} port\n   */\n  port: locationGetter('$$port'),\n\n  /**\n   * @ngdoc method\n   * @name $location#path\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Return path of current URL when called without any parameter.\n   *\n   * Change path when called with parameter and return `$location`.\n   *\n   * Note: Path should always begin with forward slash (/), this method will add the forward slash\n   * if it is missing.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var path = $location.path();\n   * // => \"/some/path\"\n   * ```\n   *\n   * @param {(string|number)=} path New path\n   * @return {(string|object)} path if called with no parameters, or `$location` if called with a parameter\n   */\n  path: locationGetterSetter('$$path', function(path) {\n    path = path !== null ? path.toString() : '';\n    return path.charAt(0) === '/' ? path : '/' + path;\n  }),\n\n  /**\n   * @ngdoc method\n   * @name $location#search\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Return search part (as object) of current URL when called without any parameter.\n   *\n   * Change search part when called with parameter and return `$location`.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo\n   * var searchObject = $location.search();\n   * // => {foo: 'bar', baz: 'xoxo'}\n   *\n   * // set foo to 'yipee'\n   * $location.search('foo', 'yipee');\n   * // $location.search() => {foo: 'yipee', baz: 'xoxo'}\n   * ```\n   *\n   * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or\n   * hash object.\n   *\n   * When called with a single argument the method acts as a setter, setting the `search` component\n   * of `$location` to the specified value.\n   *\n   * If the argument is a hash object containing an array of values, these values will be encoded\n   * as duplicate search parameters in the URL.\n   *\n   * @param {(string|Number|Array<string>|boolean)=} paramValue If `search` is a string or number, then `paramValue`\n   * will override only a single search property.\n   *\n   * If `paramValue` is an array, it will override the property of the `search` component of\n   * `$location` specified via the first argument.\n   *\n   * If `paramValue` is `null`, the property specified via the first argument will be deleted.\n   *\n   * If `paramValue` is `true`, the property specified via the first argument will be added with no\n   * value nor trailing equal sign.\n   *\n   * @return {Object} If called with no arguments returns the parsed `search` object. If called with\n   * one or more arguments returns `$location` object itself.\n   */\n  search: function(search, paramValue) {\n    switch (arguments.length) {\n      case 0:\n        return this.$$search;\n      case 1:\n        if (isString(search) || isNumber(search)) {\n          search = search.toString();\n          this.$$search = parseKeyValue(search);\n        } else if (isObject(search)) {\n          search = copy(search, {});\n          // remove object undefined or null properties\n          forEach(search, function(value, key) {\n            if (value == null) delete search[key];\n          });\n\n          this.$$search = search;\n        } else {\n          throw $locationMinErr('isrcharg',\n              'The first argument of the `$location#search()` call must be a string or an object.');\n        }\n        break;\n      default:\n        if (isUndefined(paramValue) || paramValue === null) {\n          delete this.$$search[search];\n        } else {\n          this.$$search[search] = paramValue;\n        }\n    }\n\n    this.$$compose();\n    return this;\n  },\n\n  /**\n   * @ngdoc method\n   * @name $location#hash\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Returns the hash fragment when called without any parameters.\n   *\n   * Changes the hash fragment when called with a parameter and returns `$location`.\n   *\n   *\n   * ```js\n   * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue\n   * var hash = $location.hash();\n   * // => \"hashValue\"\n   * ```\n   *\n   * @param {(string|number)=} hash New hash fragment\n   * @return {string} hash\n   */\n  hash: locationGetterSetter('$$hash', function(hash) {\n    return hash !== null ? hash.toString() : '';\n  }),\n\n  /**\n   * @ngdoc method\n   * @name $location#replace\n   *\n   * @description\n   * If called, all changes to $location during the current `$digest` will replace the current history\n   * record, instead of adding a new one.\n   */\n  replace: function() {\n    this.$$replace = true;\n    return this;\n  }\n};\n\nforEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) {\n  Location.prototype = Object.create(locationPrototype);\n\n  /**\n   * @ngdoc method\n   * @name $location#state\n   *\n   * @description\n   * This method is getter / setter.\n   *\n   * Return the history state object when called without any parameter.\n   *\n   * Change the history state object when called with one parameter and return `$location`.\n   * The state object is later passed to `pushState` or `replaceState`.\n   *\n   * NOTE: This method is supported only in HTML5 mode and only in browsers supporting\n   * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support\n   * older browsers (like IE9 or Android < 4.0), don't use this method.\n   *\n   * @param {object=} state State object for pushState or replaceState\n   * @return {object} state\n   */\n  Location.prototype.state = function(state) {\n    if (!arguments.length) {\n      return this.$$state;\n    }\n\n    if (Location !== LocationHtml5Url || !this.$$html5) {\n      throw $locationMinErr('nostate', 'History API state support is available only ' +\n        'in HTML5 mode and only in browsers supporting HTML5 History API');\n    }\n    // The user might modify `stateObject` after invoking `$location.state(stateObject)`\n    // but we're changing the $$state reference to $browser.state() during the $digest\n    // so the modification window is narrow.\n    this.$$state = isUndefined(state) ? null : state;\n    this.$$urlUpdatedByLocation = true;\n\n    return this;\n  };\n});\n\n\nfunction locationGetter(property) {\n  return /** @this */ function() {\n    return this[property];\n  };\n}\n\n\nfunction locationGetterSetter(property, preprocess) {\n  return /** @this */ function(value) {\n    if (isUndefined(value)) {\n      return this[property];\n    }\n\n    this[property] = preprocess(value);\n    this.$$compose();\n\n    return this;\n  };\n}\n\n\n/**\n * @ngdoc service\n * @name $location\n *\n * @requires $rootElement\n *\n * @description\n * The $location service parses the URL in the browser address bar (based on the\n * [window.location](https://developer.mozilla.org/en/window.location)) and makes the URL\n * available to your application. Changes to the URL in the address bar are reflected into\n * $location service and changes to $location are reflected into the browser address bar.\n *\n * **The $location service:**\n *\n * - Exposes the current URL in the browser address bar, so you can\n *   - Watch and observe the URL.\n *   - Change the URL.\n * - Synchronizes the URL with the browser when the user\n *   - Changes the address bar.\n *   - Clicks the back or forward button (or clicks a History link).\n *   - Clicks on a link.\n * - Represents the URL object as a set of methods (protocol, host, port, path, search, hash).\n *\n * For more information see {@link guide/$location Developer Guide: Using $location}\n */\n\n/**\n * @ngdoc provider\n * @name $locationProvider\n * @this\n *\n * @description\n * Use the `$locationProvider` to configure how the application deep linking paths are stored.\n */\nfunction $LocationProvider() {\n  var hashPrefix = '!',\n      html5Mode = {\n        enabled: false,\n        requireBase: true,\n        rewriteLinks: true\n      };\n\n  /**\n   * @ngdoc method\n   * @name $locationProvider#hashPrefix\n   * @description\n   * The default value for the prefix is `'!'`.\n   * @param {string=} prefix Prefix for hash part (containing path and search)\n   * @returns {*} current value if used as getter or itself (chaining) if used as setter\n   */\n  this.hashPrefix = function(prefix) {\n    if (isDefined(prefix)) {\n      hashPrefix = prefix;\n      return this;\n    } else {\n      return hashPrefix;\n    }\n  };\n\n  /**\n   * @ngdoc method\n   * @name $locationProvider#html5Mode\n   * @description\n   * @param {(boolean|Object)=} mode If boolean, sets `html5Mode.enabled` to value.\n   *   If object, sets `enabled`, `requireBase` and `rewriteLinks` to respective values. Supported\n   *   properties:\n   *   - **enabled** – `{boolean}` – (default: false) If true, will rely on `history.pushState` to\n   *     change urls where supported. Will fall back to hash-prefixed paths in browsers that do not\n   *     support `pushState`.\n   *   - **requireBase** - `{boolean}` - (default: `true`) When html5Mode is enabled, specifies\n   *     whether or not a <base> tag is required to be present. If `enabled` and `requireBase` are\n   *     true, and a base tag is not present, an error will be thrown when `$location` is injected.\n   *     See the {@link guide/$location $location guide for more information}\n   *   - **rewriteLinks** - `{boolean|string}` - (default: `true`) When html5Mode is enabled,\n   *     enables/disables URL rewriting for relative links. If set to a string, URL rewriting will\n   *     only happen on links with an attribute that matches the given string. For example, if set\n   *     to `'internal-link'`, then the URL will only be rewritten for `<a internal-link>` links.\n   *     Note that [attribute name normalization](guide/directive#normalization) does not apply\n   *     here, so `'internalLink'` will **not** match `'internal-link'`.\n   *\n   * @returns {Object} html5Mode object if used as getter or itself (chaining) if used as setter\n   */\n  this.html5Mode = function(mode) {\n    if (isBoolean(mode)) {\n      html5Mode.enabled = mode;\n      return this;\n    } else if (isObject(mode)) {\n\n      if (isBoolean(mode.enabled)) {\n        html5Mode.enabled = mode.enabled;\n      }\n\n      if (isBoolean(mode.requireBase)) {\n        html5Mode.requireBase = mode.requireBase;\n      }\n\n      if (isBoolean(mode.rewriteLinks) || isString(mode.rewriteLinks)) {\n        html5Mode.rewriteLinks = mode.rewriteLinks;\n      }\n\n      return this;\n    } else {\n      return html5Mode;\n    }\n  };\n\n  /**\n   * @ngdoc event\n   * @name $location#$locationChangeStart\n   * @eventType broadcast on root scope\n   * @description\n   * Broadcasted before a URL will change.\n   *\n   * This change can be prevented by calling\n   * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more\n   * details about event object. Upon successful change\n   * {@link ng.$location#$locationChangeSuccess $locationChangeSuccess} is fired.\n   *\n   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when\n   * the browser supports the HTML5 History API.\n   *\n   * @param {Object} angularEvent Synthetic event object.\n   * @param {string} newUrl New URL\n   * @param {string=} oldUrl URL that was before it was changed.\n   * @param {string=} newState New history state object\n   * @param {string=} oldState History state object that was before it was changed.\n   */\n\n  /**\n   * @ngdoc event\n   * @name $location#$locationChangeSuccess\n   * @eventType broadcast on root scope\n   * @description\n   * Broadcasted after a URL was changed.\n   *\n   * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when\n   * the browser supports the HTML5 History API.\n   *\n   * @param {Object} angularEvent Synthetic event object.\n   * @param {string} newUrl New URL\n   * @param {string=} oldUrl URL that was before it was changed.\n   * @param {string=} newState New history state object\n   * @param {string=} oldState History state object that was before it was changed.\n   */\n\n  this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', '$window',\n      function($rootScope, $browser, $sniffer, $rootElement, $window) {\n    var $location,\n        LocationMode,\n        baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''\n        initialUrl = $browser.url(),\n        appBase;\n\n    if (html5Mode.enabled) {\n      if (!baseHref && html5Mode.requireBase) {\n        throw $locationMinErr('nobase',\n          '$location in HTML5 mode requires a <base> tag to be present!');\n      }\n      appBase = serverBase(initialUrl) + (baseHref || '/');\n      LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url;\n    } else {\n      appBase = stripHash(initialUrl);\n      LocationMode = LocationHashbangUrl;\n    }\n    var appBaseNoFile = stripFile(appBase);\n\n    $location = new LocationMode(appBase, appBaseNoFile, '#' + hashPrefix);\n    $location.$$parseLinkUrl(initialUrl, initialUrl);\n\n    $location.$$state = $browser.state();\n\n    var IGNORE_URI_REGEXP = /^\\s*(javascript|mailto):/i;\n\n    function setBrowserUrlWithFallback(url, replace, state) {\n      var oldUrl = $location.url();\n      var oldState = $location.$$state;\n      try {\n        $browser.url(url, replace, state);\n\n        // Make sure $location.state() returns referentially identical (not just deeply equal)\n        // state object; this makes possible quick checking if the state changed in the digest\n        // loop. Checking deep equality would be too expensive.\n        $location.$$state = $browser.state();\n      } catch (e) {\n        // Restore old values if pushState fails\n        $location.url(oldUrl);\n        $location.$$state = oldState;\n\n        throw e;\n      }\n    }\n\n    $rootElement.on('click', function(event) {\n      var rewriteLinks = html5Mode.rewriteLinks;\n      // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)\n      // currently we open nice url link and redirect then\n\n      if (!rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 || event.button === 2) return;\n\n      var elm = jqLite(event.target);\n\n      // traverse the DOM up to find first A tag\n      while (nodeName_(elm[0]) !== 'a') {\n        // ignore rewriting if no A tag (reached root element, or no parent - removed from document)\n        if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return;\n      }\n\n      if (isString(rewriteLinks) && isUndefined(elm.attr(rewriteLinks))) return;\n\n      var absHref = elm.prop('href');\n      // get the actual href attribute - see\n      // http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx\n      var relHref = elm.attr('href') || elm.attr('xlink:href');\n\n      if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {\n        // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during\n        // an animation.\n        absHref = urlResolve(absHref.animVal).href;\n      }\n\n      // Ignore when url is started with javascript: or mailto:\n      if (IGNORE_URI_REGEXP.test(absHref)) return;\n\n      if (absHref && !elm.attr('target') && !event.isDefaultPrevented()) {\n        if ($location.$$parseLinkUrl(absHref, relHref)) {\n          // We do a preventDefault for all urls that are part of the angular application,\n          // in html5mode and also without, so that we are able to abort navigation without\n          // getting double entries in the location history.\n          event.preventDefault();\n          // update location manually\n          if ($location.absUrl() !== $browser.url()) {\n            $rootScope.$apply();\n            // hack to work around FF6 bug 684208 when scenario runner clicks on links\n            $window.angular['ff-684208-preventDefault'] = true;\n          }\n        }\n      }\n    });\n\n\n    // rewrite hashbang url <> html5 url\n    if (trimEmptyHash($location.absUrl()) !== trimEmptyHash(initialUrl)) {\n      $browser.url($location.absUrl(), true);\n    }\n\n    var initializing = true;\n\n    // update $location when $browser url changes\n    $browser.onUrlChange(function(newUrl, newState) {\n\n      if (!startsWith(newUrl, appBaseNoFile)) {\n        // If we are navigating outside of the app then force a reload\n        $window.location.href = newUrl;\n        return;\n      }\n\n      $rootScope.$evalAsync(function() {\n        var oldUrl = $location.absUrl();\n        var oldState = $location.$$state;\n        var defaultPrevented;\n        newUrl = trimEmptyHash(newUrl);\n        $location.$$parse(newUrl);\n        $location.$$state = newState;\n\n        defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,\n            newState, oldState).defaultPrevented;\n\n        // if the location was changed by a `$locationChangeStart` handler then stop\n        // processing this location change\n        if ($location.absUrl() !== newUrl) return;\n\n        if (defaultPrevented) {\n          $location.$$parse(oldUrl);\n          $location.$$state = oldState;\n          setBrowserUrlWithFallback(oldUrl, false, oldState);\n        } else {\n          initializing = false;\n          afterLocationChange(oldUrl, oldState);\n        }\n      });\n      if (!$rootScope.$$phase) $rootScope.$digest();\n    });\n\n    // update browser\n    $rootScope.$watch(function $locationWatch() {\n      if (initializing || $location.$$urlUpdatedByLocation) {\n        $location.$$urlUpdatedByLocation = false;\n\n        var oldUrl = trimEmptyHash($browser.url());\n        var newUrl = trimEmptyHash($location.absUrl());\n        var oldState = $browser.state();\n        var currentReplace = $location.$$replace;\n        var urlOrStateChanged = oldUrl !== newUrl ||\n          ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);\n\n        if (initializing || urlOrStateChanged) {\n          initializing = false;\n\n          $rootScope.$evalAsync(function() {\n            var newUrl = $location.absUrl();\n            var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,\n                $location.$$state, oldState).defaultPrevented;\n\n            // if the location was changed by a `$locationChangeStart` handler then stop\n            // processing this location change\n            if ($location.absUrl() !== newUrl) return;\n\n            if (defaultPrevented) {\n              $location.$$parse(oldUrl);\n              $location.$$state = oldState;\n            } else {\n              if (urlOrStateChanged) {\n                setBrowserUrlWithFallback(newUrl, currentReplace,\n                                          oldState === $location.$$state ? null : $location.$$state);\n              }\n              afterLocationChange(oldUrl, oldState);\n            }\n          });\n        }\n      }\n\n      $location.$$replace = false;\n\n      // we don't need to return anything because $evalAsync will make the digest loop dirty when\n      // there is a change\n    });\n\n    return $location;\n\n    function afterLocationChange(oldUrl, oldState) {\n      $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl,\n        $location.$$state, oldState);\n    }\n}];\n}\n\n/**\n * @ngdoc service\n * @name $log\n * @requires $window\n *\n * @description\n * Simple service for logging. Default implementation safely writes the message\n * into the browser's console (if present).\n *\n * The main purpose of this service is to simplify debugging and troubleshooting.\n *\n * The default is to log `debug` messages. You can use\n * {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.\n *\n * @example\n   <example module=\"logExample\" name=\"log-service\">\n     <file name=\"script.js\">\n       angular.module('logExample', [])\n         .controller('LogController', ['$scope', '$log', function($scope, $log) {\n           $scope.$log = $log;\n           $scope.message = 'Hello World!';\n         }]);\n     </file>\n     <file name=\"index.html\">\n       <div ng-controller=\"LogController\">\n         <p>Reload this page with open console, enter text and hit the log button...</p>\n         <label>Message:\n         <input type=\"text\" ng-model=\"message\" /></label>\n         <button ng-click=\"$log.log(message)\">log</button>\n         <button ng-click=\"$log.warn(message)\">warn</button>\n         <button ng-click=\"$log.info(message)\">info</button>\n         <button ng-click=\"$log.error(message)\">error</button>\n         <button ng-click=\"$log.debug(message)\">debug</button>\n       </div>\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc provider\n * @name $logProvider\n * @this\n *\n * @description\n * Use the `$logProvider` to configure how the application logs messages\n */\nfunction $LogProvider() {\n  var debug = true,\n      self = this;\n\n  /**\n   * @ngdoc method\n   * @name $logProvider#debugEnabled\n   * @description\n   * @param {boolean=} flag enable or disable debug level messages\n   * @returns {*} current value if used as getter or itself (chaining) if used as setter\n   */\n  this.debugEnabled = function(flag) {\n    if (isDefined(flag)) {\n      debug = flag;\n      return this;\n    } else {\n      return debug;\n    }\n  };\n\n  this.$get = ['$window', function($window) {\n    // Support: IE 9-11, Edge 12-14+\n    // IE/Edge display errors in such a way that it requires the user to click in 4 places\n    // to see the stack trace. There is no way to feature-detect it so there's a chance\n    // of the user agent sniffing to go wrong but since it's only about logging, this shouldn't\n    // break apps. Other browsers display errors in a sensible way and some of them map stack\n    // traces along source maps if available so it makes sense to let browsers display it\n    // as they want.\n    var formatStackTrace = msie || /\\bEdge\\//.test($window.navigator && $window.navigator.userAgent);\n\n    return {\n      /**\n       * @ngdoc method\n       * @name $log#log\n       *\n       * @description\n       * Write a log message\n       */\n      log: consoleLog('log'),\n\n      /**\n       * @ngdoc method\n       * @name $log#info\n       *\n       * @description\n       * Write an information message\n       */\n      info: consoleLog('info'),\n\n      /**\n       * @ngdoc method\n       * @name $log#warn\n       *\n       * @description\n       * Write a warning message\n       */\n      warn: consoleLog('warn'),\n\n      /**\n       * @ngdoc method\n       * @name $log#error\n       *\n       * @description\n       * Write an error message\n       */\n      error: consoleLog('error'),\n\n      /**\n       * @ngdoc method\n       * @name $log#debug\n       *\n       * @description\n       * Write a debug message\n       */\n      debug: (function() {\n        var fn = consoleLog('debug');\n\n        return function() {\n          if (debug) {\n            fn.apply(self, arguments);\n          }\n        };\n      })()\n    };\n\n    function formatError(arg) {\n      if (arg instanceof Error) {\n        if (arg.stack && formatStackTrace) {\n          arg = (arg.message && arg.stack.indexOf(arg.message) === -1)\n              ? 'Error: ' + arg.message + '\\n' + arg.stack\n              : arg.stack;\n        } else if (arg.sourceURL) {\n          arg = arg.message + '\\n' + arg.sourceURL + ':' + arg.line;\n        }\n      }\n      return arg;\n    }\n\n    function consoleLog(type) {\n      var console = $window.console || {},\n          logFn = console[type] || console.log || noop,\n          hasApply = false;\n\n      // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.\n      // The reason behind this is that console.log has type \"object\" in IE8...\n      try {\n        hasApply = !!logFn.apply;\n      } catch (e) { /* empty */ }\n\n      if (hasApply) {\n        return function() {\n          var args = [];\n          forEach(arguments, function(arg) {\n            args.push(formatError(arg));\n          });\n          return logFn.apply(console, args);\n        };\n      }\n\n      // we are IE which either doesn't have window.console => this is noop and we do nothing,\n      // or we are IE where console.log doesn't have apply so we log at least first 2 args\n      return function(arg1, arg2) {\n        logFn(arg1, arg2 == null ? '' : arg2);\n      };\n    }\n  }];\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *     Any commits to this file should be reviewed with security in mind.  *\n *   Changes to this file can potentially create security vulnerabilities. *\n *          An approval from 2 Core members with history of modifying      *\n *                         this file is required.                          *\n *                                                                         *\n *  Does the change somehow allow for arbitrary javascript to be executed? *\n *    Or allows for someone to change the prototype of built-in objects?   *\n *     Or gives undesired access to variables likes document or window?    *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\nvar $parseMinErr = minErr('$parse');\n\nvar objectValueOf = {}.constructor.prototype.valueOf;\n\n// Sandboxing Angular Expressions\n// ------------------------------\n// Angular expressions are no longer sandboxed. So it is now even easier to access arbitrary JS code by\n// various means such as obtaining a reference to native JS functions like the Function constructor.\n//\n// As an example, consider the following Angular expression:\n//\n//   {}.toString.constructor('alert(\"evil JS code\")')\n//\n// It is important to realize that if you create an expression from a string that contains user provided\n// content then it is possible that your application contains a security vulnerability to an XSS style attack.\n//\n// See https://docs.angularjs.org/guide/security\n\n\nfunction getStringValue(name) {\n  // Property names must be strings. This means that non-string objects cannot be used\n  // as keys in an object. Any non-string object, including a number, is typecasted\n  // into a string via the toString method.\n  // -- MDN, https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors#Property_names\n  //\n  // So, to ensure that we are checking the same `name` that JavaScript would use, we cast it\n  // to a string. It's not always possible. If `name` is an object and its `toString` method is\n  // 'broken' (doesn't return a string, isn't a function, etc.), an error will be thrown:\n  //\n  // TypeError: Cannot convert object to primitive value\n  //\n  // For performance reasons, we don't catch this error here and allow it to propagate up the call\n  // stack. Note that you'll get the same error in JavaScript if you try to access a property using\n  // such a 'broken' object as a key.\n  return name + '';\n}\n\n\nvar OPERATORS = createMap();\nforEach('+ - * / % === !== == != < > <= >= && || ! = |'.split(' '), function(operator) { OPERATORS[operator] = true; });\nvar ESCAPE = {'n':'\\n', 'f':'\\f', 'r':'\\r', 't':'\\t', 'v':'\\v', '\\'':'\\'', '\"':'\"'};\n\n\n/////////////////////////////////////////\n\n\n/**\n * @constructor\n */\nvar Lexer = function Lexer(options) {\n  this.options = options;\n};\n\nLexer.prototype = {\n  constructor: Lexer,\n\n  lex: function(text) {\n    this.text = text;\n    this.index = 0;\n    this.tokens = [];\n\n    while (this.index < this.text.length) {\n      var ch = this.text.charAt(this.index);\n      if (ch === '\"' || ch === '\\'') {\n        this.readString(ch);\n      } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {\n        this.readNumber();\n      } else if (this.isIdentifierStart(this.peekMultichar())) {\n        this.readIdent();\n      } else if (this.is(ch, '(){}[].,;:?')) {\n        this.tokens.push({index: this.index, text: ch});\n        this.index++;\n      } else if (this.isWhitespace(ch)) {\n        this.index++;\n      } else {\n        var ch2 = ch + this.peek();\n        var ch3 = ch2 + this.peek(2);\n        var op1 = OPERATORS[ch];\n        var op2 = OPERATORS[ch2];\n        var op3 = OPERATORS[ch3];\n        if (op1 || op2 || op3) {\n          var token = op3 ? ch3 : (op2 ? ch2 : ch);\n          this.tokens.push({index: this.index, text: token, operator: true});\n          this.index += token.length;\n        } else {\n          this.throwError('Unexpected next character ', this.index, this.index + 1);\n        }\n      }\n    }\n    return this.tokens;\n  },\n\n  is: function(ch, chars) {\n    return chars.indexOf(ch) !== -1;\n  },\n\n  peek: function(i) {\n    var num = i || 1;\n    return (this.index + num < this.text.length) ? this.text.charAt(this.index + num) : false;\n  },\n\n  isNumber: function(ch) {\n    return ('0' <= ch && ch <= '9') && typeof ch === 'string';\n  },\n\n  isWhitespace: function(ch) {\n    // IE treats non-breaking space as \\u00A0\n    return (ch === ' ' || ch === '\\r' || ch === '\\t' ||\n            ch === '\\n' || ch === '\\v' || ch === '\\u00A0');\n  },\n\n  isIdentifierStart: function(ch) {\n    return this.options.isIdentifierStart ?\n        this.options.isIdentifierStart(ch, this.codePointAt(ch)) :\n        this.isValidIdentifierStart(ch);\n  },\n\n  isValidIdentifierStart: function(ch) {\n    return ('a' <= ch && ch <= 'z' ||\n            'A' <= ch && ch <= 'Z' ||\n            '_' === ch || ch === '$');\n  },\n\n  isIdentifierContinue: function(ch) {\n    return this.options.isIdentifierContinue ?\n        this.options.isIdentifierContinue(ch, this.codePointAt(ch)) :\n        this.isValidIdentifierContinue(ch);\n  },\n\n  isValidIdentifierContinue: function(ch, cp) {\n    return this.isValidIdentifierStart(ch, cp) || this.isNumber(ch);\n  },\n\n  codePointAt: function(ch) {\n    if (ch.length === 1) return ch.charCodeAt(0);\n    // eslint-disable-next-line no-bitwise\n    return (ch.charCodeAt(0) << 10) + ch.charCodeAt(1) - 0x35FDC00;\n  },\n\n  peekMultichar: function() {\n    var ch = this.text.charAt(this.index);\n    var peek = this.peek();\n    if (!peek) {\n      return ch;\n    }\n    var cp1 = ch.charCodeAt(0);\n    var cp2 = peek.charCodeAt(0);\n    if (cp1 >= 0xD800 && cp1 <= 0xDBFF && cp2 >= 0xDC00 && cp2 <= 0xDFFF) {\n      return ch + peek;\n    }\n    return ch;\n  },\n\n  isExpOperator: function(ch) {\n    return (ch === '-' || ch === '+' || this.isNumber(ch));\n  },\n\n  throwError: function(error, start, end) {\n    end = end || this.index;\n    var colStr = (isDefined(start)\n            ? 's ' + start +  '-' + this.index + ' [' + this.text.substring(start, end) + ']'\n            : ' ' + end);\n    throw $parseMinErr('lexerr', 'Lexer Error: {0} at column{1} in expression [{2}].',\n        error, colStr, this.text);\n  },\n\n  readNumber: function() {\n    var number = '';\n    var start = this.index;\n    while (this.index < this.text.length) {\n      var ch = lowercase(this.text.charAt(this.index));\n      if (ch === '.' || this.isNumber(ch)) {\n        number += ch;\n      } else {\n        var peekCh = this.peek();\n        if (ch === 'e' && this.isExpOperator(peekCh)) {\n          number += ch;\n        } else if (this.isExpOperator(ch) &&\n            peekCh && this.isNumber(peekCh) &&\n            number.charAt(number.length - 1) === 'e') {\n          number += ch;\n        } else if (this.isExpOperator(ch) &&\n            (!peekCh || !this.isNumber(peekCh)) &&\n            number.charAt(number.length - 1) === 'e') {\n          this.throwError('Invalid exponent');\n        } else {\n          break;\n        }\n      }\n      this.index++;\n    }\n    this.tokens.push({\n      index: start,\n      text: number,\n      constant: true,\n      value: Number(number)\n    });\n  },\n\n  readIdent: function() {\n    var start = this.index;\n    this.index += this.peekMultichar().length;\n    while (this.index < this.text.length) {\n      var ch = this.peekMultichar();\n      if (!this.isIdentifierContinue(ch)) {\n        break;\n      }\n      this.index += ch.length;\n    }\n    this.tokens.push({\n      index: start,\n      text: this.text.slice(start, this.index),\n      identifier: true\n    });\n  },\n\n  readString: function(quote) {\n    var start = this.index;\n    this.index++;\n    var string = '';\n    var rawString = quote;\n    var escape = false;\n    while (this.index < this.text.length) {\n      var ch = this.text.charAt(this.index);\n      rawString += ch;\n      if (escape) {\n        if (ch === 'u') {\n          var hex = this.text.substring(this.index + 1, this.index + 5);\n          if (!hex.match(/[\\da-f]{4}/i)) {\n            this.throwError('Invalid unicode escape [\\\\u' + hex + ']');\n          }\n          this.index += 4;\n          string += String.fromCharCode(parseInt(hex, 16));\n        } else {\n          var rep = ESCAPE[ch];\n          string = string + (rep || ch);\n        }\n        escape = false;\n      } else if (ch === '\\\\') {\n        escape = true;\n      } else if (ch === quote) {\n        this.index++;\n        this.tokens.push({\n          index: start,\n          text: rawString,\n          constant: true,\n          value: string\n        });\n        return;\n      } else {\n        string += ch;\n      }\n      this.index++;\n    }\n    this.throwError('Unterminated quote', start);\n  }\n};\n\nvar AST = function AST(lexer, options) {\n  this.lexer = lexer;\n  this.options = options;\n};\n\nAST.Program = 'Program';\nAST.ExpressionStatement = 'ExpressionStatement';\nAST.AssignmentExpression = 'AssignmentExpression';\nAST.ConditionalExpression = 'ConditionalExpression';\nAST.LogicalExpression = 'LogicalExpression';\nAST.BinaryExpression = 'BinaryExpression';\nAST.UnaryExpression = 'UnaryExpression';\nAST.CallExpression = 'CallExpression';\nAST.MemberExpression = 'MemberExpression';\nAST.Identifier = 'Identifier';\nAST.Literal = 'Literal';\nAST.ArrayExpression = 'ArrayExpression';\nAST.Property = 'Property';\nAST.ObjectExpression = 'ObjectExpression';\nAST.ThisExpression = 'ThisExpression';\nAST.LocalsExpression = 'LocalsExpression';\n\n// Internal use only\nAST.NGValueParameter = 'NGValueParameter';\n\nAST.prototype = {\n  ast: function(text) {\n    this.text = text;\n    this.tokens = this.lexer.lex(text);\n\n    var value = this.program();\n\n    if (this.tokens.length !== 0) {\n      this.throwError('is an unexpected token', this.tokens[0]);\n    }\n\n    return value;\n  },\n\n  program: function() {\n    var body = [];\n    while (true) {\n      if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']'))\n        body.push(this.expressionStatement());\n      if (!this.expect(';')) {\n        return { type: AST.Program, body: body};\n      }\n    }\n  },\n\n  expressionStatement: function() {\n    return { type: AST.ExpressionStatement, expression: this.filterChain() };\n  },\n\n  filterChain: function() {\n    var left = this.expression();\n    while (this.expect('|')) {\n      left = this.filter(left);\n    }\n    return left;\n  },\n\n  expression: function() {\n    return this.assignment();\n  },\n\n  assignment: function() {\n    var result = this.ternary();\n    if (this.expect('=')) {\n      if (!isAssignable(result)) {\n        throw $parseMinErr('lval', 'Trying to assign a value to a non l-value');\n      }\n\n      result = { type: AST.AssignmentExpression, left: result, right: this.assignment(), operator: '='};\n    }\n    return result;\n  },\n\n  ternary: function() {\n    var test = this.logicalOR();\n    var alternate;\n    var consequent;\n    if (this.expect('?')) {\n      alternate = this.expression();\n      if (this.consume(':')) {\n        consequent = this.expression();\n        return { type: AST.ConditionalExpression, test: test, alternate: alternate, consequent: consequent};\n      }\n    }\n    return test;\n  },\n\n  logicalOR: function() {\n    var left = this.logicalAND();\n    while (this.expect('||')) {\n      left = { type: AST.LogicalExpression, operator: '||', left: left, right: this.logicalAND() };\n    }\n    return left;\n  },\n\n  logicalAND: function() {\n    var left = this.equality();\n    while (this.expect('&&')) {\n      left = { type: AST.LogicalExpression, operator: '&&', left: left, right: this.equality()};\n    }\n    return left;\n  },\n\n  equality: function() {\n    var left = this.relational();\n    var token;\n    while ((token = this.expect('==','!=','===','!=='))) {\n      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.relational() };\n    }\n    return left;\n  },\n\n  relational: function() {\n    var left = this.additive();\n    var token;\n    while ((token = this.expect('<', '>', '<=', '>='))) {\n      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.additive() };\n    }\n    return left;\n  },\n\n  additive: function() {\n    var left = this.multiplicative();\n    var token;\n    while ((token = this.expect('+','-'))) {\n      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.multiplicative() };\n    }\n    return left;\n  },\n\n  multiplicative: function() {\n    var left = this.unary();\n    var token;\n    while ((token = this.expect('*','/','%'))) {\n      left = { type: AST.BinaryExpression, operator: token.text, left: left, right: this.unary() };\n    }\n    return left;\n  },\n\n  unary: function() {\n    var token;\n    if ((token = this.expect('+', '-', '!'))) {\n      return { type: AST.UnaryExpression, operator: token.text, prefix: true, argument: this.unary() };\n    } else {\n      return this.primary();\n    }\n  },\n\n  primary: function() {\n    var primary;\n    if (this.expect('(')) {\n      primary = this.filterChain();\n      this.consume(')');\n    } else if (this.expect('[')) {\n      primary = this.arrayDeclaration();\n    } else if (this.expect('{')) {\n      primary = this.object();\n    } else if (this.selfReferential.hasOwnProperty(this.peek().text)) {\n      primary = copy(this.selfReferential[this.consume().text]);\n    } else if (this.options.literals.hasOwnProperty(this.peek().text)) {\n      primary = { type: AST.Literal, value: this.options.literals[this.consume().text]};\n    } else if (this.peek().identifier) {\n      primary = this.identifier();\n    } else if (this.peek().constant) {\n      primary = this.constant();\n    } else {\n      this.throwError('not a primary expression', this.peek());\n    }\n\n    var next;\n    while ((next = this.expect('(', '[', '.'))) {\n      if (next.text === '(') {\n        primary = {type: AST.CallExpression, callee: primary, arguments: this.parseArguments() };\n        this.consume(')');\n      } else if (next.text === '[') {\n        primary = { type: AST.MemberExpression, object: primary, property: this.expression(), computed: true };\n        this.consume(']');\n      } else if (next.text === '.') {\n        primary = { type: AST.MemberExpression, object: primary, property: this.identifier(), computed: false };\n      } else {\n        this.throwError('IMPOSSIBLE');\n      }\n    }\n    return primary;\n  },\n\n  filter: function(baseExpression) {\n    var args = [baseExpression];\n    var result = {type: AST.CallExpression, callee: this.identifier(), arguments: args, filter: true};\n\n    while (this.expect(':')) {\n      args.push(this.expression());\n    }\n\n    return result;\n  },\n\n  parseArguments: function() {\n    var args = [];\n    if (this.peekToken().text !== ')') {\n      do {\n        args.push(this.filterChain());\n      } while (this.expect(','));\n    }\n    return args;\n  },\n\n  identifier: function() {\n    var token = this.consume();\n    if (!token.identifier) {\n      this.throwError('is not a valid identifier', token);\n    }\n    return { type: AST.Identifier, name: token.text };\n  },\n\n  constant: function() {\n    // TODO check that it is a constant\n    return { type: AST.Literal, value: this.consume().value };\n  },\n\n  arrayDeclaration: function() {\n    var elements = [];\n    if (this.peekToken().text !== ']') {\n      do {\n        if (this.peek(']')) {\n          // Support trailing commas per ES5.1.\n          break;\n        }\n        elements.push(this.expression());\n      } while (this.expect(','));\n    }\n    this.consume(']');\n\n    return { type: AST.ArrayExpression, elements: elements };\n  },\n\n  object: function() {\n    var properties = [], property;\n    if (this.peekToken().text !== '}') {\n      do {\n        if (this.peek('}')) {\n          // Support trailing commas per ES5.1.\n          break;\n        }\n        property = {type: AST.Property, kind: 'init'};\n        if (this.peek().constant) {\n          property.key = this.constant();\n          property.computed = false;\n          this.consume(':');\n          property.value = this.expression();\n        } else if (this.peek().identifier) {\n          property.key = this.identifier();\n          property.computed = false;\n          if (this.peek(':')) {\n            this.consume(':');\n            property.value = this.expression();\n          } else {\n            property.value = property.key;\n          }\n        } else if (this.peek('[')) {\n          this.consume('[');\n          property.key = this.expression();\n          this.consume(']');\n          property.computed = true;\n          this.consume(':');\n          property.value = this.expression();\n        } else {\n          this.throwError('invalid key', this.peek());\n        }\n        properties.push(property);\n      } while (this.expect(','));\n    }\n    this.consume('}');\n\n    return {type: AST.ObjectExpression, properties: properties };\n  },\n\n  throwError: function(msg, token) {\n    throw $parseMinErr('syntax',\n        'Syntax Error: Token \\'{0}\\' {1} at column {2} of the expression [{3}] starting at [{4}].',\n          token.text, msg, (token.index + 1), this.text, this.text.substring(token.index));\n  },\n\n  consume: function(e1) {\n    if (this.tokens.length === 0) {\n      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);\n    }\n\n    var token = this.expect(e1);\n    if (!token) {\n      this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());\n    }\n    return token;\n  },\n\n  peekToken: function() {\n    if (this.tokens.length === 0) {\n      throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);\n    }\n    return this.tokens[0];\n  },\n\n  peek: function(e1, e2, e3, e4) {\n    return this.peekAhead(0, e1, e2, e3, e4);\n  },\n\n  peekAhead: function(i, e1, e2, e3, e4) {\n    if (this.tokens.length > i) {\n      var token = this.tokens[i];\n      var t = token.text;\n      if (t === e1 || t === e2 || t === e3 || t === e4 ||\n          (!e1 && !e2 && !e3 && !e4)) {\n        return token;\n      }\n    }\n    return false;\n  },\n\n  expect: function(e1, e2, e3, e4) {\n    var token = this.peek(e1, e2, e3, e4);\n    if (token) {\n      this.tokens.shift();\n      return token;\n    }\n    return false;\n  },\n\n  selfReferential: {\n    'this': {type: AST.ThisExpression },\n    '$locals': {type: AST.LocalsExpression }\n  }\n};\n\nfunction ifDefined(v, d) {\n  return typeof v !== 'undefined' ? v : d;\n}\n\nfunction plusFn(l, r) {\n  if (typeof l === 'undefined') return r;\n  if (typeof r === 'undefined') return l;\n  return l + r;\n}\n\nfunction isStateless($filter, filterName) {\n  var fn = $filter(filterName);\n  return !fn.$stateful;\n}\n\nfunction findConstantAndWatchExpressions(ast, $filter) {\n  var allConstants;\n  var argsToWatch;\n  var isStatelessFilter;\n  switch (ast.type) {\n  case AST.Program:\n    allConstants = true;\n    forEach(ast.body, function(expr) {\n      findConstantAndWatchExpressions(expr.expression, $filter);\n      allConstants = allConstants && expr.expression.constant;\n    });\n    ast.constant = allConstants;\n    break;\n  case AST.Literal:\n    ast.constant = true;\n    ast.toWatch = [];\n    break;\n  case AST.UnaryExpression:\n    findConstantAndWatchExpressions(ast.argument, $filter);\n    ast.constant = ast.argument.constant;\n    ast.toWatch = ast.argument.toWatch;\n    break;\n  case AST.BinaryExpression:\n    findConstantAndWatchExpressions(ast.left, $filter);\n    findConstantAndWatchExpressions(ast.right, $filter);\n    ast.constant = ast.left.constant && ast.right.constant;\n    ast.toWatch = ast.left.toWatch.concat(ast.right.toWatch);\n    break;\n  case AST.LogicalExpression:\n    findConstantAndWatchExpressions(ast.left, $filter);\n    findConstantAndWatchExpressions(ast.right, $filter);\n    ast.constant = ast.left.constant && ast.right.constant;\n    ast.toWatch = ast.constant ? [] : [ast];\n    break;\n  case AST.ConditionalExpression:\n    findConstantAndWatchExpressions(ast.test, $filter);\n    findConstantAndWatchExpressions(ast.alternate, $filter);\n    findConstantAndWatchExpressions(ast.consequent, $filter);\n    ast.constant = ast.test.constant && ast.alternate.constant && ast.consequent.constant;\n    ast.toWatch = ast.constant ? [] : [ast];\n    break;\n  case AST.Identifier:\n    ast.constant = false;\n    ast.toWatch = [ast];\n    break;\n  case AST.MemberExpression:\n    findConstantAndWatchExpressions(ast.object, $filter);\n    if (ast.computed) {\n      findConstantAndWatchExpressions(ast.property, $filter);\n    }\n    ast.constant = ast.object.constant && (!ast.computed || ast.property.constant);\n    ast.toWatch = [ast];\n    break;\n  case AST.CallExpression:\n    isStatelessFilter = ast.filter ? isStateless($filter, ast.callee.name) : false;\n    allConstants = isStatelessFilter;\n    argsToWatch = [];\n    forEach(ast.arguments, function(expr) {\n      findConstantAndWatchExpressions(expr, $filter);\n      allConstants = allConstants && expr.constant;\n      if (!expr.constant) {\n        argsToWatch.push.apply(argsToWatch, expr.toWatch);\n      }\n    });\n    ast.constant = allConstants;\n    ast.toWatch = isStatelessFilter ? argsToWatch : [ast];\n    break;\n  case AST.AssignmentExpression:\n    findConstantAndWatchExpressions(ast.left, $filter);\n    findConstantAndWatchExpressions(ast.right, $filter);\n    ast.constant = ast.left.constant && ast.right.constant;\n    ast.toWatch = [ast];\n    break;\n  case AST.ArrayExpression:\n    allConstants = true;\n    argsToWatch = [];\n    forEach(ast.elements, function(expr) {\n      findConstantAndWatchExpressions(expr, $filter);\n      allConstants = allConstants && expr.constant;\n      if (!expr.constant) {\n        argsToWatch.push.apply(argsToWatch, expr.toWatch);\n      }\n    });\n    ast.constant = allConstants;\n    ast.toWatch = argsToWatch;\n    break;\n  case AST.ObjectExpression:\n    allConstants = true;\n    argsToWatch = [];\n    forEach(ast.properties, function(property) {\n      findConstantAndWatchExpressions(property.value, $filter);\n      allConstants = allConstants && property.value.constant && !property.computed;\n      if (!property.value.constant) {\n        argsToWatch.push.apply(argsToWatch, property.value.toWatch);\n      }\n      if (property.computed) {\n        findConstantAndWatchExpressions(property.key, $filter);\n        if (!property.key.constant) {\n          argsToWatch.push.apply(argsToWatch, property.key.toWatch);\n        }\n      }\n\n    });\n    ast.constant = allConstants;\n    ast.toWatch = argsToWatch;\n    break;\n  case AST.ThisExpression:\n    ast.constant = false;\n    ast.toWatch = [];\n    break;\n  case AST.LocalsExpression:\n    ast.constant = false;\n    ast.toWatch = [];\n    break;\n  }\n}\n\nfunction getInputs(body) {\n  if (body.length !== 1) return;\n  var lastExpression = body[0].expression;\n  var candidate = lastExpression.toWatch;\n  if (candidate.length !== 1) return candidate;\n  return candidate[0] !== lastExpression ? candidate : undefined;\n}\n\nfunction isAssignable(ast) {\n  return ast.type === AST.Identifier || ast.type === AST.MemberExpression;\n}\n\nfunction assignableAST(ast) {\n  if (ast.body.length === 1 && isAssignable(ast.body[0].expression)) {\n    return {type: AST.AssignmentExpression, left: ast.body[0].expression, right: {type: AST.NGValueParameter}, operator: '='};\n  }\n}\n\nfunction isLiteral(ast) {\n  return ast.body.length === 0 ||\n      ast.body.length === 1 && (\n      ast.body[0].expression.type === AST.Literal ||\n      ast.body[0].expression.type === AST.ArrayExpression ||\n      ast.body[0].expression.type === AST.ObjectExpression);\n}\n\nfunction isConstant(ast) {\n  return ast.constant;\n}\n\nfunction ASTCompiler(astBuilder, $filter) {\n  this.astBuilder = astBuilder;\n  this.$filter = $filter;\n}\n\nASTCompiler.prototype = {\n  compile: function(expression) {\n    var self = this;\n    var ast = this.astBuilder.ast(expression);\n    this.state = {\n      nextId: 0,\n      filters: {},\n      fn: {vars: [], body: [], own: {}},\n      assign: {vars: [], body: [], own: {}},\n      inputs: []\n    };\n    findConstantAndWatchExpressions(ast, self.$filter);\n    var extra = '';\n    var assignable;\n    this.stage = 'assign';\n    if ((assignable = assignableAST(ast))) {\n      this.state.computing = 'assign';\n      var result = this.nextId();\n      this.recurse(assignable, result);\n      this.return_(result);\n      extra = 'fn.assign=' + this.generateFunction('assign', 's,v,l');\n    }\n    var toWatch = getInputs(ast.body);\n    self.stage = 'inputs';\n    forEach(toWatch, function(watch, key) {\n      var fnKey = 'fn' + key;\n      self.state[fnKey] = {vars: [], body: [], own: {}};\n      self.state.computing = fnKey;\n      var intoId = self.nextId();\n      self.recurse(watch, intoId);\n      self.return_(intoId);\n      self.state.inputs.push(fnKey);\n      watch.watchId = key;\n    });\n    this.state.computing = 'fn';\n    this.stage = 'main';\n    this.recurse(ast);\n    var fnString =\n      // The build and minification steps remove the string \"use strict\" from the code, but this is done using a regex.\n      // This is a workaround for this until we do a better job at only removing the prefix only when we should.\n      '\"' + this.USE + ' ' + this.STRICT + '\";\\n' +\n      this.filterPrefix() +\n      'var fn=' + this.generateFunction('fn', 's,l,a,i') +\n      extra +\n      this.watchFns() +\n      'return fn;';\n\n    // eslint-disable-next-line no-new-func\n    var fn = (new Function('$filter',\n        'getStringValue',\n        'ifDefined',\n        'plus',\n        fnString))(\n          this.$filter,\n          getStringValue,\n          ifDefined,\n          plusFn);\n    this.state = this.stage = undefined;\n    fn.literal = isLiteral(ast);\n    fn.constant = isConstant(ast);\n    return fn;\n  },\n\n  USE: 'use',\n\n  STRICT: 'strict',\n\n  watchFns: function() {\n    var result = [];\n    var fns = this.state.inputs;\n    var self = this;\n    forEach(fns, function(name) {\n      result.push('var ' + name + '=' + self.generateFunction(name, 's'));\n    });\n    if (fns.length) {\n      result.push('fn.inputs=[' + fns.join(',') + '];');\n    }\n    return result.join('');\n  },\n\n  generateFunction: function(name, params) {\n    return 'function(' + params + '){' +\n        this.varsPrefix(name) +\n        this.body(name) +\n        '};';\n  },\n\n  filterPrefix: function() {\n    var parts = [];\n    var self = this;\n    forEach(this.state.filters, function(id, filter) {\n      parts.push(id + '=$filter(' + self.escape(filter) + ')');\n    });\n    if (parts.length) return 'var ' + parts.join(',') + ';';\n    return '';\n  },\n\n  varsPrefix: function(section) {\n    return this.state[section].vars.length ? 'var ' + this.state[section].vars.join(',') + ';' : '';\n  },\n\n  body: function(section) {\n    return this.state[section].body.join('');\n  },\n\n  recurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {\n    var left, right, self = this, args, expression, computed;\n    recursionFn = recursionFn || noop;\n    if (!skipWatchIdCheck && isDefined(ast.watchId)) {\n      intoId = intoId || this.nextId();\n      this.if_('i',\n        this.lazyAssign(intoId, this.computedMember('i', ast.watchId)),\n        this.lazyRecurse(ast, intoId, nameId, recursionFn, create, true)\n      );\n      return;\n    }\n    switch (ast.type) {\n    case AST.Program:\n      forEach(ast.body, function(expression, pos) {\n        self.recurse(expression.expression, undefined, undefined, function(expr) { right = expr; });\n        if (pos !== ast.body.length - 1) {\n          self.current().body.push(right, ';');\n        } else {\n          self.return_(right);\n        }\n      });\n      break;\n    case AST.Literal:\n      expression = this.escape(ast.value);\n      this.assign(intoId, expression);\n      recursionFn(intoId || expression);\n      break;\n    case AST.UnaryExpression:\n      this.recurse(ast.argument, undefined, undefined, function(expr) { right = expr; });\n      expression = ast.operator + '(' + this.ifDefined(right, 0) + ')';\n      this.assign(intoId, expression);\n      recursionFn(expression);\n      break;\n    case AST.BinaryExpression:\n      this.recurse(ast.left, undefined, undefined, function(expr) { left = expr; });\n      this.recurse(ast.right, undefined, undefined, function(expr) { right = expr; });\n      if (ast.operator === '+') {\n        expression = this.plus(left, right);\n      } else if (ast.operator === '-') {\n        expression = this.ifDefined(left, 0) + ast.operator + this.ifDefined(right, 0);\n      } else {\n        expression = '(' + left + ')' + ast.operator + '(' + right + ')';\n      }\n      this.assign(intoId, expression);\n      recursionFn(expression);\n      break;\n    case AST.LogicalExpression:\n      intoId = intoId || this.nextId();\n      self.recurse(ast.left, intoId);\n      self.if_(ast.operator === '&&' ? intoId : self.not(intoId), self.lazyRecurse(ast.right, intoId));\n      recursionFn(intoId);\n      break;\n    case AST.ConditionalExpression:\n      intoId = intoId || this.nextId();\n      self.recurse(ast.test, intoId);\n      self.if_(intoId, self.lazyRecurse(ast.alternate, intoId), self.lazyRecurse(ast.consequent, intoId));\n      recursionFn(intoId);\n      break;\n    case AST.Identifier:\n      intoId = intoId || this.nextId();\n      if (nameId) {\n        nameId.context = self.stage === 'inputs' ? 's' : this.assign(this.nextId(), this.getHasOwnProperty('l', ast.name) + '?l:s');\n        nameId.computed = false;\n        nameId.name = ast.name;\n      }\n      self.if_(self.stage === 'inputs' || self.not(self.getHasOwnProperty('l', ast.name)),\n        function() {\n          self.if_(self.stage === 'inputs' || 's', function() {\n            if (create && create !== 1) {\n              self.if_(\n                self.isNull(self.nonComputedMember('s', ast.name)),\n                self.lazyAssign(self.nonComputedMember('s', ast.name), '{}'));\n            }\n            self.assign(intoId, self.nonComputedMember('s', ast.name));\n          });\n        }, intoId && self.lazyAssign(intoId, self.nonComputedMember('l', ast.name))\n        );\n      recursionFn(intoId);\n      break;\n    case AST.MemberExpression:\n      left = nameId && (nameId.context = this.nextId()) || this.nextId();\n      intoId = intoId || this.nextId();\n      self.recurse(ast.object, left, undefined, function() {\n        self.if_(self.notNull(left), function() {\n          if (ast.computed) {\n            right = self.nextId();\n            self.recurse(ast.property, right);\n            self.getStringValue(right);\n            if (create && create !== 1) {\n              self.if_(self.not(self.computedMember(left, right)), self.lazyAssign(self.computedMember(left, right), '{}'));\n            }\n            expression = self.computedMember(left, right);\n            self.assign(intoId, expression);\n            if (nameId) {\n              nameId.computed = true;\n              nameId.name = right;\n            }\n          } else {\n            if (create && create !== 1) {\n              self.if_(self.isNull(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), '{}'));\n            }\n            expression = self.nonComputedMember(left, ast.property.name);\n            self.assign(intoId, expression);\n            if (nameId) {\n              nameId.computed = false;\n              nameId.name = ast.property.name;\n            }\n          }\n        }, function() {\n          self.assign(intoId, 'undefined');\n        });\n        recursionFn(intoId);\n      }, !!create);\n      break;\n    case AST.CallExpression:\n      intoId = intoId || this.nextId();\n      if (ast.filter) {\n        right = self.filter(ast.callee.name);\n        args = [];\n        forEach(ast.arguments, function(expr) {\n          var argument = self.nextId();\n          self.recurse(expr, argument);\n          args.push(argument);\n        });\n        expression = right + '(' + args.join(',') + ')';\n        self.assign(intoId, expression);\n        recursionFn(intoId);\n      } else {\n        right = self.nextId();\n        left = {};\n        args = [];\n        self.recurse(ast.callee, right, left, function() {\n          self.if_(self.notNull(right), function() {\n            forEach(ast.arguments, function(expr) {\n              self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) {\n                args.push(argument);\n              });\n            });\n            if (left.name) {\n              expression = self.member(left.context, left.name, left.computed) + '(' + args.join(',') + ')';\n            } else {\n              expression = right + '(' + args.join(',') + ')';\n            }\n            self.assign(intoId, expression);\n          }, function() {\n            self.assign(intoId, 'undefined');\n          });\n          recursionFn(intoId);\n        });\n      }\n      break;\n    case AST.AssignmentExpression:\n      right = this.nextId();\n      left = {};\n      this.recurse(ast.left, undefined, left, function() {\n        self.if_(self.notNull(left.context), function() {\n          self.recurse(ast.right, right);\n          expression = self.member(left.context, left.name, left.computed) + ast.operator + right;\n          self.assign(intoId, expression);\n          recursionFn(intoId || expression);\n        });\n      }, 1);\n      break;\n    case AST.ArrayExpression:\n      args = [];\n      forEach(ast.elements, function(expr) {\n        self.recurse(expr, ast.constant ? undefined : self.nextId(), undefined, function(argument) {\n          args.push(argument);\n        });\n      });\n      expression = '[' + args.join(',') + ']';\n      this.assign(intoId, expression);\n      recursionFn(intoId || expression);\n      break;\n    case AST.ObjectExpression:\n      args = [];\n      computed = false;\n      forEach(ast.properties, function(property) {\n        if (property.computed) {\n          computed = true;\n        }\n      });\n      if (computed) {\n        intoId = intoId || this.nextId();\n        this.assign(intoId, '{}');\n        forEach(ast.properties, function(property) {\n          if (property.computed) {\n            left = self.nextId();\n            self.recurse(property.key, left);\n          } else {\n            left = property.key.type === AST.Identifier ?\n                       property.key.name :\n                       ('' + property.key.value);\n          }\n          right = self.nextId();\n          self.recurse(property.value, right);\n          self.assign(self.member(intoId, left, property.computed), right);\n        });\n      } else {\n        forEach(ast.properties, function(property) {\n          self.recurse(property.value, ast.constant ? undefined : self.nextId(), undefined, function(expr) {\n            args.push(self.escape(\n                property.key.type === AST.Identifier ? property.key.name :\n                  ('' + property.key.value)) +\n                ':' + expr);\n          });\n        });\n        expression = '{' + args.join(',') + '}';\n        this.assign(intoId, expression);\n      }\n      recursionFn(intoId || expression);\n      break;\n    case AST.ThisExpression:\n      this.assign(intoId, 's');\n      recursionFn(intoId || 's');\n      break;\n    case AST.LocalsExpression:\n      this.assign(intoId, 'l');\n      recursionFn(intoId || 'l');\n      break;\n    case AST.NGValueParameter:\n      this.assign(intoId, 'v');\n      recursionFn(intoId || 'v');\n      break;\n    }\n  },\n\n  getHasOwnProperty: function(element, property) {\n    var key = element + '.' + property;\n    var own = this.current().own;\n    if (!own.hasOwnProperty(key)) {\n      own[key] = this.nextId(false, element + '&&(' + this.escape(property) + ' in ' + element + ')');\n    }\n    return own[key];\n  },\n\n  assign: function(id, value) {\n    if (!id) return;\n    this.current().body.push(id, '=', value, ';');\n    return id;\n  },\n\n  filter: function(filterName) {\n    if (!this.state.filters.hasOwnProperty(filterName)) {\n      this.state.filters[filterName] = this.nextId(true);\n    }\n    return this.state.filters[filterName];\n  },\n\n  ifDefined: function(id, defaultValue) {\n    return 'ifDefined(' + id + ',' + this.escape(defaultValue) + ')';\n  },\n\n  plus: function(left, right) {\n    return 'plus(' + left + ',' + right + ')';\n  },\n\n  return_: function(id) {\n    this.current().body.push('return ', id, ';');\n  },\n\n  if_: function(test, alternate, consequent) {\n    if (test === true) {\n      alternate();\n    } else {\n      var body = this.current().body;\n      body.push('if(', test, '){');\n      alternate();\n      body.push('}');\n      if (consequent) {\n        body.push('else{');\n        consequent();\n        body.push('}');\n      }\n    }\n  },\n\n  not: function(expression) {\n    return '!(' + expression + ')';\n  },\n\n  isNull: function(expression) {\n    return expression + '==null';\n  },\n\n  notNull: function(expression) {\n    return expression + '!=null';\n  },\n\n  nonComputedMember: function(left, right) {\n    var SAFE_IDENTIFIER = /^[$_a-zA-Z][$_a-zA-Z0-9]*$/;\n    var UNSAFE_CHARACTERS = /[^$_a-zA-Z0-9]/g;\n    if (SAFE_IDENTIFIER.test(right)) {\n      return left + '.' + right;\n    } else {\n      return left  + '[\"' + right.replace(UNSAFE_CHARACTERS, this.stringEscapeFn) + '\"]';\n    }\n  },\n\n  computedMember: function(left, right) {\n    return left + '[' + right + ']';\n  },\n\n  member: function(left, right, computed) {\n    if (computed) return this.computedMember(left, right);\n    return this.nonComputedMember(left, right);\n  },\n\n  getStringValue: function(item) {\n    this.assign(item, 'getStringValue(' + item + ')');\n  },\n\n  lazyRecurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {\n    var self = this;\n    return function() {\n      self.recurse(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck);\n    };\n  },\n\n  lazyAssign: function(id, value) {\n    var self = this;\n    return function() {\n      self.assign(id, value);\n    };\n  },\n\n  stringEscapeRegex: /[^ a-zA-Z0-9]/g,\n\n  stringEscapeFn: function(c) {\n    return '\\\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4);\n  },\n\n  escape: function(value) {\n    if (isString(value)) return '\\'' + value.replace(this.stringEscapeRegex, this.stringEscapeFn) + '\\'';\n    if (isNumber(value)) return value.toString();\n    if (value === true) return 'true';\n    if (value === false) return 'false';\n    if (value === null) return 'null';\n    if (typeof value === 'undefined') return 'undefined';\n\n    throw $parseMinErr('esc', 'IMPOSSIBLE');\n  },\n\n  nextId: function(skip, init) {\n    var id = 'v' + (this.state.nextId++);\n    if (!skip) {\n      this.current().vars.push(id + (init ? '=' + init : ''));\n    }\n    return id;\n  },\n\n  current: function() {\n    return this.state[this.state.computing];\n  }\n};\n\n\nfunction ASTInterpreter(astBuilder, $filter) {\n  this.astBuilder = astBuilder;\n  this.$filter = $filter;\n}\n\nASTInterpreter.prototype = {\n  compile: function(expression) {\n    var self = this;\n    var ast = this.astBuilder.ast(expression);\n    findConstantAndWatchExpressions(ast, self.$filter);\n    var assignable;\n    var assign;\n    if ((assignable = assignableAST(ast))) {\n      assign = this.recurse(assignable);\n    }\n    var toWatch = getInputs(ast.body);\n    var inputs;\n    if (toWatch) {\n      inputs = [];\n      forEach(toWatch, function(watch, key) {\n        var input = self.recurse(watch);\n        watch.input = input;\n        inputs.push(input);\n        watch.watchId = key;\n      });\n    }\n    var expressions = [];\n    forEach(ast.body, function(expression) {\n      expressions.push(self.recurse(expression.expression));\n    });\n    var fn = ast.body.length === 0 ? noop :\n             ast.body.length === 1 ? expressions[0] :\n             function(scope, locals) {\n               var lastValue;\n               forEach(expressions, function(exp) {\n                 lastValue = exp(scope, locals);\n               });\n               return lastValue;\n             };\n    if (assign) {\n      fn.assign = function(scope, value, locals) {\n        return assign(scope, locals, value);\n      };\n    }\n    if (inputs) {\n      fn.inputs = inputs;\n    }\n    fn.literal = isLiteral(ast);\n    fn.constant = isConstant(ast);\n    return fn;\n  },\n\n  recurse: function(ast, context, create) {\n    var left, right, self = this, args;\n    if (ast.input) {\n      return this.inputs(ast.input, ast.watchId);\n    }\n    switch (ast.type) {\n    case AST.Literal:\n      return this.value(ast.value, context);\n    case AST.UnaryExpression:\n      right = this.recurse(ast.argument);\n      return this['unary' + ast.operator](right, context);\n    case AST.BinaryExpression:\n      left = this.recurse(ast.left);\n      right = this.recurse(ast.right);\n      return this['binary' + ast.operator](left, right, context);\n    case AST.LogicalExpression:\n      left = this.recurse(ast.left);\n      right = this.recurse(ast.right);\n      return this['binary' + ast.operator](left, right, context);\n    case AST.ConditionalExpression:\n      return this['ternary?:'](\n        this.recurse(ast.test),\n        this.recurse(ast.alternate),\n        this.recurse(ast.consequent),\n        context\n      );\n    case AST.Identifier:\n      return self.identifier(ast.name, context, create);\n    case AST.MemberExpression:\n      left = this.recurse(ast.object, false, !!create);\n      if (!ast.computed) {\n        right = ast.property.name;\n      }\n      if (ast.computed) right = this.recurse(ast.property);\n      return ast.computed ?\n        this.computedMember(left, right, context, create) :\n        this.nonComputedMember(left, right, context, create);\n    case AST.CallExpression:\n      args = [];\n      forEach(ast.arguments, function(expr) {\n        args.push(self.recurse(expr));\n      });\n      if (ast.filter) right = this.$filter(ast.callee.name);\n      if (!ast.filter) right = this.recurse(ast.callee, true);\n      return ast.filter ?\n        function(scope, locals, assign, inputs) {\n          var values = [];\n          for (var i = 0; i < args.length; ++i) {\n            values.push(args[i](scope, locals, assign, inputs));\n          }\n          var value = right.apply(undefined, values, inputs);\n          return context ? {context: undefined, name: undefined, value: value} : value;\n        } :\n        function(scope, locals, assign, inputs) {\n          var rhs = right(scope, locals, assign, inputs);\n          var value;\n          if (rhs.value != null) {\n            var values = [];\n            for (var i = 0; i < args.length; ++i) {\n              values.push(args[i](scope, locals, assign, inputs));\n            }\n            value = rhs.value.apply(rhs.context, values);\n          }\n          return context ? {value: value} : value;\n        };\n    case AST.AssignmentExpression:\n      left = this.recurse(ast.left, true, 1);\n      right = this.recurse(ast.right);\n      return function(scope, locals, assign, inputs) {\n        var lhs = left(scope, locals, assign, inputs);\n        var rhs = right(scope, locals, assign, inputs);\n        lhs.context[lhs.name] = rhs;\n        return context ? {value: rhs} : rhs;\n      };\n    case AST.ArrayExpression:\n      args = [];\n      forEach(ast.elements, function(expr) {\n        args.push(self.recurse(expr));\n      });\n      return function(scope, locals, assign, inputs) {\n        var value = [];\n        for (var i = 0; i < args.length; ++i) {\n          value.push(args[i](scope, locals, assign, inputs));\n        }\n        return context ? {value: value} : value;\n      };\n    case AST.ObjectExpression:\n      args = [];\n      forEach(ast.properties, function(property) {\n        if (property.computed) {\n          args.push({key: self.recurse(property.key),\n                     computed: true,\n                     value: self.recurse(property.value)\n          });\n        } else {\n          args.push({key: property.key.type === AST.Identifier ?\n                          property.key.name :\n                          ('' + property.key.value),\n                     computed: false,\n                     value: self.recurse(property.value)\n          });\n        }\n      });\n      return function(scope, locals, assign, inputs) {\n        var value = {};\n        for (var i = 0; i < args.length; ++i) {\n          if (args[i].computed) {\n            value[args[i].key(scope, locals, assign, inputs)] = args[i].value(scope, locals, assign, inputs);\n          } else {\n            value[args[i].key] = args[i].value(scope, locals, assign, inputs);\n          }\n        }\n        return context ? {value: value} : value;\n      };\n    case AST.ThisExpression:\n      return function(scope) {\n        return context ? {value: scope} : scope;\n      };\n    case AST.LocalsExpression:\n      return function(scope, locals) {\n        return context ? {value: locals} : locals;\n      };\n    case AST.NGValueParameter:\n      return function(scope, locals, assign) {\n        return context ? {value: assign} : assign;\n      };\n    }\n  },\n\n  'unary+': function(argument, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = argument(scope, locals, assign, inputs);\n      if (isDefined(arg)) {\n        arg = +arg;\n      } else {\n        arg = 0;\n      }\n      return context ? {value: arg} : arg;\n    };\n  },\n  'unary-': function(argument, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = argument(scope, locals, assign, inputs);\n      if (isDefined(arg)) {\n        arg = -arg;\n      } else {\n        arg = -0;\n      }\n      return context ? {value: arg} : arg;\n    };\n  },\n  'unary!': function(argument, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = !argument(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary+': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var lhs = left(scope, locals, assign, inputs);\n      var rhs = right(scope, locals, assign, inputs);\n      var arg = plusFn(lhs, rhs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary-': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var lhs = left(scope, locals, assign, inputs);\n      var rhs = right(scope, locals, assign, inputs);\n      var arg = (isDefined(lhs) ? lhs : 0) - (isDefined(rhs) ? rhs : 0);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary*': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) * right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary/': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) / right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary%': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) % right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary===': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) === right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary!==': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) !== right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary==': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      // eslint-disable-next-line eqeqeq\n      var arg = left(scope, locals, assign, inputs) == right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary!=': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      // eslint-disable-next-line eqeqeq\n      var arg = left(scope, locals, assign, inputs) != right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary<': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) < right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary>': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) > right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary<=': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) <= right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary>=': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) >= right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary&&': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) && right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'binary||': function(left, right, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = left(scope, locals, assign, inputs) || right(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  'ternary?:': function(test, alternate, consequent, context) {\n    return function(scope, locals, assign, inputs) {\n      var arg = test(scope, locals, assign, inputs) ? alternate(scope, locals, assign, inputs) : consequent(scope, locals, assign, inputs);\n      return context ? {value: arg} : arg;\n    };\n  },\n  value: function(value, context) {\n    return function() { return context ? {context: undefined, name: undefined, value: value} : value; };\n  },\n  identifier: function(name, context, create) {\n    return function(scope, locals, assign, inputs) {\n      var base = locals && (name in locals) ? locals : scope;\n      if (create && create !== 1 && base && base[name] == null) {\n        base[name] = {};\n      }\n      var value = base ? base[name] : undefined;\n      if (context) {\n        return {context: base, name: name, value: value};\n      } else {\n        return value;\n      }\n    };\n  },\n  computedMember: function(left, right, context, create) {\n    return function(scope, locals, assign, inputs) {\n      var lhs = left(scope, locals, assign, inputs);\n      var rhs;\n      var value;\n      if (lhs != null) {\n        rhs = right(scope, locals, assign, inputs);\n        rhs = getStringValue(rhs);\n        if (create && create !== 1) {\n          if (lhs && !(lhs[rhs])) {\n            lhs[rhs] = {};\n          }\n        }\n        value = lhs[rhs];\n      }\n      if (context) {\n        return {context: lhs, name: rhs, value: value};\n      } else {\n        return value;\n      }\n    };\n  },\n  nonComputedMember: function(left, right, context, create) {\n    return function(scope, locals, assign, inputs) {\n      var lhs = left(scope, locals, assign, inputs);\n      if (create && create !== 1) {\n        if (lhs && lhs[right] == null) {\n          lhs[right] = {};\n        }\n      }\n      var value = lhs != null ? lhs[right] : undefined;\n      if (context) {\n        return {context: lhs, name: right, value: value};\n      } else {\n        return value;\n      }\n    };\n  },\n  inputs: function(input, watchId) {\n    return function(scope, value, locals, inputs) {\n      if (inputs) return inputs[watchId];\n      return input(scope, value, locals);\n    };\n  }\n};\n\n/**\n * @constructor\n */\nvar Parser = function Parser(lexer, $filter, options) {\n  this.lexer = lexer;\n  this.$filter = $filter;\n  this.options = options;\n  this.ast = new AST(lexer, options);\n  this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) :\n                                   new ASTCompiler(this.ast, $filter);\n};\n\nParser.prototype = {\n  constructor: Parser,\n\n  parse: function(text) {\n    return this.astCompiler.compile(text);\n  }\n};\n\nfunction getValueOf(value) {\n  return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value);\n}\n\n///////////////////////////////////\n\n/**\n * @ngdoc service\n * @name $parse\n * @kind function\n *\n * @description\n *\n * Converts Angular {@link guide/expression expression} into a function.\n *\n * ```js\n *   var getter = $parse('user.name');\n *   var setter = getter.assign;\n *   var context = {user:{name:'angular'}};\n *   var locals = {user:{name:'local'}};\n *\n *   expect(getter(context)).toEqual('angular');\n *   setter(context, 'newValue');\n *   expect(context.user.name).toEqual('newValue');\n *   expect(getter(context, locals)).toEqual('local');\n * ```\n *\n *\n * @param {string} expression String expression to compile.\n * @returns {function(context, locals)} a function which represents the compiled expression:\n *\n *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n *      are evaluated against (typically a scope object).\n *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n *      `context`.\n *\n *    The returned function also has the following properties:\n *      * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript\n *        literal.\n *      * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript\n *        constant literals.\n *      * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be\n *        set to a function to change its value on the given context.\n *\n */\n\n\n/**\n * @ngdoc provider\n * @name $parseProvider\n * @this\n *\n * @description\n * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse}\n *  service.\n */\nfunction $ParseProvider() {\n  var cache = createMap();\n  var literals = {\n    'true': true,\n    'false': false,\n    'null': null,\n    'undefined': undefined\n  };\n  var identStart, identContinue;\n\n  /**\n   * @ngdoc method\n   * @name $parseProvider#addLiteral\n   * @description\n   *\n   * Configure $parse service to add literal values that will be present as literal at expressions.\n   *\n   * @param {string} literalName Token for the literal value. The literal name value must be a valid literal name.\n   * @param {*} literalValue Value for this literal. All literal values must be primitives or `undefined`.\n   *\n   **/\n  this.addLiteral = function(literalName, literalValue) {\n    literals[literalName] = literalValue;\n  };\n\n /**\n  * @ngdoc method\n  * @name $parseProvider#setIdentifierFns\n  *\n  * @description\n  *\n  * Allows defining the set of characters that are allowed in Angular expressions. The function\n  * `identifierStart` will get called to know if a given character is a valid character to be the\n  * first character for an identifier. The function `identifierContinue` will get called to know if\n  * a given character is a valid character to be a follow-up identifier character. The functions\n  * `identifierStart` and `identifierContinue` will receive as arguments the single character to be\n  * identifier and the character code point. These arguments will be `string` and `numeric`. Keep in\n  * mind that the `string` parameter can be two characters long depending on the character\n  * representation. It is expected for the function to return `true` or `false`, whether that\n  * character is allowed or not.\n  *\n  * Since this function will be called extensively, keep the implementation of these functions fast,\n  * as the performance of these functions have a direct impact on the expressions parsing speed.\n  *\n  * @param {function=} identifierStart The function that will decide whether the given character is\n  *   a valid identifier start character.\n  * @param {function=} identifierContinue The function that will decide whether the given character is\n  *   a valid identifier continue character.\n  */\n  this.setIdentifierFns = function(identifierStart, identifierContinue) {\n    identStart = identifierStart;\n    identContinue = identifierContinue;\n    return this;\n  };\n\n  this.$get = ['$filter', function($filter) {\n    var noUnsafeEval = csp().noUnsafeEval;\n    var $parseOptions = {\n          csp: noUnsafeEval,\n          literals: copy(literals),\n          isIdentifierStart: isFunction(identStart) && identStart,\n          isIdentifierContinue: isFunction(identContinue) && identContinue\n        };\n    return $parse;\n\n    function $parse(exp, interceptorFn) {\n      var parsedExpression, oneTime, cacheKey;\n\n      switch (typeof exp) {\n        case 'string':\n          exp = exp.trim();\n          cacheKey = exp;\n\n          parsedExpression = cache[cacheKey];\n\n          if (!parsedExpression) {\n            if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {\n              oneTime = true;\n              exp = exp.substring(2);\n            }\n            var lexer = new Lexer($parseOptions);\n            var parser = new Parser(lexer, $filter, $parseOptions);\n            parsedExpression = parser.parse(exp);\n            if (parsedExpression.constant) {\n              parsedExpression.$$watchDelegate = constantWatchDelegate;\n            } else if (oneTime) {\n              parsedExpression.$$watchDelegate = parsedExpression.literal ?\n                  oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;\n            } else if (parsedExpression.inputs) {\n              parsedExpression.$$watchDelegate = inputsWatchDelegate;\n            }\n            cache[cacheKey] = parsedExpression;\n          }\n          return addInterceptor(parsedExpression, interceptorFn);\n\n        case 'function':\n          return addInterceptor(exp, interceptorFn);\n\n        default:\n          return addInterceptor(noop, interceptorFn);\n      }\n    }\n\n    function expressionInputDirtyCheck(newValue, oldValueOfValue, compareObjectIdentity) {\n\n      if (newValue == null || oldValueOfValue == null) { // null/undefined\n        return newValue === oldValueOfValue;\n      }\n\n      if (typeof newValue === 'object' && !compareObjectIdentity) {\n\n        // attempt to convert the value to a primitive type\n        // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can\n        //             be cheaply dirty-checked\n        newValue = getValueOf(newValue);\n\n        if (typeof newValue === 'object') {\n          // objects/arrays are not supported - deep-watching them would be too expensive\n          return false;\n        }\n\n        // fall-through to the primitive equality check\n      }\n\n      //Primitive or NaN\n      // eslint-disable-next-line no-self-compare\n      return newValue === oldValueOfValue || (newValue !== newValue && oldValueOfValue !== oldValueOfValue);\n    }\n\n    function inputsWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {\n      var inputExpressions = parsedExpression.inputs;\n      var lastResult;\n\n      if (inputExpressions.length === 1) {\n        var oldInputValueOf = expressionInputDirtyCheck; // init to something unique so that equals check fails\n        inputExpressions = inputExpressions[0];\n        return scope.$watch(function expressionInputWatch(scope) {\n          var newInputValue = inputExpressions(scope);\n          if (!expressionInputDirtyCheck(newInputValue, oldInputValueOf, parsedExpression.literal)) {\n            lastResult = parsedExpression(scope, undefined, undefined, [newInputValue]);\n            oldInputValueOf = newInputValue && getValueOf(newInputValue);\n          }\n          return lastResult;\n        }, listener, objectEquality, prettyPrintExpression);\n      }\n\n      var oldInputValueOfValues = [];\n      var oldInputValues = [];\n      for (var i = 0, ii = inputExpressions.length; i < ii; i++) {\n        oldInputValueOfValues[i] = expressionInputDirtyCheck; // init to something unique so that equals check fails\n        oldInputValues[i] = null;\n      }\n\n      return scope.$watch(function expressionInputsWatch(scope) {\n        var changed = false;\n\n        for (var i = 0, ii = inputExpressions.length; i < ii; i++) {\n          var newInputValue = inputExpressions[i](scope);\n          if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i], parsedExpression.literal))) {\n            oldInputValues[i] = newInputValue;\n            oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue);\n          }\n        }\n\n        if (changed) {\n          lastResult = parsedExpression(scope, undefined, undefined, oldInputValues);\n        }\n\n        return lastResult;\n      }, listener, objectEquality, prettyPrintExpression);\n    }\n\n    function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {\n      var unwatch, lastValue;\n      if (parsedExpression.inputs) {\n        unwatch = inputsWatchDelegate(scope, oneTimeListener, objectEquality, parsedExpression, prettyPrintExpression);\n      } else {\n        unwatch = scope.$watch(oneTimeWatch, oneTimeListener, objectEquality);\n      }\n      return unwatch;\n\n      function oneTimeWatch(scope) {\n        return parsedExpression(scope);\n      }\n      function oneTimeListener(value, old, scope) {\n        lastValue = value;\n        if (isFunction(listener)) {\n          listener(value, old, scope);\n        }\n        if (isDefined(value)) {\n          scope.$$postDigest(function() {\n            if (isDefined(lastValue)) {\n              unwatch();\n            }\n          });\n        }\n      }\n    }\n\n    function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) {\n      var unwatch, lastValue;\n      unwatch = scope.$watch(function oneTimeWatch(scope) {\n        return parsedExpression(scope);\n      }, function oneTimeListener(value, old, scope) {\n        lastValue = value;\n        if (isFunction(listener)) {\n          listener(value, old, scope);\n        }\n        if (isAllDefined(value)) {\n          scope.$$postDigest(function() {\n            if (isAllDefined(lastValue)) unwatch();\n          });\n        }\n      }, objectEquality);\n\n      return unwatch;\n\n      function isAllDefined(value) {\n        var allDefined = true;\n        forEach(value, function(val) {\n          if (!isDefined(val)) allDefined = false;\n        });\n        return allDefined;\n      }\n    }\n\n    function constantWatchDelegate(scope, listener, objectEquality, parsedExpression) {\n      var unwatch = scope.$watch(function constantWatch(scope) {\n        unwatch();\n        return parsedExpression(scope);\n      }, listener, objectEquality);\n      return unwatch;\n    }\n\n    function addInterceptor(parsedExpression, interceptorFn) {\n      if (!interceptorFn) return parsedExpression;\n      var watchDelegate = parsedExpression.$$watchDelegate;\n      var useInputs = false;\n\n      var regularWatch =\n          watchDelegate !== oneTimeLiteralWatchDelegate &&\n          watchDelegate !== oneTimeWatchDelegate;\n\n      var fn = regularWatch ? function regularInterceptedExpression(scope, locals, assign, inputs) {\n        var value = useInputs && inputs ? inputs[0] : parsedExpression(scope, locals, assign, inputs);\n        return interceptorFn(value, scope, locals);\n      } : function oneTimeInterceptedExpression(scope, locals, assign, inputs) {\n        var value = parsedExpression(scope, locals, assign, inputs);\n        var result = interceptorFn(value, scope, locals);\n        // we only return the interceptor's result if the\n        // initial value is defined (for bind-once)\n        return isDefined(value) ? result : value;\n      };\n\n      // Propagate $$watchDelegates other then inputsWatchDelegate\n      useInputs = !parsedExpression.inputs;\n      if (parsedExpression.$$watchDelegate &&\n          parsedExpression.$$watchDelegate !== inputsWatchDelegate) {\n        fn.$$watchDelegate = parsedExpression.$$watchDelegate;\n        fn.inputs = parsedExpression.inputs;\n      } else if (!interceptorFn.$stateful) {\n        // If there is an interceptor, but no watchDelegate then treat the interceptor like\n        // we treat filters - it is assumed to be a pure function unless flagged with $stateful\n        fn.$$watchDelegate = inputsWatchDelegate;\n        fn.inputs = parsedExpression.inputs ? parsedExpression.inputs : [parsedExpression];\n      }\n\n      return fn;\n    }\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $q\n * @requires $rootScope\n *\n * @description\n * A service that helps you run functions asynchronously, and use their return values (or exceptions)\n * when they are done processing.\n *\n * This is a [Promises/A+](https://promisesaplus.com/)-compliant implementation of promises/deferred\n * objects inspired by [Kris Kowal's Q](https://github.com/kriskowal/q).\n *\n * $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred\n * implementations, and the other which resembles ES6 (ES2015) promises to some degree.\n *\n * # $q constructor\n *\n * The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver`\n * function as the first argument. This is similar to the native Promise implementation from ES6,\n * see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).\n *\n * While the constructor-style use is supported, not all of the supporting methods from ES6 promises are\n * available yet.\n *\n * It can be used like so:\n *\n * ```js\n *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`\n *   // are available in the current lexical scope (they could have been injected or passed in).\n *\n *   function asyncGreet(name) {\n *     // perform some asynchronous operation, resolve or reject the promise when appropriate.\n *     return $q(function(resolve, reject) {\n *       setTimeout(function() {\n *         if (okToGreet(name)) {\n *           resolve('Hello, ' + name + '!');\n *         } else {\n *           reject('Greeting ' + name + ' is not allowed.');\n *         }\n *       }, 1000);\n *     });\n *   }\n *\n *   var promise = asyncGreet('Robin Hood');\n *   promise.then(function(greeting) {\n *     alert('Success: ' + greeting);\n *   }, function(reason) {\n *     alert('Failed: ' + reason);\n *   });\n * ```\n *\n * Note: progress/notify callbacks are not currently supported via the ES6-style interface.\n *\n * Note: unlike ES6 behavior, an exception thrown in the constructor function will NOT implicitly reject the promise.\n *\n * However, the more traditional CommonJS-style usage is still available, and documented below.\n *\n * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an\n * interface for interacting with an object that represents the result of an action that is\n * performed asynchronously, and may or may not be finished at any given point in time.\n *\n * From the perspective of dealing with error handling, deferred and promise APIs are to\n * asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.\n *\n * ```js\n *   // for the purpose of this example let's assume that variables `$q` and `okToGreet`\n *   // are available in the current lexical scope (they could have been injected or passed in).\n *\n *   function asyncGreet(name) {\n *     var deferred = $q.defer();\n *\n *     setTimeout(function() {\n *       deferred.notify('About to greet ' + name + '.');\n *\n *       if (okToGreet(name)) {\n *         deferred.resolve('Hello, ' + name + '!');\n *       } else {\n *         deferred.reject('Greeting ' + name + ' is not allowed.');\n *       }\n *     }, 1000);\n *\n *     return deferred.promise;\n *   }\n *\n *   var promise = asyncGreet('Robin Hood');\n *   promise.then(function(greeting) {\n *     alert('Success: ' + greeting);\n *   }, function(reason) {\n *     alert('Failed: ' + reason);\n *   }, function(update) {\n *     alert('Got notification: ' + update);\n *   });\n * ```\n *\n * At first it might not be obvious why this extra complexity is worth the trouble. The payoff\n * comes in the way of guarantees that promise and deferred APIs make, see\n * https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md.\n *\n * Additionally the promise api allows for composition that is very hard to do with the\n * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach.\n * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the\n * section on serial or parallel joining of promises.\n *\n * # The Deferred API\n *\n * A new instance of deferred is constructed by calling `$q.defer()`.\n *\n * The purpose of the deferred object is to expose the associated Promise instance as well as APIs\n * that can be used for signaling the successful or unsuccessful completion, as well as the status\n * of the task.\n *\n * **Methods**\n *\n * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection\n *   constructed via `$q.reject`, the promise will be rejected instead.\n * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to\n *   resolving it with a rejection constructed via `$q.reject`.\n * - `notify(value)` - provides updates on the status of the promise's execution. This may be called\n *   multiple times before the promise is either resolved or rejected.\n *\n * **Properties**\n *\n * - promise – `{Promise}` – promise object associated with this deferred.\n *\n *\n * # The Promise API\n *\n * A new promise instance is created when a deferred instance is created and can be retrieved by\n * calling `deferred.promise`.\n *\n * The purpose of the promise object is to allow for interested parties to get access to the result\n * of the deferred task when it completes.\n *\n * **Methods**\n *\n * - `then(successCallback, [errorCallback], [notifyCallback])` – regardless of when the promise was or\n *   will be resolved or rejected, `then` calls one of the success or error callbacks asynchronously\n *   as soon as the result is available. The callbacks are called with a single argument: the result\n *   or rejection reason. Additionally, the notify callback may be called zero or more times to\n *   provide a progress indication, before the promise is resolved or rejected.\n *\n *   This method *returns a new promise* which is resolved or rejected via the return value of the\n *   `successCallback`, `errorCallback` (unless that value is a promise, in which case it is resolved\n *   with the value which is resolved in that promise using\n *   [promise chaining](http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promises-queues)).\n *   It also notifies via the return value of the `notifyCallback` method. The promise cannot be\n *   resolved or rejected from the notifyCallback method. The errorCallback and notifyCallback\n *   arguments are optional.\n *\n * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`\n *\n * - `finally(callback, notifyCallback)` – allows you to observe either the fulfillment or rejection of a promise,\n *   but to do so without modifying the final value. This is useful to release resources or do some\n *   clean-up that needs to be done whether the promise was rejected or resolved. See the [full\n *   specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefinallycallback) for\n *   more information.\n *\n * # Chaining promises\n *\n * Because calling the `then` method of a promise returns a new derived promise, it is easily\n * possible to create a chain of promises:\n *\n * ```js\n *   promiseB = promiseA.then(function(result) {\n *     return result + 1;\n *   });\n *\n *   // promiseB will be resolved immediately after promiseA is resolved and its value\n *   // will be the result of promiseA incremented by 1\n * ```\n *\n * It is possible to create chains of any length and since a promise can be resolved with another\n * promise (which will defer its resolution further), it is possible to pause/defer resolution of\n * the promises at any point in the chain. This makes it possible to implement powerful APIs like\n * $http's response interceptors.\n *\n *\n * # Differences between Kris Kowal's Q and $q\n *\n *  There are two main differences:\n *\n * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation\n *   mechanism in angular, which means faster propagation of resolution or rejection into your\n *   models and avoiding unnecessary browser repaints, which would result in flickering UI.\n * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains\n *   all the important functionality needed for common async tasks.\n *\n * # Testing\n *\n *  ```js\n *    it('should simulate promise', inject(function($q, $rootScope) {\n *      var deferred = $q.defer();\n *      var promise = deferred.promise;\n *      var resolvedValue;\n *\n *      promise.then(function(value) { resolvedValue = value; });\n *      expect(resolvedValue).toBeUndefined();\n *\n *      // Simulate resolving of promise\n *      deferred.resolve(123);\n *      // Note that the 'then' function does not get called synchronously.\n *      // This is because we want the promise API to always be async, whether or not\n *      // it got called synchronously or asynchronously.\n *      expect(resolvedValue).toBeUndefined();\n *\n *      // Propagate promise resolution to 'then' functions using $apply().\n *      $rootScope.$apply();\n *      expect(resolvedValue).toEqual(123);\n *    }));\n *  ```\n *\n * @param {function(function, function)} resolver Function which is responsible for resolving or\n *   rejecting the newly created promise. The first parameter is a function which resolves the\n *   promise, the second parameter is a function which rejects the promise.\n *\n * @returns {Promise} The newly created promise.\n */\n/**\n * @ngdoc provider\n * @name $qProvider\n * @this\n *\n * @description\n */\nfunction $QProvider() {\n  var errorOnUnhandledRejections = true;\n  this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) {\n    return qFactory(function(callback) {\n      $rootScope.$evalAsync(callback);\n    }, $exceptionHandler, errorOnUnhandledRejections);\n  }];\n\n  /**\n   * @ngdoc method\n   * @name $qProvider#errorOnUnhandledRejections\n   * @kind function\n   *\n   * @description\n   * Retrieves or overrides whether to generate an error when a rejected promise is not handled.\n   * This feature is enabled by default.\n   *\n   * @param {boolean=} value Whether to generate an error when a rejected promise is not handled.\n   * @returns {boolean|ng.$qProvider} Current value when called without a new value or self for\n   *    chaining otherwise.\n   */\n  this.errorOnUnhandledRejections = function(value) {\n    if (isDefined(value)) {\n      errorOnUnhandledRejections = value;\n      return this;\n    } else {\n      return errorOnUnhandledRejections;\n    }\n  };\n}\n\n/** @this */\nfunction $$QProvider() {\n  var errorOnUnhandledRejections = true;\n  this.$get = ['$browser', '$exceptionHandler', function($browser, $exceptionHandler) {\n    return qFactory(function(callback) {\n      $browser.defer(callback);\n    }, $exceptionHandler, errorOnUnhandledRejections);\n  }];\n\n  this.errorOnUnhandledRejections = function(value) {\n    if (isDefined(value)) {\n      errorOnUnhandledRejections = value;\n      return this;\n    } else {\n      return errorOnUnhandledRejections;\n    }\n  };\n}\n\n/**\n * Constructs a promise manager.\n *\n * @param {function(function)} nextTick Function for executing functions in the next turn.\n * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for\n *     debugging purposes.\n @ param {=boolean} errorOnUnhandledRejections Whether an error should be generated on unhandled\n *     promises rejections.\n * @returns {object} Promise manager.\n */\nfunction qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {\n  var $qMinErr = minErr('$q', TypeError);\n  var queueSize = 0;\n  var checkQueue = [];\n\n  /**\n   * @ngdoc method\n   * @name ng.$q#defer\n   * @kind function\n   *\n   * @description\n   * Creates a `Deferred` object which represents a task which will finish in the future.\n   *\n   * @returns {Deferred} Returns a new instance of deferred.\n   */\n  function defer() {\n    return new Deferred();\n  }\n\n  function Deferred() {\n    var promise = this.promise = new Promise();\n    //Non prototype methods necessary to support unbound execution :/\n    this.resolve = function(val) { resolvePromise(promise, val); };\n    this.reject = function(reason) { rejectPromise(promise, reason); };\n    this.notify = function(progress) { notifyPromise(promise, progress); };\n  }\n\n\n  function Promise() {\n    this.$$state = { status: 0 };\n  }\n\n  extend(Promise.prototype, {\n    then: function(onFulfilled, onRejected, progressBack) {\n      if (isUndefined(onFulfilled) && isUndefined(onRejected) && isUndefined(progressBack)) {\n        return this;\n      }\n      var result = new Promise();\n\n      this.$$state.pending = this.$$state.pending || [];\n      this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);\n      if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);\n\n      return result;\n    },\n\n    'catch': function(callback) {\n      return this.then(null, callback);\n    },\n\n    'finally': function(callback, progressBack) {\n      return this.then(function(value) {\n        return handleCallback(value, resolve, callback);\n      }, function(error) {\n        return handleCallback(error, reject, callback);\n      }, progressBack);\n    }\n  });\n\n  function processQueue(state) {\n    var fn, promise, pending;\n\n    pending = state.pending;\n    state.processScheduled = false;\n    state.pending = undefined;\n    try {\n      for (var i = 0, ii = pending.length; i < ii; ++i) {\n        state.pur = true;\n        promise = pending[i][0];\n        fn = pending[i][state.status];\n        try {\n          if (isFunction(fn)) {\n            resolvePromise(promise, fn(state.value));\n          } else if (state.status === 1) {\n            resolvePromise(promise, state.value);\n          } else {\n            rejectPromise(promise, state.value);\n          }\n        } catch (e) {\n          rejectPromise(promise, e);\n        }\n      }\n    } finally {\n      --queueSize;\n      if (errorOnUnhandledRejections && queueSize === 0) {\n        nextTick(processChecks);\n      }\n    }\n  }\n\n  function processChecks() {\n    // eslint-disable-next-line no-unmodified-loop-condition\n    while (!queueSize && checkQueue.length) {\n      var toCheck = checkQueue.shift();\n      if (!toCheck.pur) {\n        toCheck.pur = true;\n        var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value);\n        if (toCheck.value instanceof Error) {\n          exceptionHandler(toCheck.value, errorMessage);\n        } else {\n          exceptionHandler(errorMessage);\n        }\n      }\n    }\n  }\n\n  function scheduleProcessQueue(state) {\n    if (errorOnUnhandledRejections && !state.pending && state.status === 2 && !state.pur) {\n      if (queueSize === 0 && checkQueue.length === 0) {\n        nextTick(processChecks);\n      }\n      checkQueue.push(state);\n    }\n    if (state.processScheduled || !state.pending) return;\n    state.processScheduled = true;\n    ++queueSize;\n    nextTick(function() { processQueue(state); });\n  }\n\n  function resolvePromise(promise, val) {\n    if (promise.$$state.status) return;\n    if (val === promise) {\n      $$reject(promise, $qMinErr(\n        'qcycle',\n        'Expected promise to be resolved with value other than itself \\'{0}\\'',\n        val));\n    } else {\n      $$resolve(promise, val);\n    }\n\n  }\n\n  function $$resolve(promise, val) {\n    var then;\n    var done = false;\n    try {\n      if (isObject(val) || isFunction(val)) then = val.then;\n      if (isFunction(then)) {\n        promise.$$state.status = -1;\n        then.call(val, doResolve, doReject, doNotify);\n      } else {\n        promise.$$state.value = val;\n        promise.$$state.status = 1;\n        scheduleProcessQueue(promise.$$state);\n      }\n    } catch (e) {\n      doReject(e);\n    }\n\n    function doResolve(val) {\n      if (done) return;\n      done = true;\n      $$resolve(promise, val);\n    }\n    function doReject(val) {\n      if (done) return;\n      done = true;\n      $$reject(promise, val);\n    }\n    function doNotify(progress) {\n      notifyPromise(promise, progress);\n    }\n  }\n\n  function rejectPromise(promise, reason) {\n    if (promise.$$state.status) return;\n    $$reject(promise, reason);\n  }\n\n  function $$reject(promise, reason) {\n    promise.$$state.value = reason;\n    promise.$$state.status = 2;\n    scheduleProcessQueue(promise.$$state);\n  }\n\n  function notifyPromise(promise, progress) {\n    var callbacks = promise.$$state.pending;\n\n    if ((promise.$$state.status <= 0) && callbacks && callbacks.length) {\n      nextTick(function() {\n        var callback, result;\n        for (var i = 0, ii = callbacks.length; i < ii; i++) {\n          result = callbacks[i][0];\n          callback = callbacks[i][3];\n          try {\n            notifyPromise(result, isFunction(callback) ? callback(progress) : progress);\n          } catch (e) {\n            exceptionHandler(e);\n          }\n        }\n      });\n    }\n  }\n\n  /**\n   * @ngdoc method\n   * @name $q#reject\n   * @kind function\n   *\n   * @description\n   * Creates a promise that is resolved as rejected with the specified `reason`. This api should be\n   * used to forward rejection in a chain of promises. If you are dealing with the last promise in\n   * a promise chain, you don't need to worry about it.\n   *\n   * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of\n   * `reject` as the `throw` keyword in JavaScript. This also means that if you \"catch\" an error via\n   * a promise error callback and you want to forward the error to the promise derived from the\n   * current promise, you have to \"rethrow\" the error by returning a rejection constructed via\n   * `reject`.\n   *\n   * ```js\n   *   promiseB = promiseA.then(function(result) {\n   *     // success: do something and resolve promiseB\n   *     //          with the old or a new result\n   *     return result;\n   *   }, function(reason) {\n   *     // error: handle the error if possible and\n   *     //        resolve promiseB with newPromiseOrValue,\n   *     //        otherwise forward the rejection to promiseB\n   *     if (canHandle(reason)) {\n   *      // handle the error and recover\n   *      return newPromiseOrValue;\n   *     }\n   *     return $q.reject(reason);\n   *   });\n   * ```\n   *\n   * @param {*} reason Constant, message, exception or an object representing the rejection reason.\n   * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.\n   */\n  function reject(reason) {\n    var result = new Promise();\n    rejectPromise(result, reason);\n    return result;\n  }\n\n  function handleCallback(value, resolver, callback) {\n    var callbackOutput = null;\n    try {\n      if (isFunction(callback)) callbackOutput = callback();\n    } catch (e) {\n      return reject(e);\n    }\n    if (isPromiseLike(callbackOutput)) {\n      return callbackOutput.then(function() {\n        return resolver(value);\n      }, reject);\n    } else {\n      return resolver(value);\n    }\n  }\n\n  /**\n   * @ngdoc method\n   * @name $q#when\n   * @kind function\n   *\n   * @description\n   * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.\n   * This is useful when you are dealing with an object that might or might not be a promise, or if\n   * the promise comes from a source that can't be trusted.\n   *\n   * @param {*} value Value or a promise\n   * @param {Function=} successCallback\n   * @param {Function=} errorCallback\n   * @param {Function=} progressCallback\n   * @returns {Promise} Returns a promise of the passed value or promise\n   */\n\n\n  function when(value, callback, errback, progressBack) {\n    var result = new Promise();\n    resolvePromise(result, value);\n    return result.then(callback, errback, progressBack);\n  }\n\n  /**\n   * @ngdoc method\n   * @name $q#resolve\n   * @kind function\n   *\n   * @description\n   * Alias of {@link ng.$q#when when} to maintain naming consistency with ES6.\n   *\n   * @param {*} value Value or a promise\n   * @param {Function=} successCallback\n   * @param {Function=} errorCallback\n   * @param {Function=} progressCallback\n   * @returns {Promise} Returns a promise of the passed value or promise\n   */\n  var resolve = when;\n\n  /**\n   * @ngdoc method\n   * @name $q#all\n   * @kind function\n   *\n   * @description\n   * Combines multiple promises into a single promise that is resolved when all of the input\n   * promises are resolved.\n   *\n   * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.\n   * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values,\n   *   each value corresponding to the promise at the same index/key in the `promises` array/hash.\n   *   If any of the promises is resolved with a rejection, this resulting promise will be rejected\n   *   with the same rejection value.\n   */\n\n  function all(promises) {\n    var result = new Promise(),\n        counter = 0,\n        results = isArray(promises) ? [] : {};\n\n    forEach(promises, function(promise, key) {\n      counter++;\n      when(promise).then(function(value) {\n        results[key] = value;\n        if (!(--counter)) resolvePromise(result, results);\n      }, function(reason) {\n        rejectPromise(result, reason);\n      });\n    });\n\n    if (counter === 0) {\n      resolvePromise(result, results);\n    }\n\n    return result;\n  }\n\n  /**\n   * @ngdoc method\n   * @name $q#race\n   * @kind function\n   *\n   * @description\n   * Returns a promise that resolves or rejects as soon as one of those promises\n   * resolves or rejects, with the value or reason from that promise.\n   *\n   * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.\n   * @returns {Promise} a promise that resolves or rejects as soon as one of the `promises`\n   * resolves or rejects, with the value or reason from that promise.\n   */\n\n  function race(promises) {\n    var deferred = defer();\n\n    forEach(promises, function(promise) {\n      when(promise).then(deferred.resolve, deferred.reject);\n    });\n\n    return deferred.promise;\n  }\n\n  function $Q(resolver) {\n    if (!isFunction(resolver)) {\n      throw $qMinErr('norslvr', 'Expected resolverFn, got \\'{0}\\'', resolver);\n    }\n\n    var promise = new Promise();\n\n    function resolveFn(value) {\n      resolvePromise(promise, value);\n    }\n\n    function rejectFn(reason) {\n      rejectPromise(promise, reason);\n    }\n\n    resolver(resolveFn, rejectFn);\n\n    return promise;\n  }\n\n  // Let's make the instanceof operator work for promises, so that\n  // `new $q(fn) instanceof $q` would evaluate to true.\n  $Q.prototype = Promise.prototype;\n\n  $Q.defer = defer;\n  $Q.reject = reject;\n  $Q.when = when;\n  $Q.resolve = resolve;\n  $Q.all = all;\n  $Q.race = race;\n\n  return $Q;\n}\n\n/** @this */\nfunction $$RAFProvider() { //rAF\n  this.$get = ['$window', '$timeout', function($window, $timeout) {\n    var requestAnimationFrame = $window.requestAnimationFrame ||\n                                $window.webkitRequestAnimationFrame;\n\n    var cancelAnimationFrame = $window.cancelAnimationFrame ||\n                               $window.webkitCancelAnimationFrame ||\n                               $window.webkitCancelRequestAnimationFrame;\n\n    var rafSupported = !!requestAnimationFrame;\n    var raf = rafSupported\n      ? function(fn) {\n          var id = requestAnimationFrame(fn);\n          return function() {\n            cancelAnimationFrame(id);\n          };\n        }\n      : function(fn) {\n          var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n          return function() {\n            $timeout.cancel(timer);\n          };\n        };\n\n    raf.supported = rafSupported;\n\n    return raf;\n  }];\n}\n\n/**\n * DESIGN NOTES\n *\n * The design decisions behind the scope are heavily favored for speed and memory consumption.\n *\n * The typical use of scope is to watch the expressions, which most of the time return the same\n * value as last time so we optimize the operation.\n *\n * Closures construction is expensive in terms of speed as well as memory:\n *   - No closures, instead use prototypical inheritance for API\n *   - Internal state needs to be stored on scope directly, which means that private state is\n *     exposed as $$____ properties\n *\n * Loop operations are optimized by using while(count--) { ... }\n *   - This means that in order to keep the same order of execution as addition we have to add\n *     items to the array at the beginning (unshift) instead of at the end (push)\n *\n * Child scopes are created and removed often\n *   - Using an array would be slow since inserts in the middle are expensive; so we use linked lists\n *\n * There are fewer watches than observers. This is why you don't want the observer to be implemented\n * in the same way as watch. Watch requires return of the initialization function which is expensive\n * to construct.\n */\n\n\n/**\n * @ngdoc provider\n * @name $rootScopeProvider\n * @description\n *\n * Provider for the $rootScope service.\n */\n\n/**\n * @ngdoc method\n * @name $rootScopeProvider#digestTtl\n * @description\n *\n * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and\n * assuming that the model is unstable.\n *\n * The current default is 10 iterations.\n *\n * In complex applications it's possible that the dependencies between `$watch`s will result in\n * several digest iterations. However if an application needs more than the default 10 digest\n * iterations for its model to stabilize then you should investigate what is causing the model to\n * continuously change during the digest.\n *\n * Increasing the TTL could have performance implications, so you should not change it without\n * proper justification.\n *\n * @param {number} limit The number of digest iterations.\n */\n\n\n/**\n * @ngdoc service\n * @name $rootScope\n * @this\n *\n * @description\n *\n * Every application has a single root {@link ng.$rootScope.Scope scope}.\n * All other scopes are descendant scopes of the root scope. Scopes provide separation\n * between the model and the view, via a mechanism for watching the model for changes.\n * They also provide event emission/broadcast and subscription facility. See the\n * {@link guide/scope developer guide on scopes}.\n */\nfunction $RootScopeProvider() {\n  var TTL = 10;\n  var $rootScopeMinErr = minErr('$rootScope');\n  var lastDirtyWatch = null;\n  var applyAsyncId = null;\n\n  this.digestTtl = function(value) {\n    if (arguments.length) {\n      TTL = value;\n    }\n    return TTL;\n  };\n\n  function createChildScopeClass(parent) {\n    function ChildScope() {\n      this.$$watchers = this.$$nextSibling =\n          this.$$childHead = this.$$childTail = null;\n      this.$$listeners = {};\n      this.$$listenerCount = {};\n      this.$$watchersCount = 0;\n      this.$id = nextUid();\n      this.$$ChildScope = null;\n    }\n    ChildScope.prototype = parent;\n    return ChildScope;\n  }\n\n  this.$get = ['$exceptionHandler', '$parse', '$browser',\n      function($exceptionHandler, $parse, $browser) {\n\n    function destroyChildScope($event) {\n        $event.currentScope.$$destroyed = true;\n    }\n\n    function cleanUpScope($scope) {\n\n      // Support: IE 9 only\n      if (msie === 9) {\n        // There is a memory leak in IE9 if all child scopes are not disconnected\n        // completely when a scope is destroyed. So this code will recurse up through\n        // all this scopes children\n        //\n        // See issue https://github.com/angular/angular.js/issues/10706\n        if ($scope.$$childHead) {\n          cleanUpScope($scope.$$childHead);\n        }\n        if ($scope.$$nextSibling) {\n          cleanUpScope($scope.$$nextSibling);\n        }\n      }\n\n      // The code below works around IE9 and V8's memory leaks\n      //\n      // See:\n      // - https://code.google.com/p/v8/issues/detail?id=2073#c26\n      // - https://github.com/angular/angular.js/issues/6794#issuecomment-38648909\n      // - https://github.com/angular/angular.js/issues/1313#issuecomment-10378451\n\n      $scope.$parent = $scope.$$nextSibling = $scope.$$prevSibling = $scope.$$childHead =\n          $scope.$$childTail = $scope.$root = $scope.$$watchers = null;\n    }\n\n    /**\n     * @ngdoc type\n     * @name $rootScope.Scope\n     *\n     * @description\n     * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the\n     * {@link auto.$injector $injector}. Child scopes are created using the\n     * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when\n     * compiled HTML template is executed.) See also the {@link guide/scope Scopes guide} for\n     * an in-depth introduction and usage examples.\n     *\n     *\n     * # Inheritance\n     * A scope can inherit from a parent scope, as in this example:\n     * ```js\n         var parent = $rootScope;\n         var child = parent.$new();\n\n         parent.salutation = \"Hello\";\n         expect(child.salutation).toEqual('Hello');\n\n         child.salutation = \"Welcome\";\n         expect(child.salutation).toEqual('Welcome');\n         expect(parent.salutation).toEqual('Hello');\n     * ```\n     *\n     * When interacting with `Scope` in tests, additional helper methods are available on the\n     * instances of `Scope` type. See {@link ngMock.$rootScope.Scope ngMock Scope} for additional\n     * details.\n     *\n     *\n     * @param {Object.<string, function()>=} providers Map of service factory which need to be\n     *                                       provided for the current scope. Defaults to {@link ng}.\n     * @param {Object.<string, *>=} instanceCache Provides pre-instantiated services which should\n     *                              append/override services provided by `providers`. This is handy\n     *                              when unit-testing and having the need to override a default\n     *                              service.\n     * @returns {Object} Newly created scope.\n     *\n     */\n    function Scope() {\n      this.$id = nextUid();\n      this.$$phase = this.$parent = this.$$watchers =\n                     this.$$nextSibling = this.$$prevSibling =\n                     this.$$childHead = this.$$childTail = null;\n      this.$root = this;\n      this.$$destroyed = false;\n      this.$$listeners = {};\n      this.$$listenerCount = {};\n      this.$$watchersCount = 0;\n      this.$$isolateBindings = null;\n    }\n\n    /**\n     * @ngdoc property\n     * @name $rootScope.Scope#$id\n     *\n     * @description\n     * Unique scope ID (monotonically increasing) useful for debugging.\n     */\n\n     /**\n      * @ngdoc property\n      * @name $rootScope.Scope#$parent\n      *\n      * @description\n      * Reference to the parent scope.\n      */\n\n      /**\n       * @ngdoc property\n       * @name $rootScope.Scope#$root\n       *\n       * @description\n       * Reference to the root scope.\n       */\n\n    Scope.prototype = {\n      constructor: Scope,\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$new\n       * @kind function\n       *\n       * @description\n       * Creates a new child {@link ng.$rootScope.Scope scope}.\n       *\n       * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} event.\n       * The scope can be removed from the scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}.\n       *\n       * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is\n       * desired for the scope and its child scopes to be permanently detached from the parent and\n       * thus stop participating in model change detection and listener notification by invoking.\n       *\n       * @param {boolean} isolate If true, then the scope does not prototypically inherit from the\n       *         parent scope. The scope is isolated, as it can not see parent scope properties.\n       *         When creating widgets, it is useful for the widget to not accidentally read parent\n       *         state.\n       *\n       * @param {Scope} [parent=this] The {@link ng.$rootScope.Scope `Scope`} that will be the `$parent`\n       *                              of the newly created scope. Defaults to `this` scope if not provided.\n       *                              This is used when creating a transclude scope to correctly place it\n       *                              in the scope hierarchy while maintaining the correct prototypical\n       *                              inheritance.\n       *\n       * @returns {Object} The newly created child scope.\n       *\n       */\n      $new: function(isolate, parent) {\n        var child;\n\n        parent = parent || this;\n\n        if (isolate) {\n          child = new Scope();\n          child.$root = this.$root;\n        } else {\n          // Only create a child scope class if somebody asks for one,\n          // but cache it to allow the VM to optimize lookups.\n          if (!this.$$ChildScope) {\n            this.$$ChildScope = createChildScopeClass(this);\n          }\n          child = new this.$$ChildScope();\n        }\n        child.$parent = parent;\n        child.$$prevSibling = parent.$$childTail;\n        if (parent.$$childHead) {\n          parent.$$childTail.$$nextSibling = child;\n          parent.$$childTail = child;\n        } else {\n          parent.$$childHead = parent.$$childTail = child;\n        }\n\n        // When the new scope is not isolated or we inherit from `this`, and\n        // the parent scope is destroyed, the property `$$destroyed` is inherited\n        // prototypically. In all other cases, this property needs to be set\n        // when the parent scope is destroyed.\n        // The listener needs to be added after the parent is set\n        if (isolate || parent !== this) child.$on('$destroy', destroyChildScope);\n\n        return child;\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$watch\n       * @kind function\n       *\n       * @description\n       * Registers a `listener` callback to be executed whenever the `watchExpression` changes.\n       *\n       * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest\n       *   $digest()} and should return the value that will be watched. (`watchExpression` should not change\n       *   its value when executed multiple times with the same input because it may be executed multiple\n       *   times by {@link ng.$rootScope.Scope#$digest $digest()}. That is, `watchExpression` should be\n       *   [idempotent](http://en.wikipedia.org/wiki/Idempotence).)\n       * - The `listener` is called only when the value from the current `watchExpression` and the\n       *   previous call to `watchExpression` are not equal (with the exception of the initial run,\n       *   see below). Inequality is determined according to reference inequality,\n       *   [strict comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)\n       *    via the `!==` Javascript operator, unless `objectEquality == true`\n       *   (see next point)\n       * - When `objectEquality == true`, inequality of the `watchExpression` is determined\n       *   according to the {@link angular.equals} function. To save the value of the object for\n       *   later comparison, the {@link angular.copy} function is used. This therefore means that\n       *   watching complex objects will have adverse memory and performance implications.\n       * - This should not be used to watch for changes in objects that are\n       *   or contain [File](https://developer.mozilla.org/docs/Web/API/File) objects due to limitations with {@link angular.copy `angular.copy`}.\n       * - The watch `listener` may change the model, which may trigger other `listener`s to fire.\n       *   This is achieved by rerunning the watchers until no changes are detected. The rerun\n       *   iteration limit is 10 to prevent an infinite loop deadlock.\n       *\n       *\n       * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called,\n       * you can register a `watchExpression` function with no `listener`. (Be prepared for\n       * multiple calls to your `watchExpression` because it will execute multiple times in a\n       * single {@link ng.$rootScope.Scope#$digest $digest} cycle if a change is detected.)\n       *\n       * After a watcher is registered with the scope, the `listener` fn is called asynchronously\n       * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the\n       * watcher. In rare cases, this is undesirable because the listener is called when the result\n       * of `watchExpression` didn't change. To detect this scenario within the `listener` fn, you\n       * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the\n       * listener was called due to initialization.\n       *\n       *\n       *\n       * # Example\n       * ```js\n           // let's assume that scope was dependency injected as the $rootScope\n           var scope = $rootScope;\n           scope.name = 'misko';\n           scope.counter = 0;\n\n           expect(scope.counter).toEqual(0);\n           scope.$watch('name', function(newValue, oldValue) {\n             scope.counter = scope.counter + 1;\n           });\n           expect(scope.counter).toEqual(0);\n\n           scope.$digest();\n           // the listener is always called during the first $digest loop after it was registered\n           expect(scope.counter).toEqual(1);\n\n           scope.$digest();\n           // but now it will not be called unless the value changes\n           expect(scope.counter).toEqual(1);\n\n           scope.name = 'adam';\n           scope.$digest();\n           expect(scope.counter).toEqual(2);\n\n\n\n           // Using a function as a watchExpression\n           var food;\n           scope.foodCounter = 0;\n           expect(scope.foodCounter).toEqual(0);\n           scope.$watch(\n             // This function returns the value being watched. It is called for each turn of the $digest loop\n             function() { return food; },\n             // This is the change listener, called when the value returned from the above function changes\n             function(newValue, oldValue) {\n               if ( newValue !== oldValue ) {\n                 // Only increment the counter if the value changed\n                 scope.foodCounter = scope.foodCounter + 1;\n               }\n             }\n           );\n           // No digest has been run so the counter will be zero\n           expect(scope.foodCounter).toEqual(0);\n\n           // Run the digest but since food has not changed count will still be zero\n           scope.$digest();\n           expect(scope.foodCounter).toEqual(0);\n\n           // Update food and run digest.  Now the counter will increment\n           food = 'cheeseburger';\n           scope.$digest();\n           expect(scope.foodCounter).toEqual(1);\n\n       * ```\n       *\n       *\n       *\n       * @param {(function()|string)} watchExpression Expression that is evaluated on each\n       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers\n       *    a call to the `listener`.\n       *\n       *    - `string`: Evaluated as {@link guide/expression expression}\n       *    - `function(scope)`: called with current `scope` as a parameter.\n       * @param {function(newVal, oldVal, scope)} listener Callback called whenever the value\n       *    of `watchExpression` changes.\n       *\n       *    - `newVal` contains the current value of the `watchExpression`\n       *    - `oldVal` contains the previous value of the `watchExpression`\n       *    - `scope` refers to the current scope\n       * @param {boolean=} [objectEquality=false] Compare for object equality using {@link angular.equals} instead of\n       *     comparing for reference equality.\n       * @returns {function()} Returns a deregistration function for this listener.\n       */\n      $watch: function(watchExp, listener, objectEquality, prettyPrintExpression) {\n        var get = $parse(watchExp);\n\n        if (get.$$watchDelegate) {\n          return get.$$watchDelegate(this, listener, objectEquality, get, watchExp);\n        }\n        var scope = this,\n            array = scope.$$watchers,\n            watcher = {\n              fn: listener,\n              last: initWatchVal,\n              get: get,\n              exp: prettyPrintExpression || watchExp,\n              eq: !!objectEquality\n            };\n\n        lastDirtyWatch = null;\n\n        if (!isFunction(listener)) {\n          watcher.fn = noop;\n        }\n\n        if (!array) {\n          array = scope.$$watchers = [];\n          array.$$digestWatchIndex = -1;\n        }\n        // we use unshift since we use a while loop in $digest for speed.\n        // the while loop reads in reverse order.\n        array.unshift(watcher);\n        array.$$digestWatchIndex++;\n        incrementWatchersCount(this, 1);\n\n        return function deregisterWatch() {\n          var index = arrayRemove(array, watcher);\n          if (index >= 0) {\n            incrementWatchersCount(scope, -1);\n            if (index < array.$$digestWatchIndex) {\n              array.$$digestWatchIndex--;\n            }\n          }\n          lastDirtyWatch = null;\n        };\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$watchGroup\n       * @kind function\n       *\n       * @description\n       * A variant of {@link ng.$rootScope.Scope#$watch $watch()} where it watches an array of `watchExpressions`.\n       * If any one expression in the collection changes the `listener` is executed.\n       *\n       * - The items in the `watchExpressions` array are observed via the standard `$watch` operation. Their return\n       *   values are examined for changes on every call to `$digest`.\n       * - The `listener` is called whenever any expression in the `watchExpressions` array changes.\n       *\n       * @param {Array.<string|Function(scope)>} watchExpressions Array of expressions that will be individually\n       * watched using {@link ng.$rootScope.Scope#$watch $watch()}\n       *\n       * @param {function(newValues, oldValues, scope)} listener Callback called whenever the return value of any\n       *    expression in `watchExpressions` changes\n       *    The `newValues` array contains the current values of the `watchExpressions`, with the indexes matching\n       *    those of `watchExpression`\n       *    and the `oldValues` array contains the previous values of the `watchExpressions`, with the indexes matching\n       *    those of `watchExpression`\n       *    The `scope` refers to the current scope.\n       * @returns {function()} Returns a de-registration function for all listeners.\n       */\n      $watchGroup: function(watchExpressions, listener) {\n        var oldValues = new Array(watchExpressions.length);\n        var newValues = new Array(watchExpressions.length);\n        var deregisterFns = [];\n        var self = this;\n        var changeReactionScheduled = false;\n        var firstRun = true;\n\n        if (!watchExpressions.length) {\n          // No expressions means we call the listener ASAP\n          var shouldCall = true;\n          self.$evalAsync(function() {\n            if (shouldCall) listener(newValues, newValues, self);\n          });\n          return function deregisterWatchGroup() {\n            shouldCall = false;\n          };\n        }\n\n        if (watchExpressions.length === 1) {\n          // Special case size of one\n          return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) {\n            newValues[0] = value;\n            oldValues[0] = oldValue;\n            listener(newValues, (value === oldValue) ? newValues : oldValues, scope);\n          });\n        }\n\n        forEach(watchExpressions, function(expr, i) {\n          var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) {\n            newValues[i] = value;\n            oldValues[i] = oldValue;\n            if (!changeReactionScheduled) {\n              changeReactionScheduled = true;\n              self.$evalAsync(watchGroupAction);\n            }\n          });\n          deregisterFns.push(unwatchFn);\n        });\n\n        function watchGroupAction() {\n          changeReactionScheduled = false;\n\n          if (firstRun) {\n            firstRun = false;\n            listener(newValues, newValues, self);\n          } else {\n            listener(newValues, oldValues, self);\n          }\n        }\n\n        return function deregisterWatchGroup() {\n          while (deregisterFns.length) {\n            deregisterFns.shift()();\n          }\n        };\n      },\n\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$watchCollection\n       * @kind function\n       *\n       * @description\n       * Shallow watches the properties of an object and fires whenever any of the properties change\n       * (for arrays, this implies watching the array items; for object maps, this implies watching\n       * the properties). If a change is detected, the `listener` callback is fired.\n       *\n       * - The `obj` collection is observed via standard $watch operation and is examined on every\n       *   call to $digest() to see if any items have been added, removed, or moved.\n       * - The `listener` is called whenever anything within the `obj` has changed. Examples include\n       *   adding, removing, and moving items belonging to an object or array.\n       *\n       *\n       * # Example\n       * ```js\n          $scope.names = ['igor', 'matias', 'misko', 'james'];\n          $scope.dataCount = 4;\n\n          $scope.$watchCollection('names', function(newNames, oldNames) {\n            $scope.dataCount = newNames.length;\n          });\n\n          expect($scope.dataCount).toEqual(4);\n          $scope.$digest();\n\n          //still at 4 ... no changes\n          expect($scope.dataCount).toEqual(4);\n\n          $scope.names.pop();\n          $scope.$digest();\n\n          //now there's been a change\n          expect($scope.dataCount).toEqual(3);\n       * ```\n       *\n       *\n       * @param {string|function(scope)} obj Evaluated as {@link guide/expression expression}. The\n       *    expression value should evaluate to an object or an array which is observed on each\n       *    {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the\n       *    collection will trigger a call to the `listener`.\n       *\n       * @param {function(newCollection, oldCollection, scope)} listener a callback function called\n       *    when a change is detected.\n       *    - The `newCollection` object is the newly modified data obtained from the `obj` expression\n       *    - The `oldCollection` object is a copy of the former collection data.\n       *      Due to performance considerations, the`oldCollection` value is computed only if the\n       *      `listener` function declares two or more arguments.\n       *    - The `scope` argument refers to the current scope.\n       *\n       * @returns {function()} Returns a de-registration function for this listener. When the\n       *    de-registration function is executed, the internal watch operation is terminated.\n       */\n      $watchCollection: function(obj, listener) {\n        $watchCollectionInterceptor.$stateful = true;\n\n        var self = this;\n        // the current value, updated on each dirty-check run\n        var newValue;\n        // a shallow copy of the newValue from the last dirty-check run,\n        // updated to match newValue during dirty-check run\n        var oldValue;\n        // a shallow copy of the newValue from when the last change happened\n        var veryOldValue;\n        // only track veryOldValue if the listener is asking for it\n        var trackVeryOldValue = (listener.length > 1);\n        var changeDetected = 0;\n        var changeDetector = $parse(obj, $watchCollectionInterceptor);\n        var internalArray = [];\n        var internalObject = {};\n        var initRun = true;\n        var oldLength = 0;\n\n        function $watchCollectionInterceptor(_value) {\n          newValue = _value;\n          var newLength, key, bothNaN, newItem, oldItem;\n\n          // If the new value is undefined, then return undefined as the watch may be a one-time watch\n          if (isUndefined(newValue)) return;\n\n          if (!isObject(newValue)) { // if primitive\n            if (oldValue !== newValue) {\n              oldValue = newValue;\n              changeDetected++;\n            }\n          } else if (isArrayLike(newValue)) {\n            if (oldValue !== internalArray) {\n              // we are transitioning from something which was not an array into array.\n              oldValue = internalArray;\n              oldLength = oldValue.length = 0;\n              changeDetected++;\n            }\n\n            newLength = newValue.length;\n\n            if (oldLength !== newLength) {\n              // if lengths do not match we need to trigger change notification\n              changeDetected++;\n              oldValue.length = oldLength = newLength;\n            }\n            // copy the items to oldValue and look for changes.\n            for (var i = 0; i < newLength; i++) {\n              oldItem = oldValue[i];\n              newItem = newValue[i];\n\n              // eslint-disable-next-line no-self-compare\n              bothNaN = (oldItem !== oldItem) && (newItem !== newItem);\n              if (!bothNaN && (oldItem !== newItem)) {\n                changeDetected++;\n                oldValue[i] = newItem;\n              }\n            }\n          } else {\n            if (oldValue !== internalObject) {\n              // we are transitioning from something which was not an object into object.\n              oldValue = internalObject = {};\n              oldLength = 0;\n              changeDetected++;\n            }\n            // copy the items to oldValue and look for changes.\n            newLength = 0;\n            for (key in newValue) {\n              if (hasOwnProperty.call(newValue, key)) {\n                newLength++;\n                newItem = newValue[key];\n                oldItem = oldValue[key];\n\n                if (key in oldValue) {\n                  // eslint-disable-next-line no-self-compare\n                  bothNaN = (oldItem !== oldItem) && (newItem !== newItem);\n                  if (!bothNaN && (oldItem !== newItem)) {\n                    changeDetected++;\n                    oldValue[key] = newItem;\n                  }\n                } else {\n                  oldLength++;\n                  oldValue[key] = newItem;\n                  changeDetected++;\n                }\n              }\n            }\n            if (oldLength > newLength) {\n              // we used to have more keys, need to find them and destroy them.\n              changeDetected++;\n              for (key in oldValue) {\n                if (!hasOwnProperty.call(newValue, key)) {\n                  oldLength--;\n                  delete oldValue[key];\n                }\n              }\n            }\n          }\n          return changeDetected;\n        }\n\n        function $watchCollectionAction() {\n          if (initRun) {\n            initRun = false;\n            listener(newValue, newValue, self);\n          } else {\n            listener(newValue, veryOldValue, self);\n          }\n\n          // make a copy for the next time a collection is changed\n          if (trackVeryOldValue) {\n            if (!isObject(newValue)) {\n              //primitive\n              veryOldValue = newValue;\n            } else if (isArrayLike(newValue)) {\n              veryOldValue = new Array(newValue.length);\n              for (var i = 0; i < newValue.length; i++) {\n                veryOldValue[i] = newValue[i];\n              }\n            } else { // if object\n              veryOldValue = {};\n              for (var key in newValue) {\n                if (hasOwnProperty.call(newValue, key)) {\n                  veryOldValue[key] = newValue[key];\n                }\n              }\n            }\n          }\n        }\n\n        return this.$watch(changeDetector, $watchCollectionAction);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$digest\n       * @kind function\n       *\n       * @description\n       * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and\n       * its children. Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change\n       * the model, the `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers}\n       * until no more listeners are firing. This means that it is possible to get into an infinite\n       * loop. This function will throw `'Maximum iteration limit exceeded.'` if the number of\n       * iterations exceeds 10.\n       *\n       * Usually, you don't call `$digest()` directly in\n       * {@link ng.directive:ngController controllers} or in\n       * {@link ng.$compileProvider#directive directives}.\n       * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within\n       * a {@link ng.$compileProvider#directive directive}), which will force a `$digest()`.\n       *\n       * If you want to be notified whenever `$digest()` is called,\n       * you can register a `watchExpression` function with\n       * {@link ng.$rootScope.Scope#$watch $watch()} with no `listener`.\n       *\n       * In unit tests, you may need to call `$digest()` to simulate the scope life cycle.\n       *\n       * # Example\n       * ```js\n           var scope = ...;\n           scope.name = 'misko';\n           scope.counter = 0;\n\n           expect(scope.counter).toEqual(0);\n           scope.$watch('name', function(newValue, oldValue) {\n             scope.counter = scope.counter + 1;\n           });\n           expect(scope.counter).toEqual(0);\n\n           scope.$digest();\n           // the listener is always called during the first $digest loop after it was registered\n           expect(scope.counter).toEqual(1);\n\n           scope.$digest();\n           // but now it will not be called unless the value changes\n           expect(scope.counter).toEqual(1);\n\n           scope.name = 'adam';\n           scope.$digest();\n           expect(scope.counter).toEqual(2);\n       * ```\n       *\n       */\n      $digest: function() {\n        var watch, value, last, fn, get,\n            watchers,\n            dirty, ttl = TTL,\n            next, current, target = this,\n            watchLog = [],\n            logIdx, asyncTask;\n\n        beginPhase('$digest');\n        // Check for changes to browser url that happened in sync before the call to $digest\n        $browser.$$checkUrlChange();\n\n        if (this === $rootScope && applyAsyncId !== null) {\n          // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then\n          // cancel the scheduled $apply and flush the queue of expressions to be evaluated.\n          $browser.defer.cancel(applyAsyncId);\n          flushApplyAsync();\n        }\n\n        lastDirtyWatch = null;\n\n        do { // \"while dirty\" loop\n          dirty = false;\n          current = target;\n\n          // It's safe for asyncQueuePosition to be a local variable here because this loop can't\n          // be reentered recursively. Calling $digest from a function passed to $evalAsync would\n          // lead to a '$digest already in progress' error.\n          for (var asyncQueuePosition = 0; asyncQueuePosition < asyncQueue.length; asyncQueuePosition++) {\n            try {\n              asyncTask = asyncQueue[asyncQueuePosition];\n              fn = asyncTask.fn;\n              fn(asyncTask.scope, asyncTask.locals);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n            lastDirtyWatch = null;\n          }\n          asyncQueue.length = 0;\n\n          traverseScopesLoop:\n          do { // \"traverse the scopes\" loop\n            if ((watchers = current.$$watchers)) {\n              // process our watches\n              watchers.$$digestWatchIndex = watchers.length;\n              while (watchers.$$digestWatchIndex--) {\n                try {\n                  watch = watchers[watchers.$$digestWatchIndex];\n                  // Most common watches are on primitives, in which case we can short\n                  // circuit it with === operator, only when === fails do we use .equals\n                  if (watch) {\n                    get = watch.get;\n                    if ((value = get(current)) !== (last = watch.last) &&\n                        !(watch.eq\n                            ? equals(value, last)\n                            : (isNumberNaN(value) && isNumberNaN(last)))) {\n                      dirty = true;\n                      lastDirtyWatch = watch;\n                      watch.last = watch.eq ? copy(value, null) : value;\n                      fn = watch.fn;\n                      fn(value, ((last === initWatchVal) ? value : last), current);\n                      if (ttl < 5) {\n                        logIdx = 4 - ttl;\n                        if (!watchLog[logIdx]) watchLog[logIdx] = [];\n                        watchLog[logIdx].push({\n                          msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp,\n                          newVal: value,\n                          oldVal: last\n                        });\n                      }\n                    } else if (watch === lastDirtyWatch) {\n                      // If the most recently dirty watcher is now clean, short circuit since the remaining watchers\n                      // have already been tested.\n                      dirty = false;\n                      break traverseScopesLoop;\n                    }\n                  }\n                } catch (e) {\n                  $exceptionHandler(e);\n                }\n              }\n            }\n\n            // Insanity Warning: scope depth-first traversal\n            // yes, this code is a bit crazy, but it works and we have tests to prove it!\n            // this piece should be kept in sync with the traversal in $broadcast\n            if (!(next = ((current.$$watchersCount && current.$$childHead) ||\n                (current !== target && current.$$nextSibling)))) {\n              while (current !== target && !(next = current.$$nextSibling)) {\n                current = current.$parent;\n              }\n            }\n          } while ((current = next));\n\n          // `break traverseScopesLoop;` takes us to here\n\n          if ((dirty || asyncQueue.length) && !(ttl--)) {\n            clearPhase();\n            throw $rootScopeMinErr('infdig',\n                '{0} $digest() iterations reached. Aborting!\\n' +\n                'Watchers fired in the last 5 iterations: {1}',\n                TTL, watchLog);\n          }\n\n        } while (dirty || asyncQueue.length);\n\n        clearPhase();\n\n        // postDigestQueuePosition isn't local here because this loop can be reentered recursively.\n        while (postDigestQueuePosition < postDigestQueue.length) {\n          try {\n            postDigestQueue[postDigestQueuePosition++]();\n          } catch (e) {\n            $exceptionHandler(e);\n          }\n        }\n        postDigestQueue.length = postDigestQueuePosition = 0;\n\n        // Check for changes to browser url that happened during the $digest\n        // (for which no event is fired; e.g. via `history.pushState()`)\n        $browser.$$checkUrlChange();\n      },\n\n\n      /**\n       * @ngdoc event\n       * @name $rootScope.Scope#$destroy\n       * @eventType broadcast on scope being destroyed\n       *\n       * @description\n       * Broadcasted when a scope and its children are being destroyed.\n       *\n       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to\n       * clean up DOM bindings before an element is removed from the DOM.\n       */\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$destroy\n       * @kind function\n       *\n       * @description\n       * Removes the current scope (and all of its children) from the parent scope. Removal implies\n       * that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer\n       * propagate to the current scope and its children. Removal also implies that the current\n       * scope is eligible for garbage collection.\n       *\n       * The `$destroy()` is usually used by directives such as\n       * {@link ng.directive:ngRepeat ngRepeat} for managing the\n       * unrolling of the loop.\n       *\n       * Just before a scope is destroyed, a `$destroy` event is broadcasted on this scope.\n       * Application code can register a `$destroy` event handler that will give it a chance to\n       * perform any necessary cleanup.\n       *\n       * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to\n       * clean up DOM bindings before an element is removed from the DOM.\n       */\n      $destroy: function() {\n        // We can't destroy a scope that has been already destroyed.\n        if (this.$$destroyed) return;\n        var parent = this.$parent;\n\n        this.$broadcast('$destroy');\n        this.$$destroyed = true;\n\n        if (this === $rootScope) {\n          //Remove handlers attached to window when $rootScope is removed\n          $browser.$$applicationDestroyed();\n        }\n\n        incrementWatchersCount(this, -this.$$watchersCount);\n        for (var eventName in this.$$listenerCount) {\n          decrementListenerCount(this, this.$$listenerCount[eventName], eventName);\n        }\n\n        // sever all the references to parent scopes (after this cleanup, the current scope should\n        // not be retained by any of our references and should be eligible for garbage collection)\n        if (parent && parent.$$childHead === this) parent.$$childHead = this.$$nextSibling;\n        if (parent && parent.$$childTail === this) parent.$$childTail = this.$$prevSibling;\n        if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;\n        if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;\n\n        // Disable listeners, watchers and apply/digest methods\n        this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop;\n        this.$on = this.$watch = this.$watchGroup = function() { return noop; };\n        this.$$listeners = {};\n\n        // Disconnect the next sibling to prevent `cleanUpScope` destroying those too\n        this.$$nextSibling = null;\n        cleanUpScope(this);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$eval\n       * @kind function\n       *\n       * @description\n       * Executes the `expression` on the current scope and returns the result. Any exceptions in\n       * the expression are propagated (uncaught). This is useful when evaluating Angular\n       * expressions.\n       *\n       * # Example\n       * ```js\n           var scope = ng.$rootScope.Scope();\n           scope.a = 1;\n           scope.b = 2;\n\n           expect(scope.$eval('a+b')).toEqual(3);\n           expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3);\n       * ```\n       *\n       * @param {(string|function())=} expression An angular expression to be executed.\n       *\n       *    - `string`: execute using the rules as defined in  {@link guide/expression expression}.\n       *    - `function(scope)`: execute the function with the current `scope` parameter.\n       *\n       * @param {(object)=} locals Local variables object, useful for overriding values in scope.\n       * @returns {*} The result of evaluating the expression.\n       */\n      $eval: function(expr, locals) {\n        return $parse(expr)(this, locals);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$evalAsync\n       * @kind function\n       *\n       * @description\n       * Executes the expression on the current scope at a later point in time.\n       *\n       * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only\n       * that:\n       *\n       *   - it will execute after the function that scheduled the evaluation (preferably before DOM\n       *     rendering).\n       *   - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after\n       *     `expression` execution.\n       *\n       * Any exceptions from the execution of the expression are forwarded to the\n       * {@link ng.$exceptionHandler $exceptionHandler} service.\n       *\n       * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle\n       * will be scheduled. However, it is encouraged to always call code that changes the model\n       * from within an `$apply` call. That includes code evaluated via `$evalAsync`.\n       *\n       * @param {(string|function())=} expression An angular expression to be executed.\n       *\n       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.\n       *    - `function(scope)`: execute the function with the current `scope` parameter.\n       *\n       * @param {(object)=} locals Local variables object, useful for overriding values in scope.\n       */\n      $evalAsync: function(expr, locals) {\n        // if we are outside of an $digest loop and this is the first time we are scheduling async\n        // task also schedule async auto-flush\n        if (!$rootScope.$$phase && !asyncQueue.length) {\n          $browser.defer(function() {\n            if (asyncQueue.length) {\n              $rootScope.$digest();\n            }\n          });\n        }\n\n        asyncQueue.push({scope: this, fn: $parse(expr), locals: locals});\n      },\n\n      $$postDigest: function(fn) {\n        postDigestQueue.push(fn);\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$apply\n       * @kind function\n       *\n       * @description\n       * `$apply()` is used to execute an expression in angular from outside of the angular\n       * framework. (For example from browser DOM events, setTimeout, XHR or third party libraries).\n       * Because we are calling into the angular framework we need to perform proper scope life\n       * cycle of {@link ng.$exceptionHandler exception handling},\n       * {@link ng.$rootScope.Scope#$digest executing watches}.\n       *\n       * ## Life cycle\n       *\n       * # Pseudo-Code of `$apply()`\n       * ```js\n           function $apply(expr) {\n             try {\n               return $eval(expr);\n             } catch (e) {\n               $exceptionHandler(e);\n             } finally {\n               $root.$digest();\n             }\n           }\n       * ```\n       *\n       *\n       * Scope's `$apply()` method transitions through the following stages:\n       *\n       * 1. The {@link guide/expression expression} is executed using the\n       *    {@link ng.$rootScope.Scope#$eval $eval()} method.\n       * 2. Any exceptions from the execution of the expression are forwarded to the\n       *    {@link ng.$exceptionHandler $exceptionHandler} service.\n       * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the\n       *    expression was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method.\n       *\n       *\n       * @param {(string|function())=} exp An angular expression to be executed.\n       *\n       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.\n       *    - `function(scope)`: execute the function with current `scope` parameter.\n       *\n       * @returns {*} The result of evaluating the expression.\n       */\n      $apply: function(expr) {\n        try {\n          beginPhase('$apply');\n          try {\n            return this.$eval(expr);\n          } finally {\n            clearPhase();\n          }\n        } catch (e) {\n          $exceptionHandler(e);\n        } finally {\n          try {\n            $rootScope.$digest();\n          } catch (e) {\n            $exceptionHandler(e);\n            // eslint-disable-next-line no-unsafe-finally\n            throw e;\n          }\n        }\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$applyAsync\n       * @kind function\n       *\n       * @description\n       * Schedule the invocation of $apply to occur at a later time. The actual time difference\n       * varies across browsers, but is typically around ~10 milliseconds.\n       *\n       * This can be used to queue up multiple expressions which need to be evaluated in the same\n       * digest.\n       *\n       * @param {(string|function())=} exp An angular expression to be executed.\n       *\n       *    - `string`: execute using the rules as defined in {@link guide/expression expression}.\n       *    - `function(scope)`: execute the function with current `scope` parameter.\n       */\n      $applyAsync: function(expr) {\n        var scope = this;\n        if (expr) {\n          applyAsyncQueue.push($applyAsyncExpression);\n        }\n        expr = $parse(expr);\n        scheduleApplyAsync();\n\n        function $applyAsyncExpression() {\n          scope.$eval(expr);\n        }\n      },\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$on\n       * @kind function\n       *\n       * @description\n       * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for\n       * discussion of event life cycle.\n       *\n       * The event listener function format is: `function(event, args...)`. The `event` object\n       * passed into the listener has the following attributes:\n       *\n       *   - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or\n       *     `$broadcast`-ed.\n       *   - `currentScope` - `{Scope}`: the scope that is currently handling the event. Once the\n       *     event propagates through the scope hierarchy, this property is set to null.\n       *   - `name` - `{string}`: name of the event.\n       *   - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel\n       *     further event propagation (available only for events that were `$emit`-ed).\n       *   - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag\n       *     to true.\n       *   - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.\n       *\n       * @param {string} name Event name to listen on.\n       * @param {function(event, ...args)} listener Function to call when the event is emitted.\n       * @returns {function()} Returns a deregistration function for this listener.\n       */\n      $on: function(name, listener) {\n        var namedListeners = this.$$listeners[name];\n        if (!namedListeners) {\n          this.$$listeners[name] = namedListeners = [];\n        }\n        namedListeners.push(listener);\n\n        var current = this;\n        do {\n          if (!current.$$listenerCount[name]) {\n            current.$$listenerCount[name] = 0;\n          }\n          current.$$listenerCount[name]++;\n        } while ((current = current.$parent));\n\n        var self = this;\n        return function() {\n          var indexOfListener = namedListeners.indexOf(listener);\n          if (indexOfListener !== -1) {\n            namedListeners[indexOfListener] = null;\n            decrementListenerCount(self, 1, name);\n          }\n        };\n      },\n\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$emit\n       * @kind function\n       *\n       * @description\n       * Dispatches an event `name` upwards through the scope hierarchy notifying the\n       * registered {@link ng.$rootScope.Scope#$on} listeners.\n       *\n       * The event life cycle starts at the scope on which `$emit` was called. All\n       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get\n       * notified. Afterwards, the event traverses upwards toward the root scope and calls all\n       * registered listeners along the way. The event will stop propagating if one of the listeners\n       * cancels it.\n       *\n       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed\n       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.\n       *\n       * @param {string} name Event name to emit.\n       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.\n       * @return {Object} Event object (see {@link ng.$rootScope.Scope#$on}).\n       */\n      $emit: function(name, args) {\n        var empty = [],\n            namedListeners,\n            scope = this,\n            stopPropagation = false,\n            event = {\n              name: name,\n              targetScope: scope,\n              stopPropagation: function() {stopPropagation = true;},\n              preventDefault: function() {\n                event.defaultPrevented = true;\n              },\n              defaultPrevented: false\n            },\n            listenerArgs = concat([event], arguments, 1),\n            i, length;\n\n        do {\n          namedListeners = scope.$$listeners[name] || empty;\n          event.currentScope = scope;\n          for (i = 0, length = namedListeners.length; i < length; i++) {\n\n            // if listeners were deregistered, defragment the array\n            if (!namedListeners[i]) {\n              namedListeners.splice(i, 1);\n              i--;\n              length--;\n              continue;\n            }\n            try {\n              //allow all listeners attached to the current scope to run\n              namedListeners[i].apply(null, listenerArgs);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          }\n          //if any listener on the current scope stops propagation, prevent bubbling\n          if (stopPropagation) {\n            event.currentScope = null;\n            return event;\n          }\n          //traverse upwards\n          scope = scope.$parent;\n        } while (scope);\n\n        event.currentScope = null;\n\n        return event;\n      },\n\n\n      /**\n       * @ngdoc method\n       * @name $rootScope.Scope#$broadcast\n       * @kind function\n       *\n       * @description\n       * Dispatches an event `name` downwards to all child scopes (and their children) notifying the\n       * registered {@link ng.$rootScope.Scope#$on} listeners.\n       *\n       * The event life cycle starts at the scope on which `$broadcast` was called. All\n       * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get\n       * notified. Afterwards, the event propagates to all direct and indirect scopes of the current\n       * scope and calls all registered listeners along the way. The event cannot be canceled.\n       *\n       * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed\n       * onto the {@link ng.$exceptionHandler $exceptionHandler} service.\n       *\n       * @param {string} name Event name to broadcast.\n       * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.\n       * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}\n       */\n      $broadcast: function(name, args) {\n        var target = this,\n            current = target,\n            next = target,\n            event = {\n              name: name,\n              targetScope: target,\n              preventDefault: function() {\n                event.defaultPrevented = true;\n              },\n              defaultPrevented: false\n            };\n\n        if (!target.$$listenerCount[name]) return event;\n\n        var listenerArgs = concat([event], arguments, 1),\n            listeners, i, length;\n\n        //down while you can, then up and next sibling or up and next sibling until back at root\n        while ((current = next)) {\n          event.currentScope = current;\n          listeners = current.$$listeners[name] || [];\n          for (i = 0, length = listeners.length; i < length; i++) {\n            // if listeners were deregistered, defragment the array\n            if (!listeners[i]) {\n              listeners.splice(i, 1);\n              i--;\n              length--;\n              continue;\n            }\n\n            try {\n              listeners[i].apply(null, listenerArgs);\n            } catch (e) {\n              $exceptionHandler(e);\n            }\n          }\n\n          // Insanity Warning: scope depth-first traversal\n          // yes, this code is a bit crazy, but it works and we have tests to prove it!\n          // this piece should be kept in sync with the traversal in $digest\n          // (though it differs due to having the extra check for $$listenerCount)\n          if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||\n              (current !== target && current.$$nextSibling)))) {\n            while (current !== target && !(next = current.$$nextSibling)) {\n              current = current.$parent;\n            }\n          }\n        }\n\n        event.currentScope = null;\n        return event;\n      }\n    };\n\n    var $rootScope = new Scope();\n\n    //The internal queues. Expose them on the $rootScope for debugging/testing purposes.\n    var asyncQueue = $rootScope.$$asyncQueue = [];\n    var postDigestQueue = $rootScope.$$postDigestQueue = [];\n    var applyAsyncQueue = $rootScope.$$applyAsyncQueue = [];\n\n    var postDigestQueuePosition = 0;\n\n    return $rootScope;\n\n\n    function beginPhase(phase) {\n      if ($rootScope.$$phase) {\n        throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase);\n      }\n\n      $rootScope.$$phase = phase;\n    }\n\n    function clearPhase() {\n      $rootScope.$$phase = null;\n    }\n\n    function incrementWatchersCount(current, count) {\n      do {\n        current.$$watchersCount += count;\n      } while ((current = current.$parent));\n    }\n\n    function decrementListenerCount(current, count, name) {\n      do {\n        current.$$listenerCount[name] -= count;\n\n        if (current.$$listenerCount[name] === 0) {\n          delete current.$$listenerCount[name];\n        }\n      } while ((current = current.$parent));\n    }\n\n    /**\n     * function used as an initial value for watchers.\n     * because it's unique we can easily tell it apart from other values\n     */\n    function initWatchVal() {}\n\n    function flushApplyAsync() {\n      while (applyAsyncQueue.length) {\n        try {\n          applyAsyncQueue.shift()();\n        } catch (e) {\n          $exceptionHandler(e);\n        }\n      }\n      applyAsyncId = null;\n    }\n\n    function scheduleApplyAsync() {\n      if (applyAsyncId === null) {\n        applyAsyncId = $browser.defer(function() {\n          $rootScope.$apply(flushApplyAsync);\n        });\n      }\n    }\n  }];\n}\n\n/**\n * @ngdoc service\n * @name $rootElement\n *\n * @description\n * The root element of Angular application. This is either the element where {@link\n * ng.directive:ngApp ngApp} was declared or the element passed into\n * {@link angular.bootstrap}. The element represents the root element of application. It is also the\n * location where the application's {@link auto.$injector $injector} service gets\n * published, and can be retrieved using `$rootElement.injector()`.\n */\n\n\n// the implementation is in angular.bootstrap\n\n/**\n * @this\n * @description\n * Private service to sanitize uris for links and images. Used by $compile and $sanitize.\n */\nfunction $$SanitizeUriProvider() {\n  var aHrefSanitizationWhitelist = /^\\s*(https?|ftp|mailto|tel|file):/,\n    imgSrcSanitizationWhitelist = /^\\s*((https?|ftp|file|blob):|data:image\\/)/;\n\n  /**\n   * @description\n   * Retrieves or overrides the default regular expression that is used for whitelisting of safe\n   * urls during a[href] sanitization.\n   *\n   * The sanitization is a security measure aimed at prevent XSS attacks via html links.\n   *\n   * Any url about to be assigned to a[href] via data-binding is first normalized and turned into\n   * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`\n   * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n   *\n   * @param {RegExp=} regexp New regexp to whitelist urls with.\n   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for\n   *    chaining otherwise.\n   */\n  this.aHrefSanitizationWhitelist = function(regexp) {\n    if (isDefined(regexp)) {\n      aHrefSanitizationWhitelist = regexp;\n      return this;\n    }\n    return aHrefSanitizationWhitelist;\n  };\n\n\n  /**\n   * @description\n   * Retrieves or overrides the default regular expression that is used for whitelisting of safe\n   * urls during img[src] sanitization.\n   *\n   * The sanitization is a security measure aimed at prevent XSS attacks via html links.\n   *\n   * Any url about to be assigned to img[src] via data-binding is first normalized and turned into\n   * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`\n   * regular expression. If a match is found, the original url is written into the dom. Otherwise,\n   * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.\n   *\n   * @param {RegExp=} regexp New regexp to whitelist urls with.\n   * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for\n   *    chaining otherwise.\n   */\n  this.imgSrcSanitizationWhitelist = function(regexp) {\n    if (isDefined(regexp)) {\n      imgSrcSanitizationWhitelist = regexp;\n      return this;\n    }\n    return imgSrcSanitizationWhitelist;\n  };\n\n  this.$get = function() {\n    return function sanitizeUri(uri, isImage) {\n      var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;\n      var normalizedVal;\n      normalizedVal = urlResolve(uri).href;\n      if (normalizedVal !== '' && !normalizedVal.match(regex)) {\n        return 'unsafe:' + normalizedVal;\n      }\n      return uri;\n    };\n  };\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *     Any commits to this file should be reviewed with security in mind.  *\n *   Changes to this file can potentially create security vulnerabilities. *\n *          An approval from 2 Core members with history of modifying      *\n *                         this file is required.                          *\n *                                                                         *\n *  Does the change somehow allow for arbitrary javascript to be executed? *\n *    Or allows for someone to change the prototype of built-in objects?   *\n *     Or gives undesired access to variables likes document or window?    *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/* exported $SceProvider, $SceDelegateProvider */\n\nvar $sceMinErr = minErr('$sce');\n\nvar SCE_CONTEXTS = {\n  HTML: 'html',\n  CSS: 'css',\n  URL: 'url',\n  // RESOURCE_URL is a subtype of URL used in contexts where a privileged resource is sourced from a\n  // url.  (e.g. ng-include, script src, templateUrl)\n  RESOURCE_URL: 'resourceUrl',\n  JS: 'js'\n};\n\n// Helper functions follow.\n\nvar UNDERSCORE_LOWERCASE_REGEXP = /_([a-z])/g;\n\nfunction snakeToCamel(name) {\n  return name\n    .replace(UNDERSCORE_LOWERCASE_REGEXP, fnCamelCaseReplace);\n}\n\nfunction adjustMatcher(matcher) {\n  if (matcher === 'self') {\n    return matcher;\n  } else if (isString(matcher)) {\n    // Strings match exactly except for 2 wildcards - '*' and '**'.\n    // '*' matches any character except those from the set ':/.?&'.\n    // '**' matches any character (like .* in a RegExp).\n    // More than 2 *'s raises an error as it's ill defined.\n    if (matcher.indexOf('***') > -1) {\n      throw $sceMinErr('iwcard',\n          'Illegal sequence *** in string matcher.  String: {0}', matcher);\n    }\n    matcher = escapeForRegexp(matcher).\n                  replace(/\\\\\\*\\\\\\*/g, '.*').\n                  replace(/\\\\\\*/g, '[^:/.?&;]*');\n    return new RegExp('^' + matcher + '$');\n  } else if (isRegExp(matcher)) {\n    // The only other type of matcher allowed is a Regexp.\n    // Match entire URL / disallow partial matches.\n    // Flags are reset (i.e. no global, ignoreCase or multiline)\n    return new RegExp('^' + matcher.source + '$');\n  } else {\n    throw $sceMinErr('imatcher',\n        'Matchers may only be \"self\", string patterns or RegExp objects');\n  }\n}\n\n\nfunction adjustMatchers(matchers) {\n  var adjustedMatchers = [];\n  if (isDefined(matchers)) {\n    forEach(matchers, function(matcher) {\n      adjustedMatchers.push(adjustMatcher(matcher));\n    });\n  }\n  return adjustedMatchers;\n}\n\n\n/**\n * @ngdoc service\n * @name $sceDelegate\n * @kind function\n *\n * @description\n *\n * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict\n * Contextual Escaping (SCE)} services to AngularJS.\n *\n * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of\n * the `$sce` service to customize the way Strict Contextual Escaping works in AngularJS.  This is\n * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to\n * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things\n * work because `$sce` delegates to `$sceDelegate` for these operations.\n *\n * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service.\n *\n * The default instance of `$sceDelegate` should work out of the box with little pain.  While you\n * can override it completely to change the behavior of `$sce`, the common case would\n * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting\n * your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as\n * templates.  Refer {@link ng.$sceDelegateProvider#resourceUrlWhitelist\n * $sceDelegateProvider.resourceUrlWhitelist} and {@link\n * ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}\n */\n\n/**\n * @ngdoc provider\n * @name $sceDelegateProvider\n * @this\n *\n * @description\n *\n * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate\n * $sceDelegate} service.  This allows one to get/set the whitelists and blacklists used to ensure\n * that the URLs used for sourcing Angular templates are safe.  Refer {@link\n * ng.$sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and\n * {@link ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}\n *\n * For the general details about this service in Angular, read the main page for {@link ng.$sce\n * Strict Contextual Escaping (SCE)}.\n *\n * **Example**:  Consider the following case. <a name=\"example\"></a>\n *\n * - your app is hosted at url `http://myapp.example.com/`\n * - but some of your templates are hosted on other domains you control such as\n *   `http://srv01.assets.example.com/`, `http://srv02.assets.example.com/`, etc.\n * - and you have an open redirect at `http://myapp.example.com/clickThru?...`.\n *\n * Here is what a secure configuration for this scenario might look like:\n *\n * ```\n *  angular.module('myApp', []).config(function($sceDelegateProvider) {\n *    $sceDelegateProvider.resourceUrlWhitelist([\n *      // Allow same origin resource loads.\n *      'self',\n *      // Allow loading from our assets domain.  Notice the difference between * and **.\n *      'http://srv*.assets.example.com/**'\n *    ]);\n *\n *    // The blacklist overrides the whitelist so the open redirect here is blocked.\n *    $sceDelegateProvider.resourceUrlBlacklist([\n *      'http://myapp.example.com/clickThru**'\n *    ]);\n *  });\n * ```\n */\n\nfunction $SceDelegateProvider() {\n  this.SCE_CONTEXTS = SCE_CONTEXTS;\n\n  // Resource URLs can also be trusted by policy.\n  var resourceUrlWhitelist = ['self'],\n      resourceUrlBlacklist = [];\n\n  /**\n   * @ngdoc method\n   * @name $sceDelegateProvider#resourceUrlWhitelist\n   * @kind function\n   *\n   * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value\n   *    provided.  This must be an array or null.  A snapshot of this array is used so further\n   *    changes to the array are ignored.\n   *\n   *    Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items\n   *    allowed in this array.\n   *\n   *    <div class=\"alert alert-warning\">\n   *    **Note:** an empty whitelist array will block all URLs!\n   *    </div>\n   *\n   * @return {Array} the currently set whitelist array.\n   *\n   * The **default value** when no whitelist has been explicitly set is `['self']` allowing only\n   * same origin resource requests.\n   *\n   * @description\n   * Sets/Gets the whitelist of trusted resource URLs.\n   */\n  this.resourceUrlWhitelist = function(value) {\n    if (arguments.length) {\n      resourceUrlWhitelist = adjustMatchers(value);\n    }\n    return resourceUrlWhitelist;\n  };\n\n  /**\n   * @ngdoc method\n   * @name $sceDelegateProvider#resourceUrlBlacklist\n   * @kind function\n   *\n   * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value\n   *    provided.  This must be an array or null.  A snapshot of this array is used so further\n   *    changes to the array are ignored.\n   *\n   *    Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items\n   *    allowed in this array.\n   *\n   *    The typical usage for the blacklist is to **block\n   *    [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as\n   *    these would otherwise be trusted but actually return content from the redirected domain.\n   *\n   *    Finally, **the blacklist overrides the whitelist** and has the final say.\n   *\n   * @return {Array} the currently set blacklist array.\n   *\n   * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there\n   * is no blacklist.)\n   *\n   * @description\n   * Sets/Gets the blacklist of trusted resource URLs.\n   */\n\n  this.resourceUrlBlacklist = function(value) {\n    if (arguments.length) {\n      resourceUrlBlacklist = adjustMatchers(value);\n    }\n    return resourceUrlBlacklist;\n  };\n\n  this.$get = ['$injector', function($injector) {\n\n    var htmlSanitizer = function htmlSanitizer(html) {\n      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');\n    };\n\n    if ($injector.has('$sanitize')) {\n      htmlSanitizer = $injector.get('$sanitize');\n    }\n\n\n    function matchUrl(matcher, parsedUrl) {\n      if (matcher === 'self') {\n        return urlIsSameOrigin(parsedUrl);\n      } else {\n        // definitely a regex.  See adjustMatchers()\n        return !!matcher.exec(parsedUrl.href);\n      }\n    }\n\n    function isResourceUrlAllowedByPolicy(url) {\n      var parsedUrl = urlResolve(url.toString());\n      var i, n, allowed = false;\n      // Ensure that at least one item from the whitelist allows this url.\n      for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) {\n        if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) {\n          allowed = true;\n          break;\n        }\n      }\n      if (allowed) {\n        // Ensure that no item from the blacklist blocked this url.\n        for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) {\n          if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) {\n            allowed = false;\n            break;\n          }\n        }\n      }\n      return allowed;\n    }\n\n    function generateHolderType(Base) {\n      var holderType = function TrustedValueHolderType(trustedValue) {\n        this.$$unwrapTrustedValue = function() {\n          return trustedValue;\n        };\n      };\n      if (Base) {\n        holderType.prototype = new Base();\n      }\n      holderType.prototype.valueOf = function sceValueOf() {\n        return this.$$unwrapTrustedValue();\n      };\n      holderType.prototype.toString = function sceToString() {\n        return this.$$unwrapTrustedValue().toString();\n      };\n      return holderType;\n    }\n\n    var trustedValueHolderBase = generateHolderType(),\n        byType = {};\n\n    byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase);\n    byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase);\n    byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase);\n    byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase);\n    byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]);\n\n    /**\n     * @ngdoc method\n     * @name $sceDelegate#trustAs\n     *\n     * @description\n     * Returns an object that is trusted by angular for use in specified strict\n     * contextual escaping contexts (such as ng-bind-html, ng-include, any src\n     * attribute interpolation, any dom event binding attribute interpolation\n     * such as for onclick,  etc.) that uses the provided value.\n     * See {@link ng.$sce $sce} for enabling strict contextual escaping.\n     *\n     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,\n     *   resourceUrl, html, js and css.\n     * @param {*} value The value that that should be considered trusted/safe.\n     * @returns {*} A value that can be used to stand in for the provided `value` in places\n     * where Angular expects a $sce.trustAs() return value.\n     */\n    function trustAs(type, trustedValue) {\n      var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null);\n      if (!Constructor) {\n        throw $sceMinErr('icontext',\n            'Attempted to trust a value in invalid context. Context: {0}; Value: {1}',\n            type, trustedValue);\n      }\n      if (trustedValue === null || isUndefined(trustedValue) || trustedValue === '') {\n        return trustedValue;\n      }\n      // All the current contexts in SCE_CONTEXTS happen to be strings.  In order to avoid trusting\n      // mutable objects, we ensure here that the value passed in is actually a string.\n      if (typeof trustedValue !== 'string') {\n        throw $sceMinErr('itype',\n            'Attempted to trust a non-string value in a content requiring a string: Context: {0}',\n            type);\n      }\n      return new Constructor(trustedValue);\n    }\n\n    /**\n     * @ngdoc method\n     * @name $sceDelegate#valueOf\n     *\n     * @description\n     * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs\n     * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link\n     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.\n     *\n     * If the passed parameter is not a value that had been returned by {@link\n     * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, returns it as-is.\n     *\n     * @param {*} value The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}\n     *      call or anything else.\n     * @returns {*} The `value` that was originally provided to {@link ng.$sceDelegate#trustAs\n     *     `$sceDelegate.trustAs`} if `value` is the result of such a call.  Otherwise, returns\n     *     `value` unchanged.\n     */\n    function valueOf(maybeTrusted) {\n      if (maybeTrusted instanceof trustedValueHolderBase) {\n        return maybeTrusted.$$unwrapTrustedValue();\n      } else {\n        return maybeTrusted;\n      }\n    }\n\n    /**\n     * @ngdoc method\n     * @name $sceDelegate#getTrusted\n     *\n     * @description\n     * Takes the result of a {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} call and\n     * returns the originally supplied value if the queried context type is a supertype of the\n     * created type.  If this condition isn't satisfied, throws an exception.\n     *\n     * <div class=\"alert alert-danger\">\n     * Disabling auto-escaping is extremely dangerous, it usually creates a Cross Site Scripting\n     * (XSS) vulnerability in your application.\n     * </div>\n     *\n     * @param {string} type The kind of context in which this value is to be used.\n     * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs\n     *     `$sceDelegate.trustAs`} call.\n     * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs\n     *     `$sceDelegate.trustAs`} if valid in this context.  Otherwise, throws an exception.\n     */\n    function getTrusted(type, maybeTrusted) {\n      if (maybeTrusted === null || isUndefined(maybeTrusted) || maybeTrusted === '') {\n        return maybeTrusted;\n      }\n      var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);\n      if (constructor && maybeTrusted instanceof constructor) {\n        return maybeTrusted.$$unwrapTrustedValue();\n      }\n      // If we get here, then we may only take one of two actions.\n      // 1. sanitize the value for the requested type, or\n      // 2. throw an exception.\n      if (type === SCE_CONTEXTS.RESOURCE_URL) {\n        if (isResourceUrlAllowedByPolicy(maybeTrusted)) {\n          return maybeTrusted;\n        } else {\n          throw $sceMinErr('insecurl',\n              'Blocked loading resource from url not allowed by $sceDelegate policy.  URL: {0}',\n              maybeTrusted.toString());\n        }\n      } else if (type === SCE_CONTEXTS.HTML) {\n        return htmlSanitizer(maybeTrusted);\n      }\n      throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');\n    }\n\n    return { trustAs: trustAs,\n             getTrusted: getTrusted,\n             valueOf: valueOf };\n  }];\n}\n\n\n/**\n * @ngdoc provider\n * @name $sceProvider\n * @this\n *\n * @description\n *\n * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service.\n * -   enable/disable Strict Contextual Escaping (SCE) in a module\n * -   override the default implementation with a custom delegate\n *\n * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}.\n */\n\n/**\n * @ngdoc service\n * @name $sce\n * @kind function\n *\n * @description\n *\n * `$sce` is a service that provides Strict Contextual Escaping services to AngularJS.\n *\n * # Strict Contextual Escaping\n *\n * Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain\n * contexts to result in a value that is marked as safe to use for that context.  One example of\n * such a context is binding arbitrary html controlled by the user via `ng-bind-html`.  We refer\n * to these contexts as privileged or SCE contexts.\n *\n * As of version 1.2, Angular ships with SCE enabled by default.\n *\n * Note:  When enabled (the default), IE<11 in quirks mode is not supported.  In this mode, IE<11 allow\n * one to execute arbitrary javascript by the use of the expression() syntax.  Refer\n * <http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx> to learn more about them.\n * You can ensure your document is in standards mode and not quirks mode by adding `<!doctype html>`\n * to the top of your HTML document.\n *\n * SCE assists in writing code in a way that (a) is secure by default and (b) makes auditing for\n * security vulnerabilities such as XSS, clickjacking, etc. a lot easier.\n *\n * Here's an example of a binding in a privileged context:\n *\n * ```\n * <input ng-model=\"userHtml\" aria-label=\"User input\">\n * <div ng-bind-html=\"userHtml\"></div>\n * ```\n *\n * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user.  With SCE\n * disabled, this application allows the user to render arbitrary HTML into the DIV.\n * In a more realistic example, one may be rendering user comments, blog articles, etc. via\n * bindings.  (HTML is just one example of a context where rendering user controlled input creates\n * security vulnerabilities.)\n *\n * For the case of HTML, you might use a library, either on the client side, or on the server side,\n * to sanitize unsafe HTML before binding to the value and rendering it in the document.\n *\n * How would you ensure that every place that used these types of bindings was bound to a value that\n * was sanitized by your library (or returned as safe for rendering by your server?)  How can you\n * ensure that you didn't accidentally delete the line that sanitized the value, or renamed some\n * properties/fields and forgot to update the binding to the sanitized value?\n *\n * To be secure by default, you want to ensure that any such bindings are disallowed unless you can\n * determine that something explicitly says it's safe to use a value for binding in that\n * context.  You can then audit your code (a simple grep would do) to ensure that this is only done\n * for those values that you can easily tell are safe - because they were received from your server,\n * sanitized by your library, etc.  You can organize your codebase to help with this - perhaps\n * allowing only the files in a specific directory to do this.  Ensuring that the internal API\n * exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task.\n *\n * In the case of AngularJS' SCE service, one uses {@link ng.$sce#trustAs $sce.trustAs}\n * (and shorthand methods such as {@link ng.$sce#trustAsHtml $sce.trustAsHtml}, etc.) to\n * obtain values that will be accepted by SCE / privileged contexts.\n *\n *\n * ## How does it work?\n *\n * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted\n * $sce.getTrusted(context, value)} rather than to the value directly.  Directives use {@link\n * ng.$sce#parseAs $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the\n * {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals.\n *\n * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link\n * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}.  Here's the actual code (slightly\n * simplified):\n *\n * ```\n * var ngBindHtmlDirective = ['$sce', function($sce) {\n *   return function(scope, element, attr) {\n *     scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {\n *       element.html(value || '');\n *     });\n *   };\n * }];\n * ```\n *\n * ## Impact on loading templates\n *\n * This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as\n * `templateUrl`'s specified by {@link guide/directive directives}.\n *\n * By default, Angular only loads templates from the same domain and protocol as the application\n * document.  This is done by calling {@link ng.$sce#getTrustedResourceUrl\n * $sce.getTrustedResourceUrl} on the template URL.  To load templates from other domains and/or\n * protocols, you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist\n * them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value.\n *\n * *Please note*:\n * The browser's\n * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)\n * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)\n * policy apply in addition to this and may further restrict whether the template is successfully\n * loaded.  This means that without the right CORS policy, loading templates from a different domain\n * won't work on all browsers.  Also, loading templates from `file://` URL does not work on some\n * browsers.\n *\n * ## This feels like too much overhead\n *\n * It's important to remember that SCE only applies to interpolation expressions.\n *\n * If your expressions are constant literals, they're automatically trusted and you don't need to\n * call `$sce.trustAs` on them (remember to include the `ngSanitize` module) (e.g.\n * `<div ng-bind-html=\"'<b>implicitly trusted</b>'\"></div>`) just works.\n *\n * Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them\n * through {@link ng.$sce#getTrusted $sce.getTrusted}.  SCE doesn't play a role here.\n *\n * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load\n * templates in `ng-include` from your application's domain without having to even know about SCE.\n * It blocks loading templates from other domains or loading templates over http from an https\n * served document.  You can change these by setting your own custom {@link\n * ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link\n * ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs.\n *\n * This significantly reduces the overhead.  It is far easier to pay the small overhead and have an\n * application that's secure and can be audited to verify that with much more ease than bolting\n * security onto an application later.\n *\n * <a name=\"contexts\"></a>\n * ## What trusted context types are supported?\n *\n * | Context             | Notes          |\n * |---------------------|----------------|\n * | `$sce.HTML`         | For HTML that's safe to source into the application.  The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered and the {@link ngSanitize $sanitize} module is present this will sanitize the value instead of throwing an error. |\n * | `$sce.CSS`          | For CSS that's safe to source into the application.  Currently unused.  Feel free to use it in your own directives. |\n * | `$sce.URL`          | For URLs that are safe to follow as links.  Currently unused (`<a href=` and `<img src=` sanitize their urls and don't constitute an SCE context. |\n * | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application.  Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG`, `VIDEO`, `AUDIO`, `SOURCE`, and `TRACK` (e.g. `IFRAME`, `OBJECT`, etc.)  <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. |\n * | `$sce.JS`           | For JavaScript that is safe to execute in your application's context.  Currently unused.  Feel free to use it in your own directives. |\n *\n * ## Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist} <a name=\"resourceUrlPatternItem\"></a>\n *\n *  Each element in these arrays must be one of the following:\n *\n *  - **'self'**\n *    - The special **string**, `'self'`, can be used to match against all URLs of the **same\n *      domain** as the application document using the **same protocol**.\n *  - **String** (except the special value `'self'`)\n *    - The string is matched against the full *normalized / absolute URL* of the resource\n *      being tested (substring matches are not good enough.)\n *    - There are exactly **two wildcard sequences** - `*` and `**`.  All other characters\n *      match themselves.\n *    - `*`: matches zero or more occurrences of any character other than one of the following 6\n *      characters: '`:`', '`/`', '`.`', '`?`', '`&`' and '`;`'.  It's a useful wildcard for use\n *      in a whitelist.\n *    - `**`: matches zero or more occurrences of *any* character.  As such, it's not\n *      appropriate for use in a scheme, domain, etc. as it would match too much.  (e.g.\n *      http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might\n *      not have been the intention.)  Its usage at the very end of the path is ok.  (e.g.\n *      http://foo.example.com/templates/**).\n *  - **RegExp** (*see caveat below*)\n *    - *Caveat*:  While regular expressions are powerful and offer great flexibility,  their syntax\n *      (and all the inevitable escaping) makes them *harder to maintain*.  It's easy to\n *      accidentally introduce a bug when one updates a complex expression (imho, all regexes should\n *      have good test coverage).  For instance, the use of `.` in the regex is correct only in a\n *      small number of cases.  A `.` character in the regex used when matching the scheme or a\n *      subdomain could be matched against a `:` or literal `.` that was likely not intended.   It\n *      is highly recommended to use the string patterns and only fall back to regular expressions\n *      as a last resort.\n *    - The regular expression must be an instance of RegExp (i.e. not a string.)  It is\n *      matched against the **entire** *normalized / absolute URL* of the resource being tested\n *      (even when the RegExp did not have the `^` and `$` codes.)  In addition, any flags\n *      present on the RegExp (such as multiline, global, ignoreCase) are ignored.\n *    - If you are generating your JavaScript from some other templating engine (not\n *      recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)),\n *      remember to escape your regular expression (and be aware that you might need more than\n *      one level of escaping depending on your templating engine and the way you interpolated\n *      the value.)  Do make use of your platform's escaping mechanism as it might be good\n *      enough before coding your own.  E.g. Ruby has\n *      [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape)\n *      and Python has [re.escape](http://docs.python.org/library/re.html#re.escape).\n *      Javascript lacks a similar built in function for escaping.  Take a look at Google\n *      Closure library's [goog.string.regExpEscape(s)](\n *      http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962).\n *\n * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example.\n *\n * ## Show me an example using SCE.\n *\n * <example module=\"mySceApp\" deps=\"angular-sanitize.js\" name=\"sce-service\">\n * <file name=\"index.html\">\n *   <div ng-controller=\"AppController as myCtrl\">\n *     <i ng-bind-html=\"myCtrl.explicitlyTrustedHtml\" id=\"explicitlyTrustedHtml\"></i><br><br>\n *     <b>User comments</b><br>\n *     By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when\n *     $sanitize is available.  If $sanitize isn't available, this results in an error instead of an\n *     exploit.\n *     <div class=\"well\">\n *       <div ng-repeat=\"userComment in myCtrl.userComments\">\n *         <b>{{userComment.name}}</b>:\n *         <span ng-bind-html=\"userComment.htmlComment\" class=\"htmlComment\"></span>\n *         <br>\n *       </div>\n *     </div>\n *   </div>\n * </file>\n *\n * <file name=\"script.js\">\n *   angular.module('mySceApp', ['ngSanitize'])\n *     .controller('AppController', ['$http', '$templateCache', '$sce',\n *       function AppController($http, $templateCache, $sce) {\n *         var self = this;\n *         $http.get('test_data.json', {cache: $templateCache}).then(function(response) {\n *           self.userComments = response.data;\n *         });\n *         self.explicitlyTrustedHtml = $sce.trustAsHtml(\n *             '<span onmouseover=\"this.textContent=&quot;Explicitly trusted HTML bypasses ' +\n *             'sanitization.&quot;\">Hover over this text.</span>');\n *       }]);\n * </file>\n *\n * <file name=\"test_data.json\">\n * [\n *   { \"name\": \"Alice\",\n *     \"htmlComment\":\n *         \"<span onmouseover='this.textContent=\\\"PWN3D!\\\"'>Is <i>anyone</i> reading this?</span>\"\n *   },\n *   { \"name\": \"Bob\",\n *     \"htmlComment\": \"<i>Yes!</i>  Am I the only other one?\"\n *   }\n * ]\n * </file>\n *\n * <file name=\"protractor.js\" type=\"protractor\">\n *   describe('SCE doc demo', function() {\n *     it('should sanitize untrusted values', function() {\n *       expect(element.all(by.css('.htmlComment')).first().getAttribute('innerHTML'))\n *           .toBe('<span>Is <i>anyone</i> reading this?</span>');\n *     });\n *\n *     it('should NOT sanitize explicitly trusted values', function() {\n *       expect(element(by.id('explicitlyTrustedHtml')).getAttribute('innerHTML')).toBe(\n *           '<span onmouseover=\"this.textContent=&quot;Explicitly trusted HTML bypasses ' +\n *           'sanitization.&quot;\">Hover over this text.</span>');\n *     });\n *   });\n * </file>\n * </example>\n *\n *\n *\n * ## Can I disable SCE completely?\n *\n * Yes, you can.  However, this is strongly discouraged.  SCE gives you a lot of security benefits\n * for little coding overhead.  It will be much harder to take an SCE disabled application and\n * either secure it on your own or enable SCE at a later stage.  It might make sense to disable SCE\n * for cases where you have a lot of existing code that was written before SCE was introduced and\n * you're migrating them a module at a time.\n *\n * That said, here's how you can completely disable SCE:\n *\n * ```\n * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {\n *   // Completely disable SCE.  For demonstration purposes only!\n *   // Do not use in new projects.\n *   $sceProvider.enabled(false);\n * });\n * ```\n *\n */\n\nfunction $SceProvider() {\n  var enabled = true;\n\n  /**\n   * @ngdoc method\n   * @name $sceProvider#enabled\n   * @kind function\n   *\n   * @param {boolean=} value If provided, then enables/disables SCE.\n   * @return {boolean} true if SCE is enabled, false otherwise.\n   *\n   * @description\n   * Enables/disables SCE and returns the current value.\n   */\n  this.enabled = function(value) {\n    if (arguments.length) {\n      enabled = !!value;\n    }\n    return enabled;\n  };\n\n\n  /* Design notes on the default implementation for SCE.\n   *\n   * The API contract for the SCE delegate\n   * -------------------------------------\n   * The SCE delegate object must provide the following 3 methods:\n   *\n   * - trustAs(contextEnum, value)\n   *     This method is used to tell the SCE service that the provided value is OK to use in the\n   *     contexts specified by contextEnum.  It must return an object that will be accepted by\n   *     getTrusted() for a compatible contextEnum and return this value.\n   *\n   * - valueOf(value)\n   *     For values that were not produced by trustAs(), return them as is.  For values that were\n   *     produced by trustAs(), return the corresponding input value to trustAs.  Basically, if\n   *     trustAs is wrapping the given values into some type, this operation unwraps it when given\n   *     such a value.\n   *\n   * - getTrusted(contextEnum, value)\n   *     This function should return the a value that is safe to use in the context specified by\n   *     contextEnum or throw and exception otherwise.\n   *\n   * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be\n   * opaque or wrapped in some holder object.  That happens to be an implementation detail.  For\n   * instance, an implementation could maintain a registry of all trusted objects by context.  In\n   * such a case, trustAs() would return the same object that was passed in.  getTrusted() would\n   * return the same object passed in if it was found in the registry under a compatible context or\n   * throw an exception otherwise.  An implementation might only wrap values some of the time based\n   * on some criteria.  getTrusted() might return a value and not throw an exception for special\n   * constants or objects even if not wrapped.  All such implementations fulfill this contract.\n   *\n   *\n   * A note on the inheritance model for SCE contexts\n   * ------------------------------------------------\n   * I've used inheritance and made RESOURCE_URL wrapped types a subtype of URL wrapped types.  This\n   * is purely an implementation details.\n   *\n   * The contract is simply this:\n   *\n   *     getTrusted($sce.RESOURCE_URL, value) succeeding implies that getTrusted($sce.URL, value)\n   *     will also succeed.\n   *\n   * Inheritance happens to capture this in a natural way.  In some future, we\n   * may not use inheritance anymore.  That is OK because no code outside of\n   * sce.js and sceSpecs.js would need to be aware of this detail.\n   */\n\n  this.$get = ['$parse', '$sceDelegate', function(\n                $parse,   $sceDelegate) {\n    // Support: IE 9-11 only\n    // Prereq: Ensure that we're not running in IE<11 quirks mode.  In that mode, IE < 11 allow\n    // the \"expression(javascript expression)\" syntax which is insecure.\n    if (enabled && msie < 8) {\n      throw $sceMinErr('iequirks',\n        'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' +\n        'mode.  You can fix this by adding the text <!doctype html> to the top of your HTML ' +\n        'document.  See http://docs.angularjs.org/api/ng.$sce for more information.');\n    }\n\n    var sce = shallowCopy(SCE_CONTEXTS);\n\n    /**\n     * @ngdoc method\n     * @name $sce#isEnabled\n     * @kind function\n     *\n     * @return {Boolean} true if SCE is enabled, false otherwise.  If you want to set the value, you\n     * have to do it at module config time on {@link ng.$sceProvider $sceProvider}.\n     *\n     * @description\n     * Returns a boolean indicating if SCE is enabled.\n     */\n    sce.isEnabled = function() {\n      return enabled;\n    };\n    sce.trustAs = $sceDelegate.trustAs;\n    sce.getTrusted = $sceDelegate.getTrusted;\n    sce.valueOf = $sceDelegate.valueOf;\n\n    if (!enabled) {\n      sce.trustAs = sce.getTrusted = function(type, value) { return value; };\n      sce.valueOf = identity;\n    }\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAs\n     *\n     * @description\n     * Converts Angular {@link guide/expression expression} into a function.  This is like {@link\n     * ng.$parse $parse} and is identical when the expression is a literal constant.  Otherwise, it\n     * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*,\n     * *result*)}\n     *\n     * @param {string} type The kind of SCE context in which this result will be used.\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n    sce.parseAs = function sceParseAs(type, expr) {\n      var parsed = $parse(expr);\n      if (parsed.literal && parsed.constant) {\n        return parsed;\n      } else {\n        return $parse(expr, function(value) {\n          return sce.getTrusted(type, value);\n        });\n      }\n    };\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAs\n     *\n     * @description\n     * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.  As such,\n     * returns an object that is trusted by angular for use in specified strict contextual\n     * escaping contexts (such as ng-bind-html, ng-include, any src attribute\n     * interpolation, any dom event binding attribute interpolation such as for onclick,  etc.)\n     * that uses the provided value.  See * {@link ng.$sce $sce} for enabling strict contextual\n     * escaping.\n     *\n     * @param {string} type The kind of context in which this value is safe for use.  e.g. url,\n     *   resourceUrl, html, js and css.\n     * @param {*} value The value that that should be considered trusted/safe.\n     * @returns {*} A value that can be used to stand in for the provided `value` in places\n     * where Angular expects a $sce.trustAs() return value.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAsHtml\n     *\n     * @description\n     * Shorthand method.  `$sce.trustAsHtml(value)` →\n     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`}\n     *\n     * @param {*} value The value to trustAs.\n     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedHtml\n     *     $sce.getTrustedHtml(value)} to obtain the original value.  (privileged directives\n     *     only accept expressions that are either literal constants or are the\n     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAsUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.trustAsUrl(value)` →\n     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`}\n     *\n     * @param {*} value The value to trustAs.\n     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedUrl\n     *     $sce.getTrustedUrl(value)} to obtain the original value.  (privileged directives\n     *     only accept expressions that are either literal constants or are the\n     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAsResourceUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.trustAsResourceUrl(value)` →\n     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`}\n     *\n     * @param {*} value The value to trustAs.\n     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedResourceUrl\n     *     $sce.getTrustedResourceUrl(value)} to obtain the original value.  (privileged directives\n     *     only accept expressions that are either literal constants or are the return\n     *     value of {@link ng.$sce#trustAs $sce.trustAs}.)\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#trustAsJs\n     *\n     * @description\n     * Shorthand method.  `$sce.trustAsJs(value)` →\n     *     {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`}\n     *\n     * @param {*} value The value to trustAs.\n     * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedJs\n     *     $sce.getTrustedJs(value)} to obtain the original value.  (privileged directives\n     *     only accept expressions that are either literal constants or are the\n     *     return value of {@link ng.$sce#trustAs $sce.trustAs}.)\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrusted\n     *\n     * @description\n     * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}.  As such,\n     * takes the result of a {@link ng.$sce#trustAs `$sce.trustAs`}() call and returns the\n     * originally supplied value if the queried context type is a supertype of the created type.\n     * If this condition isn't satisfied, throws an exception.\n     *\n     * @param {string} type The kind of context in which this value is to be used.\n     * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs `$sce.trustAs`}\n     *                         call.\n     * @returns {*} The value the was originally provided to\n     *              {@link ng.$sce#trustAs `$sce.trustAs`} if valid in this context.\n     *              Otherwise, throws an exception.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedHtml\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedHtml(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`}\n     *\n     * @param {*} value The value to pass to `$sce.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.HTML, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedCss\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedCss(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`}\n     *\n     * @param {*} value The value to pass to `$sce.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.CSS, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedUrl(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`}\n     *\n     * @param {*} value The value to pass to `$sce.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.URL, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedResourceUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedResourceUrl(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`}\n     *\n     * @param {*} value The value to pass to `$sceDelegate.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#getTrustedJs\n     *\n     * @description\n     * Shorthand method.  `$sce.getTrustedJs(value)` →\n     *     {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`}\n     *\n     * @param {*} value The value to pass to `$sce.getTrusted`.\n     * @returns {*} The return value of `$sce.getTrusted($sce.JS, value)`\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsHtml\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsHtml(expression string)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.HTML, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsCss\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsCss(value)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.CSS, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsUrl(value)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.URL, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsResourceUrl\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsResourceUrl(value)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.RESOURCE_URL, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    /**\n     * @ngdoc method\n     * @name $sce#parseAsJs\n     *\n     * @description\n     * Shorthand method.  `$sce.parseAsJs(value)` →\n     *     {@link ng.$sce#parseAs `$sce.parseAs($sce.JS, value)`}\n     *\n     * @param {string} expression String expression to compile.\n     * @returns {function(context, locals)} a function which represents the compiled expression:\n     *\n     *    * `context` – `{object}` – an object against which any expressions embedded in the strings\n     *      are evaluated against (typically a scope object).\n     *    * `locals` – `{object=}` – local variables context object, useful for overriding values in\n     *      `context`.\n     */\n\n    // Shorthand delegations.\n    var parse = sce.parseAs,\n        getTrusted = sce.getTrusted,\n        trustAs = sce.trustAs;\n\n    forEach(SCE_CONTEXTS, function(enumValue, name) {\n      var lName = lowercase(name);\n      sce[snakeToCamel('parse_as_' + lName)] = function(expr) {\n        return parse(enumValue, expr);\n      };\n      sce[snakeToCamel('get_trusted_' + lName)] = function(value) {\n        return getTrusted(enumValue, value);\n      };\n      sce[snakeToCamel('trust_as_' + lName)] = function(value) {\n        return trustAs(enumValue, value);\n      };\n    });\n\n    return sce;\n  }];\n}\n\n/* exported $SnifferProvider */\n\n/**\n * !!! This is an undocumented \"private\" service !!!\n *\n * @name $sniffer\n * @requires $window\n * @requires $document\n * @this\n *\n * @property {boolean} history Does the browser support html5 history api ?\n * @property {boolean} transitions Does the browser support CSS transition events ?\n * @property {boolean} animations Does the browser support CSS animation events ?\n *\n * @description\n * This is very simple implementation of testing browser's features.\n */\nfunction $SnifferProvider() {\n  this.$get = ['$window', '$document', function($window, $document) {\n    var eventSupport = {},\n        // Chrome Packaged Apps are not allowed to access `history.pushState`.\n        // If not sandboxed, they can be detected by the presence of `chrome.app.runtime`\n        // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by\n        // the presence of an extension runtime ID and the absence of other Chrome runtime APIs\n        // (see https://developer.chrome.com/apps/manifest/sandbox).\n        // (NW.js apps have access to Chrome APIs, but do support `history`.)\n        isNw = $window.nw && $window.nw.process,\n        isChromePackagedApp =\n            !isNw &&\n            $window.chrome &&\n            ($window.chrome.app && $window.chrome.app.runtime ||\n                !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id),\n        hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState,\n        android =\n          toInt((/android (\\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),\n        boxee = /Boxee/i.test(($window.navigator || {}).userAgent),\n        document = $document[0] || {},\n        bodyStyle = document.body && document.body.style,\n        transitions = false,\n        animations = false;\n\n    if (bodyStyle) {\n      // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x\n      // Mentioned browsers need a -webkit- prefix for transitions & animations.\n      transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle);\n      animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle);\n    }\n\n\n    return {\n      // Android has history.pushState, but it does not update location correctly\n      // so let's not use the history API at all.\n      // http://code.google.com/p/android/issues/detail?id=17471\n      // https://github.com/angular/angular.js/issues/904\n\n      // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has\n      // so let's not use the history API also\n      // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined\n      history: !!(hasHistoryPushState && !(android < 4) && !boxee),\n      hasEvent: function(event) {\n        // Support: IE 9-11 only\n        // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have\n        // it. In particular the event is not fired when backspace or delete key are pressed or\n        // when cut operation is performed.\n        // IE10+ implements 'input' event but it erroneously fires under various situations,\n        // e.g. when placeholder changes, or a form is focused.\n        if (event === 'input' && msie) return false;\n\n        if (isUndefined(eventSupport[event])) {\n          var divElm = document.createElement('div');\n          eventSupport[event] = 'on' + event in divElm;\n        }\n\n        return eventSupport[event];\n      },\n      csp: csp(),\n      transitions: transitions,\n      animations: animations,\n      android: android\n    };\n  }];\n}\n\nvar $templateRequestMinErr = minErr('$compile');\n\n/**\n * @ngdoc provider\n * @name $templateRequestProvider\n * @this\n *\n * @description\n * Used to configure the options passed to the {@link $http} service when making a template request.\n *\n * For example, it can be used for specifying the \"Accept\" header that is sent to the server, when\n * requesting a template.\n */\nfunction $TemplateRequestProvider() {\n\n  var httpOptions;\n\n  /**\n   * @ngdoc method\n   * @name $templateRequestProvider#httpOptions\n   * @description\n   * The options to be passed to the {@link $http} service when making the request.\n   * You can use this to override options such as the \"Accept\" header for template requests.\n   *\n   * The {@link $templateRequest} will set the `cache` and the `transformResponse` properties of the\n   * options if not overridden here.\n   *\n   * @param {string=} value new value for the {@link $http} options.\n   * @returns {string|self} Returns the {@link $http} options when used as getter and self if used as setter.\n   */\n  this.httpOptions = function(val) {\n    if (val) {\n      httpOptions = val;\n      return this;\n    }\n    return httpOptions;\n  };\n\n  /**\n   * @ngdoc service\n   * @name $templateRequest\n   *\n   * @description\n   * The `$templateRequest` service runs security checks then downloads the provided template using\n   * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request\n   * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the\n   * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the\n   * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted\n   * when `tpl` is of type string and `$templateCache` has the matching entry.\n   *\n   * If you want to pass custom options to the `$http` service, such as setting the Accept header you\n   * can configure this via {@link $templateRequestProvider#httpOptions}.\n   *\n   * @param {string|TrustedResourceUrl} tpl The HTTP request template URL\n   * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty\n   *\n   * @return {Promise} a promise for the HTTP response data of the given URL.\n   *\n   * @property {number} totalPendingRequests total amount of pending template requests being downloaded.\n   */\n  this.$get = ['$exceptionHandler', '$templateCache', '$http', '$q', '$sce',\n    function($exceptionHandler, $templateCache, $http, $q, $sce) {\n\n      function handleRequestFn(tpl, ignoreRequestError) {\n        handleRequestFn.totalPendingRequests++;\n\n        // We consider the template cache holds only trusted templates, so\n        // there's no need to go through whitelisting again for keys that already\n        // are included in there. This also makes Angular accept any script\n        // directive, no matter its name. However, we still need to unwrap trusted\n        // types.\n        if (!isString(tpl) || isUndefined($templateCache.get(tpl))) {\n          tpl = $sce.getTrustedResourceUrl(tpl);\n        }\n\n        var transformResponse = $http.defaults && $http.defaults.transformResponse;\n\n        if (isArray(transformResponse)) {\n          transformResponse = transformResponse.filter(function(transformer) {\n            return transformer !== defaultHttpResponseTransform;\n          });\n        } else if (transformResponse === defaultHttpResponseTransform) {\n          transformResponse = null;\n        }\n\n        return $http.get(tpl, extend({\n            cache: $templateCache,\n            transformResponse: transformResponse\n          }, httpOptions))\n          .finally(function() {\n            handleRequestFn.totalPendingRequests--;\n          })\n          .then(function(response) {\n            $templateCache.put(tpl, response.data);\n            return response.data;\n          }, handleError);\n\n        function handleError(resp) {\n          if (!ignoreRequestError) {\n            resp = $templateRequestMinErr('tpload',\n                'Failed to load template: {0} (HTTP status: {1} {2})',\n                tpl, resp.status, resp.statusText);\n\n            $exceptionHandler(resp);\n          }\n\n          return $q.reject(resp);\n        }\n      }\n\n      handleRequestFn.totalPendingRequests = 0;\n\n      return handleRequestFn;\n    }\n  ];\n}\n\n/** @this */\nfunction $$TestabilityProvider() {\n  this.$get = ['$rootScope', '$browser', '$location',\n       function($rootScope,   $browser,   $location) {\n\n    /**\n     * @name $testability\n     *\n     * @description\n     * The private $$testability service provides a collection of methods for use when debugging\n     * or by automated test and debugging tools.\n     */\n    var testability = {};\n\n    /**\n     * @name $$testability#findBindings\n     *\n     * @description\n     * Returns an array of elements that are bound (via ng-bind or {{}})\n     * to expressions matching the input.\n     *\n     * @param {Element} element The element root to search from.\n     * @param {string} expression The binding expression to match.\n     * @param {boolean} opt_exactMatch If true, only returns exact matches\n     *     for the expression. Filters and whitespace are ignored.\n     */\n    testability.findBindings = function(element, expression, opt_exactMatch) {\n      var bindings = element.getElementsByClassName('ng-binding');\n      var matches = [];\n      forEach(bindings, function(binding) {\n        var dataBinding = angular.element(binding).data('$binding');\n        if (dataBinding) {\n          forEach(dataBinding, function(bindingName) {\n            if (opt_exactMatch) {\n              var matcher = new RegExp('(^|\\\\s)' + escapeForRegexp(expression) + '(\\\\s|\\\\||$)');\n              if (matcher.test(bindingName)) {\n                matches.push(binding);\n              }\n            } else {\n              if (bindingName.indexOf(expression) !== -1) {\n                matches.push(binding);\n              }\n            }\n          });\n        }\n      });\n      return matches;\n    };\n\n    /**\n     * @name $$testability#findModels\n     *\n     * @description\n     * Returns an array of elements that are two-way found via ng-model to\n     * expressions matching the input.\n     *\n     * @param {Element} element The element root to search from.\n     * @param {string} expression The model expression to match.\n     * @param {boolean} opt_exactMatch If true, only returns exact matches\n     *     for the expression.\n     */\n    testability.findModels = function(element, expression, opt_exactMatch) {\n      var prefixes = ['ng-', 'data-ng-', 'ng\\\\:'];\n      for (var p = 0; p < prefixes.length; ++p) {\n        var attributeEquals = opt_exactMatch ? '=' : '*=';\n        var selector = '[' + prefixes[p] + 'model' + attributeEquals + '\"' + expression + '\"]';\n        var elements = element.querySelectorAll(selector);\n        if (elements.length) {\n          return elements;\n        }\n      }\n    };\n\n    /**\n     * @name $$testability#getLocation\n     *\n     * @description\n     * Shortcut for getting the location in a browser agnostic way. Returns\n     *     the path, search, and hash. (e.g. /path?a=b#hash)\n     */\n    testability.getLocation = function() {\n      return $location.url();\n    };\n\n    /**\n     * @name $$testability#setLocation\n     *\n     * @description\n     * Shortcut for navigating to a location without doing a full page reload.\n     *\n     * @param {string} url The location url (path, search and hash,\n     *     e.g. /path?a=b#hash) to go to.\n     */\n    testability.setLocation = function(url) {\n      if (url !== $location.url()) {\n        $location.url(url);\n        $rootScope.$digest();\n      }\n    };\n\n    /**\n     * @name $$testability#whenStable\n     *\n     * @description\n     * Calls the callback when $timeout and $http requests are completed.\n     *\n     * @param {function} callback\n     */\n    testability.whenStable = function(callback) {\n      $browser.notifyWhenNoOutstandingRequests(callback);\n    };\n\n    return testability;\n  }];\n}\n\n/** @this */\nfunction $TimeoutProvider() {\n  this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',\n       function($rootScope,   $browser,   $q,   $$q,   $exceptionHandler) {\n\n    var deferreds = {};\n\n\n     /**\n      * @ngdoc service\n      * @name $timeout\n      *\n      * @description\n      * Angular's wrapper for `window.setTimeout`. The `fn` function is wrapped into a try/catch\n      * block and delegates any exceptions to\n      * {@link ng.$exceptionHandler $exceptionHandler} service.\n      *\n      * The return value of calling `$timeout` is a promise, which will be resolved when\n      * the delay has passed and the timeout function, if provided, is executed.\n      *\n      * To cancel a timeout request, call `$timeout.cancel(promise)`.\n      *\n      * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to\n      * synchronously flush the queue of deferred functions.\n      *\n      * If you only want a promise that will be resolved after some specified delay\n      * then you can call `$timeout` without the `fn` function.\n      *\n      * @param {function()=} fn A function, whose execution should be delayed.\n      * @param {number=} [delay=0] Delay in milliseconds.\n      * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise\n      *   will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.\n      * @param {...*=} Pass additional parameters to the executed function.\n      * @returns {Promise} Promise that will be resolved when the timeout is reached. The promise\n      *   will be resolved with the return value of the `fn` function.\n      *\n      */\n    function timeout(fn, delay, invokeApply) {\n      if (!isFunction(fn)) {\n        invokeApply = delay;\n        delay = fn;\n        fn = noop;\n      }\n\n      var args = sliceArgs(arguments, 3),\n          skipApply = (isDefined(invokeApply) && !invokeApply),\n          deferred = (skipApply ? $$q : $q).defer(),\n          promise = deferred.promise,\n          timeoutId;\n\n      timeoutId = $browser.defer(function() {\n        try {\n          deferred.resolve(fn.apply(null, args));\n        } catch (e) {\n          deferred.reject(e);\n          $exceptionHandler(e);\n        } finally {\n          delete deferreds[promise.$$timeoutId];\n        }\n\n        if (!skipApply) $rootScope.$apply();\n      }, delay);\n\n      promise.$$timeoutId = timeoutId;\n      deferreds[timeoutId] = deferred;\n\n      return promise;\n    }\n\n\n     /**\n      * @ngdoc method\n      * @name $timeout#cancel\n      *\n      * @description\n      * Cancels a task associated with the `promise`. As a result of this, the promise will be\n      * resolved with a rejection.\n      *\n      * @param {Promise=} promise Promise returned by the `$timeout` function.\n      * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully\n      *   canceled.\n      */\n    timeout.cancel = function(promise) {\n      if (promise && promise.$$timeoutId in deferreds) {\n        // Timeout cancels should not report an unhandled promise.\n        deferreds[promise.$$timeoutId].promise.catch(noop);\n        deferreds[promise.$$timeoutId].reject('canceled');\n        delete deferreds[promise.$$timeoutId];\n        return $browser.defer.cancel(promise.$$timeoutId);\n      }\n      return false;\n    };\n\n    return timeout;\n  }];\n}\n\n// NOTE:  The usage of window and document instead of $window and $document here is\n// deliberate.  This service depends on the specific behavior of anchor nodes created by the\n// browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and\n// cause us to break tests.  In addition, when the browser resolves a URL for XHR, it\n// doesn't know about mocked locations and resolves URLs to the real document - which is\n// exactly the behavior needed here.  There is little value is mocking these out for this\n// service.\nvar urlParsingNode = window.document.createElement('a');\nvar originUrl = urlResolve(window.location.href);\n\n\n/**\n *\n * Implementation Notes for non-IE browsers\n * ----------------------------------------\n * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,\n * results both in the normalizing and parsing of the URL.  Normalizing means that a relative\n * URL will be resolved into an absolute URL in the context of the application document.\n * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related\n * properties are all populated to reflect the normalized URL.  This approach has wide\n * compatibility - Safari 1+, Mozilla 1+ etc.  See\n * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *\n * Implementation Notes for IE\n * ---------------------------\n * IE <= 10 normalizes the URL when assigned to the anchor node similar to the other\n * browsers.  However, the parsed components will not be set if the URL assigned did not specify\n * them.  (e.g. if you assign a.href = \"foo\", then a.protocol, a.host, etc. will be empty.)  We\n * work around that by performing the parsing in a 2nd step by taking a previously normalized\n * URL (e.g. by assigning to a.href) and assigning it a.href again.  This correctly populates the\n * properties such as protocol, hostname, port, etc.\n *\n * References:\n *   http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement\n *   http://www.aptana.com/reference/html/api/HTMLAnchorElement.html\n *   http://url.spec.whatwg.org/#urlutils\n *   https://github.com/angular/angular.js/pull/2902\n *   http://james.padolsey.com/javascript/parsing-urls-with-the-dom/\n *\n * @kind function\n * @param {string} url The URL to be parsed.\n * @description Normalizes and parses a URL.\n * @returns {object} Returns the normalized URL as a dictionary.\n *\n *   | member name   | Description    |\n *   |---------------|----------------|\n *   | href          | A normalized version of the provided URL if it was not an absolute URL |\n *   | protocol      | The protocol including the trailing colon                              |\n *   | host          | The host and port (if the port is non-default) of the normalizedUrl    |\n *   | search        | The search params, minus the question mark                             |\n *   | hash          | The hash string, minus the hash symbol\n *   | hostname      | The hostname\n *   | port          | The port, without \":\"\n *   | pathname      | The pathname, beginning with \"/\"\n *\n */\nfunction urlResolve(url) {\n  var href = url;\n\n  // Support: IE 9-11 only\n  if (msie) {\n    // Normalize before parse.  Refer Implementation Notes on why this is\n    // done in two steps on IE.\n    urlParsingNode.setAttribute('href', href);\n    href = urlParsingNode.href;\n  }\n\n  urlParsingNode.setAttribute('href', href);\n\n  // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n  return {\n    href: urlParsingNode.href,\n    protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n    host: urlParsingNode.host,\n    search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n    hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n    hostname: urlParsingNode.hostname,\n    port: urlParsingNode.port,\n    pathname: (urlParsingNode.pathname.charAt(0) === '/')\n      ? urlParsingNode.pathname\n      : '/' + urlParsingNode.pathname\n  };\n}\n\n/**\n * Parse a request URL and determine whether this is a same-origin request as the application document.\n *\n * @param {string|object} requestUrl The url of the request as a string that will be resolved\n * or a parsed URL object.\n * @returns {boolean} Whether the request is for the same origin as the application document.\n */\nfunction urlIsSameOrigin(requestUrl) {\n  var parsed = (isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl;\n  return (parsed.protocol === originUrl.protocol &&\n          parsed.host === originUrl.host);\n}\n\n/**\n * @ngdoc service\n * @name $window\n * @this\n *\n * @description\n * A reference to the browser's `window` object. While `window`\n * is globally available in JavaScript, it causes testability problems, because\n * it is a global variable. In angular we always refer to it through the\n * `$window` service, so it may be overridden, removed or mocked for testing.\n *\n * Expressions, like the one defined for the `ngClick` directive in the example\n * below, are evaluated with respect to the current scope.  Therefore, there is\n * no risk of inadvertently coding in a dependency on a global value in such an\n * expression.\n *\n * @example\n   <example module=\"windowExample\" name=\"window-service\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('windowExample', [])\n           .controller('ExampleController', ['$scope', '$window', function($scope, $window) {\n             $scope.greeting = 'Hello, World!';\n             $scope.doGreeting = function(greeting) {\n               $window.alert(greeting);\n             };\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <input type=\"text\" ng-model=\"greeting\" aria-label=\"greeting\" />\n         <button ng-click=\"doGreeting(greeting)\">ALERT</button>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n      it('should display the greeting in the input box', function() {\n       element(by.model('greeting')).sendKeys('Hello, E2E Tests');\n       // If we click the button it will block the test runner\n       // element(':button').click();\n      });\n     </file>\n   </example>\n */\nfunction $WindowProvider() {\n  this.$get = valueFn(window);\n}\n\n/**\n * @name $$cookieReader\n * @requires $document\n *\n * @description\n * This is a private service for reading cookies used by $http and ngCookies\n *\n * @return {Object} a key/value map of the current cookies\n */\nfunction $$CookieReader($document) {\n  var rawDocument = $document[0] || {};\n  var lastCookies = {};\n  var lastCookieString = '';\n\n  function safeGetCookie(rawDocument) {\n    try {\n      return rawDocument.cookie || '';\n    } catch (e) {\n      return '';\n    }\n  }\n\n  function safeDecodeURIComponent(str) {\n    try {\n      return decodeURIComponent(str);\n    } catch (e) {\n      return str;\n    }\n  }\n\n  return function() {\n    var cookieArray, cookie, i, index, name;\n    var currentCookieString = safeGetCookie(rawDocument);\n\n    if (currentCookieString !== lastCookieString) {\n      lastCookieString = currentCookieString;\n      cookieArray = lastCookieString.split('; ');\n      lastCookies = {};\n\n      for (i = 0; i < cookieArray.length; i++) {\n        cookie = cookieArray[i];\n        index = cookie.indexOf('=');\n        if (index > 0) { //ignore nameless cookies\n          name = safeDecodeURIComponent(cookie.substring(0, index));\n          // the first value that is seen for a cookie is the most\n          // specific one.  values for the same cookie name that\n          // follow are for less specific paths.\n          if (isUndefined(lastCookies[name])) {\n            lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));\n          }\n        }\n      }\n    }\n    return lastCookies;\n  };\n}\n\n$$CookieReader.$inject = ['$document'];\n\n/** @this */\nfunction $$CookieReaderProvider() {\n  this.$get = $$CookieReader;\n}\n\n/* global currencyFilter: true,\n dateFilter: true,\n filterFilter: true,\n jsonFilter: true,\n limitToFilter: true,\n lowercaseFilter: true,\n numberFilter: true,\n orderByFilter: true,\n uppercaseFilter: true,\n */\n\n/**\n * @ngdoc provider\n * @name $filterProvider\n * @description\n *\n * Filters are just functions which transform input to an output. However filters need to be\n * Dependency Injected. To achieve this a filter definition consists of a factory function which is\n * annotated with dependencies and is responsible for creating a filter function.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.\n * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace\n * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores\n * (`myapp_subsection_filterx`).\n * </div>\n *\n * ```js\n *   // Filter registration\n *   function MyModule($provide, $filterProvider) {\n *     // create a service to demonstrate injection (not always needed)\n *     $provide.value('greet', function(name){\n *       return 'Hello ' + name + '!';\n *     });\n *\n *     // register a filter factory which uses the\n *     // greet service to demonstrate DI.\n *     $filterProvider.register('greet', function(greet){\n *       // return the filter function which uses the greet service\n *       // to generate salutation\n *       return function(text) {\n *         // filters need to be forgiving so check input validity\n *         return text && greet(text) || text;\n *       };\n *     });\n *   }\n * ```\n *\n * The filter function is registered with the `$injector` under the filter name suffix with\n * `Filter`.\n *\n * ```js\n *   it('should be the same instance', inject(\n *     function($filterProvider) {\n *       $filterProvider.register('reverse', function(){\n *         return ...;\n *       });\n *     },\n *     function($filter, reverseFilter) {\n *       expect($filter('reverse')).toBe(reverseFilter);\n *     });\n * ```\n *\n *\n * For more information about how angular filters work, and how to create your own filters, see\n * {@link guide/filter Filters} in the Angular Developer Guide.\n */\n\n/**\n * @ngdoc service\n * @name $filter\n * @kind function\n * @description\n * Filters are used for formatting data displayed to the user.\n *\n * They can be used in view templates, controllers or services.Angular comes\n * with a collection of [built-in filters](api/ng/filter), but it is easy to\n * define your own as well.\n *\n * The general syntax in templates is as follows:\n *\n * ```html\n * {{ expression [| filter_name[:parameter_value] ... ] }}\n * ```\n *\n * @param {String} name Name of the filter function to retrieve\n * @return {Function} the filter function\n * @example\n   <example name=\"$filter\" module=\"filterExample\">\n     <file name=\"index.html\">\n       <div ng-controller=\"MainCtrl\">\n        <h3>{{ originalText }}</h3>\n        <h3>{{ filteredText }}</h3>\n       </div>\n     </file>\n\n     <file name=\"script.js\">\n      angular.module('filterExample', [])\n      .controller('MainCtrl', function($scope, $filter) {\n        $scope.originalText = 'hello';\n        $scope.filteredText = $filter('uppercase')($scope.originalText);\n      });\n     </file>\n   </example>\n  */\n$FilterProvider.$inject = ['$provide'];\n/** @this */\nfunction $FilterProvider($provide) {\n  var suffix = 'Filter';\n\n  /**\n   * @ngdoc method\n   * @name $filterProvider#register\n   * @param {string|Object} name Name of the filter function, or an object map of filters where\n   *    the keys are the filter names and the values are the filter factories.\n   *\n   *    <div class=\"alert alert-warning\">\n   *    **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.\n   *    Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace\n   *    your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores\n   *    (`myapp_subsection_filterx`).\n   *    </div>\n    * @param {Function} factory If the first argument was a string, a factory function for the filter to be registered.\n   * @returns {Object} Registered filter instance, or if a map of filters was provided then a map\n   *    of the registered filter instances.\n   */\n  function register(name, factory) {\n    if (isObject(name)) {\n      var filters = {};\n      forEach(name, function(filter, key) {\n        filters[key] = register(key, filter);\n      });\n      return filters;\n    } else {\n      return $provide.factory(name + suffix, factory);\n    }\n  }\n  this.register = register;\n\n  this.$get = ['$injector', function($injector) {\n    return function(name) {\n      return $injector.get(name + suffix);\n    };\n  }];\n\n  ////////////////////////////////////////\n\n  /* global\n    currencyFilter: false,\n    dateFilter: false,\n    filterFilter: false,\n    jsonFilter: false,\n    limitToFilter: false,\n    lowercaseFilter: false,\n    numberFilter: false,\n    orderByFilter: false,\n    uppercaseFilter: false\n  */\n\n  register('currency', currencyFilter);\n  register('date', dateFilter);\n  register('filter', filterFilter);\n  register('json', jsonFilter);\n  register('limitTo', limitToFilter);\n  register('lowercase', lowercaseFilter);\n  register('number', numberFilter);\n  register('orderBy', orderByFilter);\n  register('uppercase', uppercaseFilter);\n}\n\n/**\n * @ngdoc filter\n * @name filter\n * @kind function\n *\n * @description\n * Selects a subset of items from `array` and returns it as a new array.\n *\n * @param {Array} array The source array.\n * <div class=\"alert alert-info\">\n *   **Note**: If the array contains objects that reference themselves, filtering is not possible.\n * </div>\n * @param {string|Object|function()} expression The predicate to be used for selecting items from\n *   `array`.\n *\n *   Can be one of:\n *\n *   - `string`: The string is used for matching against the contents of the `array`. All strings or\n *     objects with string properties in `array` that match this string will be returned. This also\n *     applies to nested object properties.\n *     The predicate can be negated by prefixing the string with `!`.\n *\n *   - `Object`: A pattern object can be used to filter specific properties on objects contained\n *     by `array`. For example `{name:\"M\", phone:\"1\"}` predicate will return an array of items\n *     which have property `name` containing \"M\" and property `phone` containing \"1\". A special\n *     property name (`$` by default) can be used (e.g. as in `{$: \"text\"}`) to accept a match\n *     against any property of the object or its nested object properties. That's equivalent to the\n *     simple substring match with a `string` as described above. The special property name can be\n *     overwritten, using the `anyPropertyKey` parameter.\n *     The predicate can be negated by prefixing the string with `!`.\n *     For example `{name: \"!M\"}` predicate will return an array of items which have property `name`\n *     not containing \"M\".\n *\n *     Note that a named property will match properties on the same level only, while the special\n *     `$` property will match properties on the same level or deeper. E.g. an array item like\n *     `{name: {first: 'John', last: 'Doe'}}` will **not** be matched by `{name: 'John'}`, but\n *     **will** be matched by `{$: 'John'}`.\n *\n *   - `function(value, index, array)`: A predicate function can be used to write arbitrary filters.\n *     The function is called for each element of the array, with the element, its index, and\n *     the entire array itself as arguments.\n *\n *     The final result is an array of those elements that the predicate returned true for.\n *\n * @param {function(actual, expected)|true|false} [comparator] Comparator which is used in\n *     determining if the expected value (from the filter expression) and actual value (from\n *     the object in the array) should be considered a match.\n *\n *   Can be one of:\n *\n *   - `function(actual, expected)`:\n *     The function will be given the object value and the predicate value to compare and\n *     should return true if both values should be considered equal.\n *\n *   - `true`: A shorthand for `function(actual, expected) { return angular.equals(actual, expected)}`.\n *     This is essentially strict comparison of expected and actual.\n *\n *   - `false`: A short hand for a function which will look for a substring match in a case\n *     insensitive way. Primitive values are converted to strings. Objects are not compared against\n *     primitives, unless they have a custom `toString` method (e.g. `Date` objects).\n *\n *\n *   Defaults to `false`.\n *\n * @param {string} [anyPropertyKey] The special property name that matches against any property.\n *     By default `$`.\n *\n * @example\n   <example name=\"filter-filter\">\n     <file name=\"index.html\">\n       <div ng-init=\"friends = [{name:'John', phone:'555-1276'},\n                                {name:'Mary', phone:'800-BIG-MARY'},\n                                {name:'Mike', phone:'555-4321'},\n                                {name:'Adam', phone:'555-5678'},\n                                {name:'Julie', phone:'555-8765'},\n                                {name:'Juliette', phone:'555-5678'}]\"></div>\n\n       <label>Search: <input ng-model=\"searchText\"></label>\n       <table id=\"searchTextResults\">\n         <tr><th>Name</th><th>Phone</th></tr>\n         <tr ng-repeat=\"friend in friends | filter:searchText\">\n           <td>{{friend.name}}</td>\n           <td>{{friend.phone}}</td>\n         </tr>\n       </table>\n       <hr>\n       <label>Any: <input ng-model=\"search.$\"></label> <br>\n       <label>Name only <input ng-model=\"search.name\"></label><br>\n       <label>Phone only <input ng-model=\"search.phone\"></label><br>\n       <label>Equality <input type=\"checkbox\" ng-model=\"strict\"></label><br>\n       <table id=\"searchObjResults\">\n         <tr><th>Name</th><th>Phone</th></tr>\n         <tr ng-repeat=\"friendObj in friends | filter:search:strict\">\n           <td>{{friendObj.name}}</td>\n           <td>{{friendObj.phone}}</td>\n         </tr>\n       </table>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       var expectFriendNames = function(expectedNames, key) {\n         element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {\n           arr.forEach(function(wd, i) {\n             expect(wd.getText()).toMatch(expectedNames[i]);\n           });\n         });\n       };\n\n       it('should search across all fields when filtering with a string', function() {\n         var searchText = element(by.model('searchText'));\n         searchText.clear();\n         searchText.sendKeys('m');\n         expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');\n\n         searchText.clear();\n         searchText.sendKeys('76');\n         expectFriendNames(['John', 'Julie'], 'friend');\n       });\n\n       it('should search in specific fields when filtering with a predicate object', function() {\n         var searchAny = element(by.model('search.$'));\n         searchAny.clear();\n         searchAny.sendKeys('i');\n         expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');\n       });\n       it('should use a equal comparison when comparator is true', function() {\n         var searchName = element(by.model('search.name'));\n         var strict = element(by.model('strict'));\n         searchName.clear();\n         searchName.sendKeys('Julie');\n         strict.click();\n         expectFriendNames(['Julie'], 'friendObj');\n       });\n     </file>\n   </example>\n */\n\nfunction filterFilter() {\n  return function(array, expression, comparator, anyPropertyKey) {\n    if (!isArrayLike(array)) {\n      if (array == null) {\n        return array;\n      } else {\n        throw minErr('filter')('notarray', 'Expected array but received: {0}', array);\n      }\n    }\n\n    anyPropertyKey = anyPropertyKey || '$';\n    var expressionType = getTypeForFilter(expression);\n    var predicateFn;\n    var matchAgainstAnyProp;\n\n    switch (expressionType) {\n      case 'function':\n        predicateFn = expression;\n        break;\n      case 'boolean':\n      case 'null':\n      case 'number':\n      case 'string':\n        matchAgainstAnyProp = true;\n        // falls through\n      case 'object':\n        predicateFn = createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp);\n        break;\n      default:\n        return array;\n    }\n\n    return Array.prototype.filter.call(array, predicateFn);\n  };\n}\n\n// Helper functions for `filterFilter`\nfunction createPredicateFn(expression, comparator, anyPropertyKey, matchAgainstAnyProp) {\n  var shouldMatchPrimitives = isObject(expression) && (anyPropertyKey in expression);\n  var predicateFn;\n\n  if (comparator === true) {\n    comparator = equals;\n  } else if (!isFunction(comparator)) {\n    comparator = function(actual, expected) {\n      if (isUndefined(actual)) {\n        // No substring matching against `undefined`\n        return false;\n      }\n      if ((actual === null) || (expected === null)) {\n        // No substring matching against `null`; only match against `null`\n        return actual === expected;\n      }\n      if (isObject(expected) || (isObject(actual) && !hasCustomToString(actual))) {\n        // Should not compare primitives against objects, unless they have custom `toString` method\n        return false;\n      }\n\n      actual = lowercase('' + actual);\n      expected = lowercase('' + expected);\n      return actual.indexOf(expected) !== -1;\n    };\n  }\n\n  predicateFn = function(item) {\n    if (shouldMatchPrimitives && !isObject(item)) {\n      return deepCompare(item, expression[anyPropertyKey], comparator, anyPropertyKey, false);\n    }\n    return deepCompare(item, expression, comparator, anyPropertyKey, matchAgainstAnyProp);\n  };\n\n  return predicateFn;\n}\n\nfunction deepCompare(actual, expected, comparator, anyPropertyKey, matchAgainstAnyProp, dontMatchWholeObject) {\n  var actualType = getTypeForFilter(actual);\n  var expectedType = getTypeForFilter(expected);\n\n  if ((expectedType === 'string') && (expected.charAt(0) === '!')) {\n    return !deepCompare(actual, expected.substring(1), comparator, anyPropertyKey, matchAgainstAnyProp);\n  } else if (isArray(actual)) {\n    // In case `actual` is an array, consider it a match\n    // if ANY of it's items matches `expected`\n    return actual.some(function(item) {\n      return deepCompare(item, expected, comparator, anyPropertyKey, matchAgainstAnyProp);\n    });\n  }\n\n  switch (actualType) {\n    case 'object':\n      var key;\n      if (matchAgainstAnyProp) {\n        for (key in actual) {\n          // Under certain, rare, circumstances, key may not be a string and `charAt` will be undefined\n          // See: https://github.com/angular/angular.js/issues/15644\n          if (key.charAt && (key.charAt(0) !== '$') &&\n              deepCompare(actual[key], expected, comparator, anyPropertyKey, true)) {\n            return true;\n          }\n        }\n        return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, anyPropertyKey, false);\n      } else if (expectedType === 'object') {\n        for (key in expected) {\n          var expectedVal = expected[key];\n          if (isFunction(expectedVal) || isUndefined(expectedVal)) {\n            continue;\n          }\n\n          var matchAnyProperty = key === anyPropertyKey;\n          var actualVal = matchAnyProperty ? actual : actual[key];\n          if (!deepCompare(actualVal, expectedVal, comparator, anyPropertyKey, matchAnyProperty, matchAnyProperty)) {\n            return false;\n          }\n        }\n        return true;\n      } else {\n        return comparator(actual, expected);\n      }\n    case 'function':\n      return false;\n    default:\n      return comparator(actual, expected);\n  }\n}\n\n// Used for easily differentiating between `null` and actual `object`\nfunction getTypeForFilter(val) {\n  return (val === null) ? 'null' : typeof val;\n}\n\nvar MAX_DIGITS = 22;\nvar DECIMAL_SEP = '.';\nvar ZERO_CHAR = '0';\n\n/**\n * @ngdoc filter\n * @name currency\n * @kind function\n *\n * @description\n * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default\n * symbol for current locale is used.\n *\n * @param {number} amount Input to filter.\n * @param {string=} symbol Currency symbol or identifier to be displayed.\n * @param {number=} fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale\n * @returns {string} Formatted number.\n *\n *\n * @example\n   <example module=\"currencyExample\" name=\"currency-filter\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('currencyExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.amount = 1234.56;\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <input type=\"number\" ng-model=\"amount\" aria-label=\"amount\"> <br>\n         default currency symbol ($): <span id=\"currency-default\">{{amount | currency}}</span><br>\n         custom currency identifier (USD$): <span id=\"currency-custom\">{{amount | currency:\"USD$\"}}</span><br>\n         no fractions (0): <span id=\"currency-no-fractions\">{{amount | currency:\"USD$\":0}}</span>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should init with 1234.56', function() {\n         expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');\n         expect(element(by.id('currency-custom')).getText()).toBe('USD$1,234.56');\n         expect(element(by.id('currency-no-fractions')).getText()).toBe('USD$1,235');\n       });\n       it('should update', function() {\n         if (browser.params.browser === 'safari') {\n           // Safari does not understand the minus key. See\n           // https://github.com/angular/protractor/issues/481\n           return;\n         }\n         element(by.model('amount')).clear();\n         element(by.model('amount')).sendKeys('-1234');\n         expect(element(by.id('currency-default')).getText()).toBe('-$1,234.00');\n         expect(element(by.id('currency-custom')).getText()).toBe('-USD$1,234.00');\n         expect(element(by.id('currency-no-fractions')).getText()).toBe('-USD$1,234');\n       });\n     </file>\n   </example>\n */\ncurrencyFilter.$inject = ['$locale'];\nfunction currencyFilter($locale) {\n  var formats = $locale.NUMBER_FORMATS;\n  return function(amount, currencySymbol, fractionSize) {\n    if (isUndefined(currencySymbol)) {\n      currencySymbol = formats.CURRENCY_SYM;\n    }\n\n    if (isUndefined(fractionSize)) {\n      fractionSize = formats.PATTERNS[1].maxFrac;\n    }\n\n    // if null or undefined pass it through\n    return (amount == null)\n        ? amount\n        : formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize).\n            replace(/\\u00A4/g, currencySymbol);\n  };\n}\n\n/**\n * @ngdoc filter\n * @name number\n * @kind function\n *\n * @description\n * Formats a number as text.\n *\n * If the input is null or undefined, it will just be returned.\n * If the input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or '-∞' is returned, respectively.\n * If the input is not a number an empty string is returned.\n *\n *\n * @param {number|string} number Number to format.\n * @param {(number|string)=} fractionSize Number of decimal places to round the number to.\n * If this is not provided then the fraction size is computed from the current locale's number\n * formatting pattern. In the case of the default locale, it will be 3.\n * @returns {string} Number rounded to `fractionSize` appropriately formatted based on the current\n *                   locale (e.g., in the en_US locale it will have \".\" as the decimal separator and\n *                   include \",\" group separators after each third digit).\n *\n * @example\n   <example module=\"numberFilterExample\" name=\"number-filter\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('numberFilterExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.val = 1234.56789;\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <label>Enter number: <input ng-model='val'></label><br>\n         Default formatting: <span id='number-default'>{{val | number}}</span><br>\n         No fractions: <span>{{val | number:0}}</span><br>\n         Negative number: <span>{{-val | number:4}}</span>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should format numbers', function() {\n         expect(element(by.id('number-default')).getText()).toBe('1,234.568');\n         expect(element(by.binding('val | number:0')).getText()).toBe('1,235');\n         expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679');\n       });\n\n       it('should update', function() {\n         element(by.model('val')).clear();\n         element(by.model('val')).sendKeys('3374.333');\n         expect(element(by.id('number-default')).getText()).toBe('3,374.333');\n         expect(element(by.binding('val | number:0')).getText()).toBe('3,374');\n         expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330');\n      });\n     </file>\n   </example>\n */\nnumberFilter.$inject = ['$locale'];\nfunction numberFilter($locale) {\n  var formats = $locale.NUMBER_FORMATS;\n  return function(number, fractionSize) {\n\n    // if null or undefined pass it through\n    return (number == null)\n        ? number\n        : formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP,\n                       fractionSize);\n  };\n}\n\n/**\n * Parse a number (as a string) into three components that can be used\n * for formatting the number.\n *\n * (Significant bits of this parse algorithm came from https://github.com/MikeMcl/big.js/)\n *\n * @param  {string} numStr The number to parse\n * @return {object} An object describing this number, containing the following keys:\n *  - d : an array of digits containing leading zeros as necessary\n *  - i : the number of the digits in `d` that are to the left of the decimal point\n *  - e : the exponent for numbers that would need more than `MAX_DIGITS` digits in `d`\n *\n */\nfunction parse(numStr) {\n  var exponent = 0, digits, numberOfIntegerDigits;\n  var i, j, zeros;\n\n  // Decimal point?\n  if ((numberOfIntegerDigits = numStr.indexOf(DECIMAL_SEP)) > -1) {\n    numStr = numStr.replace(DECIMAL_SEP, '');\n  }\n\n  // Exponential form?\n  if ((i = numStr.search(/e/i)) > 0) {\n    // Work out the exponent.\n    if (numberOfIntegerDigits < 0) numberOfIntegerDigits = i;\n    numberOfIntegerDigits += +numStr.slice(i + 1);\n    numStr = numStr.substring(0, i);\n  } else if (numberOfIntegerDigits < 0) {\n    // There was no decimal point or exponent so it is an integer.\n    numberOfIntegerDigits = numStr.length;\n  }\n\n  // Count the number of leading zeros.\n  for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) { /* empty */ }\n\n  if (i === (zeros = numStr.length)) {\n    // The digits are all zero.\n    digits = [0];\n    numberOfIntegerDigits = 1;\n  } else {\n    // Count the number of trailing zeros\n    zeros--;\n    while (numStr.charAt(zeros) === ZERO_CHAR) zeros--;\n\n    // Trailing zeros are insignificant so ignore them\n    numberOfIntegerDigits -= i;\n    digits = [];\n    // Convert string to array of digits without leading/trailing zeros.\n    for (j = 0; i <= zeros; i++, j++) {\n      digits[j] = +numStr.charAt(i);\n    }\n  }\n\n  // If the number overflows the maximum allowed digits then use an exponent.\n  if (numberOfIntegerDigits > MAX_DIGITS) {\n    digits = digits.splice(0, MAX_DIGITS - 1);\n    exponent = numberOfIntegerDigits - 1;\n    numberOfIntegerDigits = 1;\n  }\n\n  return { d: digits, e: exponent, i: numberOfIntegerDigits };\n}\n\n/**\n * Round the parsed number to the specified number of decimal places\n * This function changed the parsedNumber in-place\n */\nfunction roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {\n    var digits = parsedNumber.d;\n    var fractionLen = digits.length - parsedNumber.i;\n\n    // determine fractionSize if it is not specified; `+fractionSize` converts it to a number\n    fractionSize = (isUndefined(fractionSize)) ? Math.min(Math.max(minFrac, fractionLen), maxFrac) : +fractionSize;\n\n    // The index of the digit to where rounding is to occur\n    var roundAt = fractionSize + parsedNumber.i;\n    var digit = digits[roundAt];\n\n    if (roundAt > 0) {\n      // Drop fractional digits beyond `roundAt`\n      digits.splice(Math.max(parsedNumber.i, roundAt));\n\n      // Set non-fractional digits beyond `roundAt` to 0\n      for (var j = roundAt; j < digits.length; j++) {\n        digits[j] = 0;\n      }\n    } else {\n      // We rounded to zero so reset the parsedNumber\n      fractionLen = Math.max(0, fractionLen);\n      parsedNumber.i = 1;\n      digits.length = Math.max(1, roundAt = fractionSize + 1);\n      digits[0] = 0;\n      for (var i = 1; i < roundAt; i++) digits[i] = 0;\n    }\n\n    if (digit >= 5) {\n      if (roundAt - 1 < 0) {\n        for (var k = 0; k > roundAt; k--) {\n          digits.unshift(0);\n          parsedNumber.i++;\n        }\n        digits.unshift(1);\n        parsedNumber.i++;\n      } else {\n        digits[roundAt - 1]++;\n      }\n    }\n\n    // Pad out with zeros to get the required fraction length\n    for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);\n\n\n    // Do any carrying, e.g. a digit was rounded up to 10\n    var carry = digits.reduceRight(function(carry, d, i, digits) {\n      d = d + carry;\n      digits[i] = d % 10;\n      return Math.floor(d / 10);\n    }, 0);\n    if (carry) {\n      digits.unshift(carry);\n      parsedNumber.i++;\n    }\n}\n\n/**\n * Format a number into a string\n * @param  {number} number       The number to format\n * @param  {{\n *           minFrac, // the minimum number of digits required in the fraction part of the number\n *           maxFrac, // the maximum number of digits required in the fraction part of the number\n *           gSize,   // number of digits in each group of separated digits\n *           lgSize,  // number of digits in the last group of digits before the decimal separator\n *           negPre,  // the string to go in front of a negative number (e.g. `-` or `(`))\n *           posPre,  // the string to go in front of a positive number\n *           negSuf,  // the string to go after a negative number (e.g. `)`)\n *           posSuf   // the string to go after a positive number\n *         }} pattern\n * @param  {string} groupSep     The string to separate groups of number (e.g. `,`)\n * @param  {string} decimalSep   The string to act as the decimal separator (e.g. `.`)\n * @param  {[type]} fractionSize The size of the fractional part of the number\n * @return {string}              The number formatted as a string\n */\nfunction formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {\n\n  if (!(isString(number) || isNumber(number)) || isNaN(number)) return '';\n\n  var isInfinity = !isFinite(number);\n  var isZero = false;\n  var numStr = Math.abs(number) + '',\n      formattedText = '',\n      parsedNumber;\n\n  if (isInfinity) {\n    formattedText = '\\u221e';\n  } else {\n    parsedNumber = parse(numStr);\n\n    roundNumber(parsedNumber, fractionSize, pattern.minFrac, pattern.maxFrac);\n\n    var digits = parsedNumber.d;\n    var integerLen = parsedNumber.i;\n    var exponent = parsedNumber.e;\n    var decimals = [];\n    isZero = digits.reduce(function(isZero, d) { return isZero && !d; }, true);\n\n    // pad zeros for small numbers\n    while (integerLen < 0) {\n      digits.unshift(0);\n      integerLen++;\n    }\n\n    // extract decimals digits\n    if (integerLen > 0) {\n      decimals = digits.splice(integerLen, digits.length);\n    } else {\n      decimals = digits;\n      digits = [0];\n    }\n\n    // format the integer digits with grouping separators\n    var groups = [];\n    if (digits.length >= pattern.lgSize) {\n      groups.unshift(digits.splice(-pattern.lgSize, digits.length).join(''));\n    }\n    while (digits.length > pattern.gSize) {\n      groups.unshift(digits.splice(-pattern.gSize, digits.length).join(''));\n    }\n    if (digits.length) {\n      groups.unshift(digits.join(''));\n    }\n    formattedText = groups.join(groupSep);\n\n    // append the decimal digits\n    if (decimals.length) {\n      formattedText += decimalSep + decimals.join('');\n    }\n\n    if (exponent) {\n      formattedText += 'e+' + exponent;\n    }\n  }\n  if (number < 0 && !isZero) {\n    return pattern.negPre + formattedText + pattern.negSuf;\n  } else {\n    return pattern.posPre + formattedText + pattern.posSuf;\n  }\n}\n\nfunction padNumber(num, digits, trim, negWrap) {\n  var neg = '';\n  if (num < 0 || (negWrap && num <= 0)) {\n    if (negWrap) {\n      num = -num + 1;\n    } else {\n      num = -num;\n      neg = '-';\n    }\n  }\n  num = '' + num;\n  while (num.length < digits) num = ZERO_CHAR + num;\n  if (trim) {\n    num = num.substr(num.length - digits);\n  }\n  return neg + num;\n}\n\n\nfunction dateGetter(name, size, offset, trim, negWrap) {\n  offset = offset || 0;\n  return function(date) {\n    var value = date['get' + name]();\n    if (offset > 0 || value > -offset) {\n      value += offset;\n    }\n    if (value === 0 && offset === -12) value = 12;\n    return padNumber(value, size, trim, negWrap);\n  };\n}\n\nfunction dateStrGetter(name, shortForm, standAlone) {\n  return function(date, formats) {\n    var value = date['get' + name]();\n    var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : '');\n    var get = uppercase(propPrefix + name);\n\n    return formats[get][value];\n  };\n}\n\nfunction timeZoneGetter(date, formats, offset) {\n  var zone = -1 * offset;\n  var paddedZone = (zone >= 0) ? '+' : '';\n\n  paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +\n                padNumber(Math.abs(zone % 60), 2);\n\n  return paddedZone;\n}\n\nfunction getFirstThursdayOfYear(year) {\n    // 0 = index of January\n    var dayOfWeekOnFirst = (new Date(year, 0, 1)).getDay();\n    // 4 = index of Thursday (+1 to account for 1st = 5)\n    // 11 = index of *next* Thursday (+1 account for 1st = 12)\n    return new Date(year, 0, ((dayOfWeekOnFirst <= 4) ? 5 : 12) - dayOfWeekOnFirst);\n}\n\nfunction getThursdayThisWeek(datetime) {\n    return new Date(datetime.getFullYear(), datetime.getMonth(),\n      // 4 = index of Thursday\n      datetime.getDate() + (4 - datetime.getDay()));\n}\n\nfunction weekGetter(size) {\n   return function(date) {\n      var firstThurs = getFirstThursdayOfYear(date.getFullYear()),\n         thisThurs = getThursdayThisWeek(date);\n\n      var diff = +thisThurs - +firstThurs,\n         result = 1 + Math.round(diff / 6.048e8); // 6.048e8 ms per week\n\n      return padNumber(result, size);\n   };\n}\n\nfunction ampmGetter(date, formats) {\n  return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1];\n}\n\nfunction eraGetter(date, formats) {\n  return date.getFullYear() <= 0 ? formats.ERAS[0] : formats.ERAS[1];\n}\n\nfunction longEraGetter(date, formats) {\n  return date.getFullYear() <= 0 ? formats.ERANAMES[0] : formats.ERANAMES[1];\n}\n\nvar DATE_FORMATS = {\n  yyyy: dateGetter('FullYear', 4, 0, false, true),\n    yy: dateGetter('FullYear', 2, 0, true, true),\n     y: dateGetter('FullYear', 1, 0, false, true),\n  MMMM: dateStrGetter('Month'),\n   MMM: dateStrGetter('Month', true),\n    MM: dateGetter('Month', 2, 1),\n     M: dateGetter('Month', 1, 1),\n  LLLL: dateStrGetter('Month', false, true),\n    dd: dateGetter('Date', 2),\n     d: dateGetter('Date', 1),\n    HH: dateGetter('Hours', 2),\n     H: dateGetter('Hours', 1),\n    hh: dateGetter('Hours', 2, -12),\n     h: dateGetter('Hours', 1, -12),\n    mm: dateGetter('Minutes', 2),\n     m: dateGetter('Minutes', 1),\n    ss: dateGetter('Seconds', 2),\n     s: dateGetter('Seconds', 1),\n     // while ISO 8601 requires fractions to be prefixed with `.` or `,`\n     // we can be just safely rely on using `sss` since we currently don't support single or two digit fractions\n   sss: dateGetter('Milliseconds', 3),\n  EEEE: dateStrGetter('Day'),\n   EEE: dateStrGetter('Day', true),\n     a: ampmGetter,\n     Z: timeZoneGetter,\n    ww: weekGetter(2),\n     w: weekGetter(1),\n     G: eraGetter,\n     GG: eraGetter,\n     GGG: eraGetter,\n     GGGG: longEraGetter\n};\n\nvar DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,\n    NUMBER_STRING = /^-?\\d+$/;\n\n/**\n * @ngdoc filter\n * @name date\n * @kind function\n *\n * @description\n *   Formats `date` to a string based on the requested `format`.\n *\n *   `format` string can be composed of the following elements:\n *\n *   * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010)\n *   * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10)\n *   * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199)\n *   * `'MMMM'`: Month in year (January-December)\n *   * `'MMM'`: Month in year (Jan-Dec)\n *   * `'MM'`: Month in year, padded (01-12)\n *   * `'M'`: Month in year (1-12)\n *   * `'LLLL'`: Stand-alone month in year (January-December)\n *   * `'dd'`: Day in month, padded (01-31)\n *   * `'d'`: Day in month (1-31)\n *   * `'EEEE'`: Day in Week,(Sunday-Saturday)\n *   * `'EEE'`: Day in Week, (Sun-Sat)\n *   * `'HH'`: Hour in day, padded (00-23)\n *   * `'H'`: Hour in day (0-23)\n *   * `'hh'`: Hour in AM/PM, padded (01-12)\n *   * `'h'`: Hour in AM/PM, (1-12)\n *   * `'mm'`: Minute in hour, padded (00-59)\n *   * `'m'`: Minute in hour (0-59)\n *   * `'ss'`: Second in minute, padded (00-59)\n *   * `'s'`: Second in minute (0-59)\n *   * `'sss'`: Millisecond in second, padded (000-999)\n *   * `'a'`: AM/PM marker\n *   * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)\n *   * `'ww'`: Week of year, padded (00-53). Week 01 is the week with the first Thursday of the year\n *   * `'w'`: Week of year (0-53). Week 1 is the week with the first Thursday of the year\n *   * `'G'`, `'GG'`, `'GGG'`: The abbreviated form of the era string (e.g. 'AD')\n *   * `'GGGG'`: The long form of the era string (e.g. 'Anno Domini')\n *\n *   `format` string can also be one of the following predefined\n *   {@link guide/i18n localizable formats}:\n *\n *   * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale\n *     (e.g. Sep 3, 2010 12:05:08 PM)\n *   * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US  locale (e.g. 9/3/10 12:05 PM)\n *   * `'fullDate'`: equivalent to `'EEEE, MMMM d, y'` for en_US  locale\n *     (e.g. Friday, September 3, 2010)\n *   * `'longDate'`: equivalent to `'MMMM d, y'` for en_US  locale (e.g. September 3, 2010)\n *   * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US  locale (e.g. Sep 3, 2010)\n *   * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)\n *   * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 PM)\n *   * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 PM)\n *\n *   `format` string can contain literal values. These need to be escaped by surrounding with single quotes (e.g.\n *   `\"h 'in the morning'\"`). In order to output a single quote, escape it - i.e., two single quotes in a sequence\n *   (e.g. `\"h 'o''clock'\"`).\n *\n * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or\n *    number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its\n *    shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is\n *    specified in the string input, the time is considered to be in the local timezone.\n * @param {string=} format Formatting rules (see Description). If not specified,\n *    `mediumDate` is used.\n * @param {string=} timezone Timezone to be used for formatting. It understands UTC/GMT and the\n *    continental US time zone abbreviations, but for general use, use a time zone offset, for\n *    example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)\n *    If not specified, the timezone of the browser will be used.\n * @returns {string} Formatted string or the input if input is not recognized as date/millis.\n *\n * @example\n   <example name=\"filter-date\">\n     <file name=\"index.html\">\n       <span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:\n           <span>{{1288323623006 | date:'medium'}}</span><br>\n       <span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:\n          <span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>\n       <span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:\n          <span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>\n       <span ng-non-bindable>{{1288323623006 | date:\"MM/dd/yyyy 'at' h:mma\"}}</span>:\n          <span>{{'1288323623006' | date:\"MM/dd/yyyy 'at' h:mma\"}}</span><br>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should format date', function() {\n         expect(element(by.binding(\"1288323623006 | date:'medium'\")).getText()).\n            toMatch(/Oct 2\\d, 2010 \\d{1,2}:\\d{2}:\\d{2} (AM|PM)/);\n         expect(element(by.binding(\"1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'\")).getText()).\n            toMatch(/2010-10-2\\d \\d{2}:\\d{2}:\\d{2} (-|\\+)?\\d{4}/);\n         expect(element(by.binding(\"'1288323623006' | date:'MM/dd/yyyy @ h:mma'\")).getText()).\n            toMatch(/10\\/2\\d\\/2010 @ \\d{1,2}:\\d{2}(AM|PM)/);\n         expect(element(by.binding(\"'1288323623006' | date:\\\"MM/dd/yyyy 'at' h:mma\\\"\")).getText()).\n            toMatch(/10\\/2\\d\\/2010 at \\d{1,2}:\\d{2}(AM|PM)/);\n       });\n     </file>\n   </example>\n */\ndateFilter.$inject = ['$locale'];\nfunction dateFilter($locale) {\n\n\n  var R_ISO8601_STR = /^(\\d{4})-?(\\d\\d)-?(\\d\\d)(?:T(\\d\\d)(?::?(\\d\\d)(?::?(\\d\\d)(?:\\.(\\d+))?)?)?(Z|([+-])(\\d\\d):?(\\d\\d))?)?$/;\n                     // 1        2       3         4          5          6          7          8  9     10      11\n  function jsonStringToDate(string) {\n    var match;\n    if ((match = string.match(R_ISO8601_STR))) {\n      var date = new Date(0),\n          tzHour = 0,\n          tzMin  = 0,\n          dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,\n          timeSetter = match[8] ? date.setUTCHours : date.setHours;\n\n      if (match[9]) {\n        tzHour = toInt(match[9] + match[10]);\n        tzMin = toInt(match[9] + match[11]);\n      }\n      dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));\n      var h = toInt(match[4] || 0) - tzHour;\n      var m = toInt(match[5] || 0) - tzMin;\n      var s = toInt(match[6] || 0);\n      var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);\n      timeSetter.call(date, h, m, s, ms);\n      return date;\n    }\n    return string;\n  }\n\n\n  return function(date, format, timezone) {\n    var text = '',\n        parts = [],\n        fn, match;\n\n    format = format || 'mediumDate';\n    format = $locale.DATETIME_FORMATS[format] || format;\n    if (isString(date)) {\n      date = NUMBER_STRING.test(date) ? toInt(date) : jsonStringToDate(date);\n    }\n\n    if (isNumber(date)) {\n      date = new Date(date);\n    }\n\n    if (!isDate(date) || !isFinite(date.getTime())) {\n      return date;\n    }\n\n    while (format) {\n      match = DATE_FORMATS_SPLIT.exec(format);\n      if (match) {\n        parts = concat(parts, match, 1);\n        format = parts.pop();\n      } else {\n        parts.push(format);\n        format = null;\n      }\n    }\n\n    var dateTimezoneOffset = date.getTimezoneOffset();\n    if (timezone) {\n      dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);\n      date = convertTimezoneToLocal(date, timezone, true);\n    }\n    forEach(parts, function(value) {\n      fn = DATE_FORMATS[value];\n      text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset)\n                 : value === '\\'\\'' ? '\\'' : value.replace(/(^'|'$)/g, '').replace(/''/g, '\\'');\n    });\n\n    return text;\n  };\n}\n\n\n/**\n * @ngdoc filter\n * @name json\n * @kind function\n *\n * @description\n *   Allows you to convert a JavaScript object into JSON string.\n *\n *   This filter is mostly useful for debugging. When using the double curly {{value}} notation\n *   the binding is automatically converted to JSON.\n *\n * @param {*} object Any JavaScript object (including arrays and primitive types) to filter.\n * @param {number=} spacing The number of spaces to use per indentation, defaults to 2.\n * @returns {string} JSON string.\n *\n *\n * @example\n   <example name=\"filter-json\">\n     <file name=\"index.html\">\n       <pre id=\"default-spacing\">{{ {'name':'value'} | json }}</pre>\n       <pre id=\"custom-spacing\">{{ {'name':'value'} | json:4 }}</pre>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should jsonify filtered objects', function() {\n         expect(element(by.id('default-spacing')).getText()).toMatch(/\\{\\n {2}\"name\": ?\"value\"\\n}/);\n         expect(element(by.id('custom-spacing')).getText()).toMatch(/\\{\\n {4}\"name\": ?\"value\"\\n}/);\n       });\n     </file>\n   </example>\n *\n */\nfunction jsonFilter() {\n  return function(object, spacing) {\n    if (isUndefined(spacing)) {\n        spacing = 2;\n    }\n    return toJson(object, spacing);\n  };\n}\n\n\n/**\n * @ngdoc filter\n * @name lowercase\n * @kind function\n * @description\n * Converts string to lowercase.\n * @see angular.lowercase\n */\nvar lowercaseFilter = valueFn(lowercase);\n\n\n/**\n * @ngdoc filter\n * @name uppercase\n * @kind function\n * @description\n * Converts string to uppercase.\n * @see angular.uppercase\n */\nvar uppercaseFilter = valueFn(uppercase);\n\n/**\n * @ngdoc filter\n * @name limitTo\n * @kind function\n *\n * @description\n * Creates a new array or string containing only a specified number of elements. The elements are\n * taken from either the beginning or the end of the source array, string or number, as specified by\n * the value and sign (positive or negative) of `limit`. Other array-like objects are also supported\n * (e.g. array subclasses, NodeLists, jqLite/jQuery collections etc). If a number is used as input,\n * it is converted to a string.\n *\n * @param {Array|ArrayLike|string|number} input - Array/array-like, string or number to be limited.\n * @param {string|number} limit - The length of the returned array or string. If the `limit` number\n *     is positive, `limit` number of items from the beginning of the source array/string are copied.\n *     If the number is negative, `limit` number  of items from the end of the source array/string\n *     are copied. The `limit` will be trimmed if it exceeds `array.length`. If `limit` is undefined,\n *     the input will be returned unchanged.\n * @param {(string|number)=} begin - Index at which to begin limitation. As a negative index,\n *     `begin` indicates an offset from the end of `input`. Defaults to `0`.\n * @returns {Array|string} A new sub-array or substring of length `limit` or less if the input had\n *     less than `limit` elements.\n *\n * @example\n   <example module=\"limitToExample\" name=\"limit-to-filter\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('limitToExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.numbers = [1,2,3,4,5,6,7,8,9];\n             $scope.letters = \"abcdefghi\";\n             $scope.longNumber = 2345432342;\n             $scope.numLimit = 3;\n             $scope.letterLimit = 3;\n             $scope.longNumberLimit = 3;\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <label>\n            Limit {{numbers}} to:\n            <input type=\"number\" step=\"1\" ng-model=\"numLimit\">\n         </label>\n         <p>Output numbers: {{ numbers | limitTo:numLimit }}</p>\n         <label>\n            Limit {{letters}} to:\n            <input type=\"number\" step=\"1\" ng-model=\"letterLimit\">\n         </label>\n         <p>Output letters: {{ letters | limitTo:letterLimit }}</p>\n         <label>\n            Limit {{longNumber}} to:\n            <input type=\"number\" step=\"1\" ng-model=\"longNumberLimit\">\n         </label>\n         <p>Output long number: {{ longNumber | limitTo:longNumberLimit }}</p>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       var numLimitInput = element(by.model('numLimit'));\n       var letterLimitInput = element(by.model('letterLimit'));\n       var longNumberLimitInput = element(by.model('longNumberLimit'));\n       var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));\n       var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));\n       var limitedLongNumber = element(by.binding('longNumber | limitTo:longNumberLimit'));\n\n       it('should limit the number array to first three items', function() {\n         expect(numLimitInput.getAttribute('value')).toBe('3');\n         expect(letterLimitInput.getAttribute('value')).toBe('3');\n         expect(longNumberLimitInput.getAttribute('value')).toBe('3');\n         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');\n         expect(limitedLetters.getText()).toEqual('Output letters: abc');\n         expect(limitedLongNumber.getText()).toEqual('Output long number: 234');\n       });\n\n       // There is a bug in safari and protractor that doesn't like the minus key\n       // it('should update the output when -3 is entered', function() {\n       //   numLimitInput.clear();\n       //   numLimitInput.sendKeys('-3');\n       //   letterLimitInput.clear();\n       //   letterLimitInput.sendKeys('-3');\n       //   longNumberLimitInput.clear();\n       //   longNumberLimitInput.sendKeys('-3');\n       //   expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');\n       //   expect(limitedLetters.getText()).toEqual('Output letters: ghi');\n       //   expect(limitedLongNumber.getText()).toEqual('Output long number: 342');\n       // });\n\n       it('should not exceed the maximum size of input array', function() {\n         numLimitInput.clear();\n         numLimitInput.sendKeys('100');\n         letterLimitInput.clear();\n         letterLimitInput.sendKeys('100');\n         longNumberLimitInput.clear();\n         longNumberLimitInput.sendKeys('100');\n         expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');\n         expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');\n         expect(limitedLongNumber.getText()).toEqual('Output long number: 2345432342');\n       });\n     </file>\n   </example>\n*/\nfunction limitToFilter() {\n  return function(input, limit, begin) {\n    if (Math.abs(Number(limit)) === Infinity) {\n      limit = Number(limit);\n    } else {\n      limit = toInt(limit);\n    }\n    if (isNumberNaN(limit)) return input;\n\n    if (isNumber(input)) input = input.toString();\n    if (!isArrayLike(input)) return input;\n\n    begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);\n    begin = (begin < 0) ? Math.max(0, input.length + begin) : begin;\n\n    if (limit >= 0) {\n      return sliceFn(input, begin, begin + limit);\n    } else {\n      if (begin === 0) {\n        return sliceFn(input, limit, input.length);\n      } else {\n        return sliceFn(input, Math.max(0, begin + limit), begin);\n      }\n    }\n  };\n}\n\nfunction sliceFn(input, begin, end) {\n  if (isString(input)) return input.slice(begin, end);\n\n  return slice.call(input, begin, end);\n}\n\n/**\n * @ngdoc filter\n * @name orderBy\n * @kind function\n *\n * @description\n * Returns an array containing the items from the specified `collection`, ordered by a `comparator`\n * function based on the values computed using the `expression` predicate.\n *\n * For example, `[{id: 'foo'}, {id: 'bar'}] | orderBy:'id'` would result in\n * `[{id: 'bar'}, {id: 'foo'}]`.\n *\n * The `collection` can be an Array or array-like object (e.g. NodeList, jQuery object, TypedArray,\n * String, etc).\n *\n * The `expression` can be a single predicate, or a list of predicates each serving as a tie-breaker\n * for the preceding one. The `expression` is evaluated against each item and the output is used\n * for comparing with other items.\n *\n * You can change the sorting order by setting `reverse` to `true`. By default, items are sorted in\n * ascending order.\n *\n * The comparison is done using the `comparator` function. If none is specified, a default, built-in\n * comparator is used (see below for details - in a nutshell, it compares numbers numerically and\n * strings alphabetically).\n *\n * ### Under the hood\n *\n * Ordering the specified `collection` happens in two phases:\n *\n * 1. All items are passed through the predicate (or predicates), and the returned values are saved\n *    along with their type (`string`, `number` etc). For example, an item `{label: 'foo'}`, passed\n *    through a predicate that extracts the value of the `label` property, would be transformed to:\n *    ```\n *    {\n *      value: 'foo',\n *      type: 'string',\n *      index: ...\n *    }\n *    ```\n * 2. The comparator function is used to sort the items, based on the derived values, types and\n *    indices.\n *\n * If you use a custom comparator, it will be called with pairs of objects of the form\n * `{value: ..., type: '...', index: ...}` and is expected to return `0` if the objects are equal\n * (as far as the comparator is concerned), `-1` if the 1st one should be ranked higher than the\n * second, or `1` otherwise.\n *\n * In order to ensure that the sorting will be deterministic across platforms, if none of the\n * specified predicates can distinguish between two items, `orderBy` will automatically introduce a\n * dummy predicate that returns the item's index as `value`.\n * (If you are using a custom comparator, make sure it can handle this predicate as well.)\n *\n * Finally, in an attempt to simplify things, if a predicate returns an object as the extracted\n * value for an item, `orderBy` will try to convert that object to a primitive value, before passing\n * it to the comparator. The following rules govern the conversion:\n *\n * 1. If the object has a `valueOf()` method that returns a primitive, its return value will be\n *    used instead.<br />\n *    (If the object has a `valueOf()` method that returns another object, then the returned object\n *    will be used in subsequent steps.)\n * 2. If the object has a custom `toString()` method (i.e. not the one inherited from `Object`) that\n *    returns a primitive, its return value will be used instead.<br />\n *    (If the object has a `toString()` method that returns another object, then the returned object\n *    will be used in subsequent steps.)\n * 3. No conversion; the object itself is used.\n *\n * ### The default comparator\n *\n * The default, built-in comparator should be sufficient for most usecases. In short, it compares\n * numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to\n * using their index in the original collection, and sorts values of different types by type.\n *\n * More specifically, it follows these steps to determine the relative order of items:\n *\n * 1. If the compared values are of different types, compare the types themselves alphabetically.\n * 2. If both values are of type `string`, compare them alphabetically in a case- and\n *    locale-insensitive way.\n * 3. If both values are objects, compare their indices instead.\n * 4. Otherwise, return:\n *    -  `0`, if the values are equal (by strict equality comparison, i.e. using `===`).\n *    - `-1`, if the 1st value is \"less than\" the 2nd value (compared using the `<` operator).\n *    -  `1`, otherwise.\n *\n * **Note:** If you notice numbers not being sorted as expected, make sure they are actually being\n *           saved as numbers and not strings.\n * **Note:** For the purpose of sorting, `null` values are treated as the string `'null'` (i.e.\n *           `type: 'string'`, `value: 'null'`). This may cause unexpected sort order relative to\n *           other values.\n *\n * @param {Array|ArrayLike} collection - The collection (array or array-like object) to sort.\n * @param {(Function|string|Array.<Function|string>)=} expression - A predicate (or list of\n *    predicates) to be used by the comparator to determine the order of elements.\n *\n *    Can be one of:\n *\n *    - `Function`: A getter function. This function will be called with each item as argument and\n *      the return value will be used for sorting.\n *    - `string`: An Angular expression. This expression will be evaluated against each item and the\n *      result will be used for sorting. For example, use `'label'` to sort by a property called\n *      `label` or `'label.substring(0, 3)'` to sort by the first 3 characters of the `label`\n *      property.<br />\n *      (The result of a constant expression is interpreted as a property name to be used for\n *      comparison. For example, use `'\"special name\"'` (note the extra pair of quotes) to sort by a\n *      property called `special name`.)<br />\n *      An expression can be optionally prefixed with `+` or `-` to control the sorting direction,\n *      ascending or descending. For example, `'+label'` or `'-label'`. If no property is provided,\n *      (e.g. `'+'` or `'-'`), the collection element itself is used in comparisons.\n *    - `Array`: An array of function and/or string predicates. If a predicate cannot determine the\n *      relative order of two items, the next predicate is used as a tie-breaker.\n *\n * **Note:** If the predicate is missing or empty then it defaults to `'+'`.\n *\n * @param {boolean=} reverse - If `true`, reverse the sorting order.\n * @param {(Function)=} comparator - The comparator function used to determine the relative order of\n *    value pairs. If omitted, the built-in comparator will be used.\n *\n * @returns {Array} - The sorted array.\n *\n *\n * @example\n * ### Ordering a table with `ngRepeat`\n *\n * The example below demonstrates a simple {@link ngRepeat ngRepeat}, where the data is sorted by\n * age in descending order (expression is set to `'-age'`). The `comparator` is not set, which means\n * it defaults to the built-in comparator.\n *\n   <example name=\"orderBy-static\" module=\"orderByExample1\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <table class=\"friends\">\n           <tr>\n             <th>Name</th>\n             <th>Phone Number</th>\n             <th>Age</th>\n           </tr>\n           <tr ng-repeat=\"friend in friends | orderBy:'-age'\">\n             <td>{{friend.name}}</td>\n             <td>{{friend.phone}}</td>\n             <td>{{friend.age}}</td>\n           </tr>\n         </table>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('orderByExample1', [])\n         .controller('ExampleController', ['$scope', function($scope) {\n           $scope.friends = [\n             {name: 'John',   phone: '555-1212',  age: 10},\n             {name: 'Mary',   phone: '555-9876',  age: 19},\n             {name: 'Mike',   phone: '555-4321',  age: 21},\n             {name: 'Adam',   phone: '555-5678',  age: 35},\n             {name: 'Julie',  phone: '555-8765',  age: 29}\n           ];\n         }]);\n     </file>\n     <file name=\"style.css\">\n       .friends {\n         border-collapse: collapse;\n       }\n\n       .friends th {\n         border-bottom: 1px solid;\n       }\n       .friends td, .friends th {\n         border-left: 1px solid;\n         padding: 5px 10px;\n       }\n       .friends td:first-child, .friends th:first-child {\n         border-left: none;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       // Element locators\n       var names = element.all(by.repeater('friends').column('friend.name'));\n\n       it('should sort friends by age in reverse order', function() {\n         expect(names.get(0).getText()).toBe('Adam');\n         expect(names.get(1).getText()).toBe('Julie');\n         expect(names.get(2).getText()).toBe('Mike');\n         expect(names.get(3).getText()).toBe('Mary');\n         expect(names.get(4).getText()).toBe('John');\n       });\n     </file>\n   </example>\n * <hr />\n *\n * @example\n * ### Changing parameters dynamically\n *\n * All parameters can be changed dynamically. The next example shows how you can make the columns of\n * a table sortable, by binding the `expression` and `reverse` parameters to scope properties.\n *\n   <example name=\"orderBy-dynamic\" module=\"orderByExample2\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <pre>Sort by = {{propertyName}}; reverse = {{reverse}}</pre>\n         <hr/>\n         <button ng-click=\"propertyName = null; reverse = false\">Set to unsorted</button>\n         <hr/>\n         <table class=\"friends\">\n           <tr>\n             <th>\n               <button ng-click=\"sortBy('name')\">Name</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'name'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n             <th>\n               <button ng-click=\"sortBy('phone')\">Phone Number</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'phone'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n             <th>\n               <button ng-click=\"sortBy('age')\">Age</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'age'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n           </tr>\n           <tr ng-repeat=\"friend in friends | orderBy:propertyName:reverse\">\n             <td>{{friend.name}}</td>\n             <td>{{friend.phone}}</td>\n             <td>{{friend.age}}</td>\n           </tr>\n         </table>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('orderByExample2', [])\n         .controller('ExampleController', ['$scope', function($scope) {\n           var friends = [\n             {name: 'John',   phone: '555-1212',  age: 10},\n             {name: 'Mary',   phone: '555-9876',  age: 19},\n             {name: 'Mike',   phone: '555-4321',  age: 21},\n             {name: 'Adam',   phone: '555-5678',  age: 35},\n             {name: 'Julie',  phone: '555-8765',  age: 29}\n           ];\n\n           $scope.propertyName = 'age';\n           $scope.reverse = true;\n           $scope.friends = friends;\n\n           $scope.sortBy = function(propertyName) {\n             $scope.reverse = ($scope.propertyName === propertyName) ? !$scope.reverse : false;\n             $scope.propertyName = propertyName;\n           };\n         }]);\n     </file>\n     <file name=\"style.css\">\n       .friends {\n         border-collapse: collapse;\n       }\n\n       .friends th {\n         border-bottom: 1px solid;\n       }\n       .friends td, .friends th {\n         border-left: 1px solid;\n         padding: 5px 10px;\n       }\n       .friends td:first-child, .friends th:first-child {\n         border-left: none;\n       }\n\n       .sortorder:after {\n         content: '\\25b2';   // BLACK UP-POINTING TRIANGLE\n       }\n       .sortorder.reverse:after {\n         content: '\\25bc';   // BLACK DOWN-POINTING TRIANGLE\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       // Element locators\n       var unsortButton = element(by.partialButtonText('unsorted'));\n       var nameHeader = element(by.partialButtonText('Name'));\n       var phoneHeader = element(by.partialButtonText('Phone'));\n       var ageHeader = element(by.partialButtonText('Age'));\n       var firstName = element(by.repeater('friends').column('friend.name').row(0));\n       var lastName = element(by.repeater('friends').column('friend.name').row(4));\n\n       it('should sort friends by some property, when clicking on the column header', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         phoneHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Mary');\n\n         nameHeader.click();\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('Mike');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Adam');\n       });\n\n       it('should sort friends in reverse order, when clicking on the same column', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Adam');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n       });\n\n       it('should restore the original order, when clicking \"Set to unsorted\"', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         unsortButton.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Julie');\n       });\n     </file>\n   </example>\n * <hr />\n *\n * @example\n * ### Using `orderBy` inside a controller\n *\n * It is also possible to call the `orderBy` filter manually, by injecting `orderByFilter`, and\n * calling it with the desired parameters. (Alternatively, you could inject the `$filter` factory\n * and retrieve the `orderBy` filter with `$filter('orderBy')`.)\n *\n   <example name=\"orderBy-call-manually\" module=\"orderByExample3\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <pre>Sort by = {{propertyName}}; reverse = {{reverse}}</pre>\n         <hr/>\n         <button ng-click=\"sortBy(null)\">Set to unsorted</button>\n         <hr/>\n         <table class=\"friends\">\n           <tr>\n             <th>\n               <button ng-click=\"sortBy('name')\">Name</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'name'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n             <th>\n               <button ng-click=\"sortBy('phone')\">Phone Number</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'phone'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n             <th>\n               <button ng-click=\"sortBy('age')\">Age</button>\n               <span class=\"sortorder\" ng-show=\"propertyName === 'age'\" ng-class=\"{reverse: reverse}\"></span>\n             </th>\n           </tr>\n           <tr ng-repeat=\"friend in friends\">\n             <td>{{friend.name}}</td>\n             <td>{{friend.phone}}</td>\n             <td>{{friend.age}}</td>\n           </tr>\n         </table>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('orderByExample3', [])\n         .controller('ExampleController', ['$scope', 'orderByFilter', function($scope, orderBy) {\n           var friends = [\n             {name: 'John',   phone: '555-1212',  age: 10},\n             {name: 'Mary',   phone: '555-9876',  age: 19},\n             {name: 'Mike',   phone: '555-4321',  age: 21},\n             {name: 'Adam',   phone: '555-5678',  age: 35},\n             {name: 'Julie',  phone: '555-8765',  age: 29}\n           ];\n\n           $scope.propertyName = 'age';\n           $scope.reverse = true;\n           $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse);\n\n           $scope.sortBy = function(propertyName) {\n             $scope.reverse = (propertyName !== null && $scope.propertyName === propertyName)\n                 ? !$scope.reverse : false;\n             $scope.propertyName = propertyName;\n             $scope.friends = orderBy(friends, $scope.propertyName, $scope.reverse);\n           };\n         }]);\n     </file>\n     <file name=\"style.css\">\n       .friends {\n         border-collapse: collapse;\n       }\n\n       .friends th {\n         border-bottom: 1px solid;\n       }\n       .friends td, .friends th {\n         border-left: 1px solid;\n         padding: 5px 10px;\n       }\n       .friends td:first-child, .friends th:first-child {\n         border-left: none;\n       }\n\n       .sortorder:after {\n         content: '\\25b2';   // BLACK UP-POINTING TRIANGLE\n       }\n       .sortorder.reverse:after {\n         content: '\\25bc';   // BLACK DOWN-POINTING TRIANGLE\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       // Element locators\n       var unsortButton = element(by.partialButtonText('unsorted'));\n       var nameHeader = element(by.partialButtonText('Name'));\n       var phoneHeader = element(by.partialButtonText('Phone'));\n       var ageHeader = element(by.partialButtonText('Age'));\n       var firstName = element(by.repeater('friends').column('friend.name').row(0));\n       var lastName = element(by.repeater('friends').column('friend.name').row(4));\n\n       it('should sort friends by some property, when clicking on the column header', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         phoneHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Mary');\n\n         nameHeader.click();\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('Mike');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Adam');\n       });\n\n       it('should sort friends in reverse order, when clicking on the same column', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Adam');\n\n         ageHeader.click();\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n       });\n\n       it('should restore the original order, when clicking \"Set to unsorted\"', function() {\n         expect(firstName.getText()).toBe('Adam');\n         expect(lastName.getText()).toBe('John');\n\n         unsortButton.click();\n         expect(firstName.getText()).toBe('John');\n         expect(lastName.getText()).toBe('Julie');\n       });\n     </file>\n   </example>\n * <hr />\n *\n * @example\n * ### Using a custom comparator\n *\n * If you have very specific requirements about the way items are sorted, you can pass your own\n * comparator function. For example, you might need to compare some strings in a locale-sensitive\n * way. (When specifying a custom comparator, you also need to pass a value for the `reverse`\n * argument - passing `false` retains the default sorting order, i.e. ascending.)\n *\n   <example name=\"orderBy-custom-comparator\" module=\"orderByExample4\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <div class=\"friends-container custom-comparator\">\n           <h3>Locale-sensitive Comparator</h3>\n           <table class=\"friends\">\n             <tr>\n               <th>Name</th>\n               <th>Favorite Letter</th>\n             </tr>\n             <tr ng-repeat=\"friend in friends | orderBy:'favoriteLetter':false:localeSensitiveComparator\">\n               <td>{{friend.name}}</td>\n               <td>{{friend.favoriteLetter}}</td>\n             </tr>\n           </table>\n         </div>\n         <div class=\"friends-container default-comparator\">\n           <h3>Default Comparator</h3>\n           <table class=\"friends\">\n             <tr>\n               <th>Name</th>\n               <th>Favorite Letter</th>\n             </tr>\n             <tr ng-repeat=\"friend in friends | orderBy:'favoriteLetter'\">\n               <td>{{friend.name}}</td>\n               <td>{{friend.favoriteLetter}}</td>\n             </tr>\n           </table>\n         </div>\n       </div>\n     </file>\n     <file name=\"script.js\">\n       angular.module('orderByExample4', [])\n         .controller('ExampleController', ['$scope', function($scope) {\n           $scope.friends = [\n             {name: 'John',   favoriteLetter: 'Ä'},\n             {name: 'Mary',   favoriteLetter: 'Ü'},\n             {name: 'Mike',   favoriteLetter: 'Ö'},\n             {name: 'Adam',   favoriteLetter: 'H'},\n             {name: 'Julie',  favoriteLetter: 'Z'}\n           ];\n\n           $scope.localeSensitiveComparator = function(v1, v2) {\n             // If we don't get strings, just compare by index\n             if (v1.type !== 'string' || v2.type !== 'string') {\n               return (v1.index < v2.index) ? -1 : 1;\n             }\n\n             // Compare strings alphabetically, taking locale into account\n             return v1.value.localeCompare(v2.value);\n           };\n         }]);\n     </file>\n     <file name=\"style.css\">\n       .friends-container {\n         display: inline-block;\n         margin: 0 30px;\n       }\n\n       .friends {\n         border-collapse: collapse;\n       }\n\n       .friends th {\n         border-bottom: 1px solid;\n       }\n       .friends td, .friends th {\n         border-left: 1px solid;\n         padding: 5px 10px;\n       }\n       .friends td:first-child, .friends th:first-child {\n         border-left: none;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       // Element locators\n       var container = element(by.css('.custom-comparator'));\n       var names = container.all(by.repeater('friends').column('friend.name'));\n\n       it('should sort friends by favorite letter (in correct alphabetical order)', function() {\n         expect(names.get(0).getText()).toBe('John');\n         expect(names.get(1).getText()).toBe('Adam');\n         expect(names.get(2).getText()).toBe('Mike');\n         expect(names.get(3).getText()).toBe('Mary');\n         expect(names.get(4).getText()).toBe('Julie');\n       });\n     </file>\n   </example>\n *\n */\norderByFilter.$inject = ['$parse'];\nfunction orderByFilter($parse) {\n  return function(array, sortPredicate, reverseOrder, compareFn) {\n\n    if (array == null) return array;\n    if (!isArrayLike(array)) {\n      throw minErr('orderBy')('notarray', 'Expected array but received: {0}', array);\n    }\n\n    if (!isArray(sortPredicate)) { sortPredicate = [sortPredicate]; }\n    if (sortPredicate.length === 0) { sortPredicate = ['+']; }\n\n    var predicates = processPredicates(sortPredicate);\n\n    var descending = reverseOrder ? -1 : 1;\n\n    // Define the `compare()` function. Use a default comparator if none is specified.\n    var compare = isFunction(compareFn) ? compareFn : defaultCompare;\n\n    // The next three lines are a version of a Swartzian Transform idiom from Perl\n    // (sometimes called the Decorate-Sort-Undecorate idiom)\n    // See https://en.wikipedia.org/wiki/Schwartzian_transform\n    var compareValues = Array.prototype.map.call(array, getComparisonObject);\n    compareValues.sort(doComparison);\n    array = compareValues.map(function(item) { return item.value; });\n\n    return array;\n\n    function getComparisonObject(value, index) {\n      // NOTE: We are adding an extra `tieBreaker` value based on the element's index.\n      // This will be used to keep the sort stable when none of the input predicates can\n      // distinguish between two elements.\n      return {\n        value: value,\n        tieBreaker: {value: index, type: 'number', index: index},\n        predicateValues: predicates.map(function(predicate) {\n          return getPredicateValue(predicate.get(value), index);\n        })\n      };\n    }\n\n    function doComparison(v1, v2) {\n      for (var i = 0, ii = predicates.length; i < ii; i++) {\n        var result = compare(v1.predicateValues[i], v2.predicateValues[i]);\n        if (result) {\n          return result * predicates[i].descending * descending;\n        }\n      }\n\n      return compare(v1.tieBreaker, v2.tieBreaker) * descending;\n    }\n  };\n\n  function processPredicates(sortPredicates) {\n    return sortPredicates.map(function(predicate) {\n      var descending = 1, get = identity;\n\n      if (isFunction(predicate)) {\n        get = predicate;\n      } else if (isString(predicate)) {\n        if ((predicate.charAt(0) === '+' || predicate.charAt(0) === '-')) {\n          descending = predicate.charAt(0) === '-' ? -1 : 1;\n          predicate = predicate.substring(1);\n        }\n        if (predicate !== '') {\n          get = $parse(predicate);\n          if (get.constant) {\n            var key = get();\n            get = function(value) { return value[key]; };\n          }\n        }\n      }\n      return {get: get, descending: descending};\n    });\n  }\n\n  function isPrimitive(value) {\n    switch (typeof value) {\n      case 'number': /* falls through */\n      case 'boolean': /* falls through */\n      case 'string':\n        return true;\n      default:\n        return false;\n    }\n  }\n\n  function objectValue(value) {\n    // If `valueOf` is a valid function use that\n    if (isFunction(value.valueOf)) {\n      value = value.valueOf();\n      if (isPrimitive(value)) return value;\n    }\n    // If `toString` is a valid function and not the one from `Object.prototype` use that\n    if (hasCustomToString(value)) {\n      value = value.toString();\n      if (isPrimitive(value)) return value;\n    }\n\n    return value;\n  }\n\n  function getPredicateValue(value, index) {\n    var type = typeof value;\n    if (value === null) {\n      type = 'string';\n      value = 'null';\n    } else if (type === 'object') {\n      value = objectValue(value);\n    }\n    return {value: value, type: type, index: index};\n  }\n\n  function defaultCompare(v1, v2) {\n    var result = 0;\n    var type1 = v1.type;\n    var type2 = v2.type;\n\n    if (type1 === type2) {\n      var value1 = v1.value;\n      var value2 = v2.value;\n\n      if (type1 === 'string') {\n        // Compare strings case-insensitively\n        value1 = value1.toLowerCase();\n        value2 = value2.toLowerCase();\n      } else if (type1 === 'object') {\n        // For basic objects, use the position of the object\n        // in the collection instead of the value\n        if (isObject(value1)) value1 = v1.index;\n        if (isObject(value2)) value2 = v2.index;\n      }\n\n      if (value1 !== value2) {\n        result = value1 < value2 ? -1 : 1;\n      }\n    } else {\n      result = type1 < type2 ? -1 : 1;\n    }\n\n    return result;\n  }\n}\n\nfunction ngDirective(directive) {\n  if (isFunction(directive)) {\n    directive = {\n      link: directive\n    };\n  }\n  directive.restrict = directive.restrict || 'AC';\n  return valueFn(directive);\n}\n\n/**\n * @ngdoc directive\n * @name a\n * @restrict E\n *\n * @description\n * Modifies the default behavior of the html a tag so that the default action is prevented when\n * the href attribute is empty.\n *\n * For dynamically creating `href` attributes for a tags, see the {@link ng.ngHref `ngHref`} directive.\n */\nvar htmlAnchorDirective = valueFn({\n  restrict: 'E',\n  compile: function(element, attr) {\n    if (!attr.href && !attr.xlinkHref) {\n      return function(scope, element) {\n        // If the linked element is not an anchor tag anymore, do nothing\n        if (element[0].nodeName.toLowerCase() !== 'a') return;\n\n        // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.\n        var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?\n                   'xlink:href' : 'href';\n        element.on('click', function(event) {\n          // if we have no href url, then don't navigate anywhere.\n          if (!element.attr(href)) {\n            event.preventDefault();\n          }\n        });\n      };\n    }\n  }\n});\n\n/**\n * @ngdoc directive\n * @name ngHref\n * @restrict A\n * @priority 99\n *\n * @description\n * Using Angular markup like `{{hash}}` in an href attribute will\n * make the link go to the wrong URL if the user clicks it before\n * Angular has a chance to replace the `{{hash}}` markup with its\n * value. Until Angular replaces the markup the link will be broken\n * and will most likely return a 404 error. The `ngHref` directive\n * solves this problem.\n *\n * The wrong way to write it:\n * ```html\n * <a href=\"http://www.gravatar.com/avatar/{{hash}}\">link1</a>\n * ```\n *\n * The correct way to write it:\n * ```html\n * <a ng-href=\"http://www.gravatar.com/avatar/{{hash}}\">link1</a>\n * ```\n *\n * @element A\n * @param {template} ngHref any string which can contain `{{}}` markup.\n *\n * @example\n * This example shows various combinations of `href`, `ng-href` and `ng-click` attributes\n * in links and their different behaviors:\n    <example name=\"ng-href\">\n      <file name=\"index.html\">\n        <input ng-model=\"value\" /><br />\n        <a id=\"link-1\" href ng-click=\"value = 1\">link 1</a> (link, don't reload)<br />\n        <a id=\"link-2\" href=\"\" ng-click=\"value = 2\">link 2</a> (link, don't reload)<br />\n        <a id=\"link-3\" ng-href=\"/{{'123'}}\">link 3</a> (link, reload!)<br />\n        <a id=\"link-4\" href=\"\" name=\"xx\" ng-click=\"value = 4\">anchor</a> (link, don't reload)<br />\n        <a id=\"link-5\" name=\"xxx\" ng-click=\"value = 5\">anchor</a> (no link)<br />\n        <a id=\"link-6\" ng-href=\"{{value}}\">link</a> (link, change location)\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should execute ng-click but not reload when href without value', function() {\n          element(by.id('link-1')).click();\n          expect(element(by.model('value')).getAttribute('value')).toEqual('1');\n          expect(element(by.id('link-1')).getAttribute('href')).toBe('');\n        });\n\n        it('should execute ng-click but not reload when href empty string', function() {\n          element(by.id('link-2')).click();\n          expect(element(by.model('value')).getAttribute('value')).toEqual('2');\n          expect(element(by.id('link-2')).getAttribute('href')).toBe('');\n        });\n\n        it('should execute ng-click and change url when ng-href specified', function() {\n          expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\\/123$/);\n\n          element(by.id('link-3')).click();\n\n          // At this point, we navigate away from an Angular page, so we need\n          // to use browser.driver to get the base webdriver.\n\n          browser.wait(function() {\n            return browser.driver.getCurrentUrl().then(function(url) {\n              return url.match(/\\/123$/);\n            });\n          }, 5000, 'page should navigate to /123');\n        });\n\n        it('should execute ng-click but not reload when href empty string and name specified', function() {\n          element(by.id('link-4')).click();\n          expect(element(by.model('value')).getAttribute('value')).toEqual('4');\n          expect(element(by.id('link-4')).getAttribute('href')).toBe('');\n        });\n\n        it('should execute ng-click but not reload when no href but name specified', function() {\n          element(by.id('link-5')).click();\n          expect(element(by.model('value')).getAttribute('value')).toEqual('5');\n          expect(element(by.id('link-5')).getAttribute('href')).toBe(null);\n        });\n\n        it('should only change url when only ng-href', function() {\n          element(by.model('value')).clear();\n          element(by.model('value')).sendKeys('6');\n          expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\\/6$/);\n\n          element(by.id('link-6')).click();\n\n          // At this point, we navigate away from an Angular page, so we need\n          // to use browser.driver to get the base webdriver.\n          browser.wait(function() {\n            return browser.driver.getCurrentUrl().then(function(url) {\n              return url.match(/\\/6$/);\n            });\n          }, 5000, 'page should navigate to /6');\n        });\n      </file>\n    </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngSrc\n * @restrict A\n * @priority 99\n *\n * @description\n * Using Angular markup like `{{hash}}` in a `src` attribute doesn't\n * work right: The browser will fetch from the URL with the literal\n * text `{{hash}}` until Angular replaces the expression inside\n * `{{hash}}`. The `ngSrc` directive solves this problem.\n *\n * The buggy way to write it:\n * ```html\n * <img src=\"http://www.gravatar.com/avatar/{{hash}}\" alt=\"Description\"/>\n * ```\n *\n * The correct way to write it:\n * ```html\n * <img ng-src=\"http://www.gravatar.com/avatar/{{hash}}\" alt=\"Description\" />\n * ```\n *\n * @element IMG\n * @param {template} ngSrc any string which can contain `{{}}` markup.\n */\n\n/**\n * @ngdoc directive\n * @name ngSrcset\n * @restrict A\n * @priority 99\n *\n * @description\n * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't\n * work right: The browser will fetch from the URL with the literal\n * text `{{hash}}` until Angular replaces the expression inside\n * `{{hash}}`. The `ngSrcset` directive solves this problem.\n *\n * The buggy way to write it:\n * ```html\n * <img srcset=\"http://www.gravatar.com/avatar/{{hash}} 2x\" alt=\"Description\"/>\n * ```\n *\n * The correct way to write it:\n * ```html\n * <img ng-srcset=\"http://www.gravatar.com/avatar/{{hash}} 2x\" alt=\"Description\" />\n * ```\n *\n * @element IMG\n * @param {template} ngSrcset any string which can contain `{{}}` markup.\n */\n\n/**\n * @ngdoc directive\n * @name ngDisabled\n * @restrict A\n * @priority 100\n *\n * @description\n *\n * This directive sets the `disabled` attribute on the element (typically a form control,\n * e.g. `input`, `button`, `select` etc.) if the\n * {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.\n *\n * A special directive is necessary because we cannot use interpolation inside the `disabled`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * @example\n    <example name=\"ng-disabled\">\n      <file name=\"index.html\">\n        <label>Click me to toggle: <input type=\"checkbox\" ng-model=\"checked\"></label><br/>\n        <button ng-model=\"button\" ng-disabled=\"checked\">Button</button>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should toggle button', function() {\n          expect(element(by.css('button')).getAttribute('disabled')).toBeFalsy();\n          element(by.model('checked')).click();\n          expect(element(by.css('button')).getAttribute('disabled')).toBeTruthy();\n        });\n      </file>\n    </example>\n *\n * @element INPUT\n * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy,\n *     then the `disabled` attribute will be set on the element\n */\n\n\n/**\n * @ngdoc directive\n * @name ngChecked\n * @restrict A\n * @priority 100\n *\n * @description\n * Sets the `checked` attribute on the element, if the expression inside `ngChecked` is truthy.\n *\n * Note that this directive should not be used together with {@link ngModel `ngModel`},\n * as this can lead to unexpected behavior.\n *\n * A special directive is necessary because we cannot use interpolation inside the `checked`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * @example\n    <example name=\"ng-checked\">\n      <file name=\"index.html\">\n        <label>Check me to check both: <input type=\"checkbox\" ng-model=\"master\"></label><br/>\n        <input id=\"checkSlave\" type=\"checkbox\" ng-checked=\"master\" aria-label=\"Slave input\">\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should check both checkBoxes', function() {\n          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy();\n          element(by.model('master')).click();\n          expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy();\n        });\n      </file>\n    </example>\n *\n * @element INPUT\n * @param {expression} ngChecked If the {@link guide/expression expression} is truthy,\n *     then the `checked` attribute will be set on the element\n */\n\n\n/**\n * @ngdoc directive\n * @name ngReadonly\n * @restrict A\n * @priority 100\n *\n * @description\n *\n * Sets the `readonly` attribute on the element, if the expression inside `ngReadonly` is truthy.\n * Note that `readonly` applies only to `input` elements with specific types. [See the input docs on\n * MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-readonly) for more information.\n *\n * A special directive is necessary because we cannot use interpolation inside the `readonly`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * @example\n    <example name=\"ng-readonly\">\n      <file name=\"index.html\">\n        <label>Check me to make text readonly: <input type=\"checkbox\" ng-model=\"checked\"></label><br/>\n        <input type=\"text\" ng-readonly=\"checked\" value=\"I'm Angular\" aria-label=\"Readonly field\" />\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should toggle readonly attr', function() {\n          expect(element(by.css('[type=\"text\"]')).getAttribute('readonly')).toBeFalsy();\n          element(by.model('checked')).click();\n          expect(element(by.css('[type=\"text\"]')).getAttribute('readonly')).toBeTruthy();\n        });\n      </file>\n    </example>\n *\n * @element INPUT\n * @param {expression} ngReadonly If the {@link guide/expression expression} is truthy,\n *     then special attribute \"readonly\" will be set on the element\n */\n\n\n/**\n * @ngdoc directive\n * @name ngSelected\n * @restrict A\n * @priority 100\n *\n * @description\n *\n * Sets the `selected` attribute on the element, if the expression inside `ngSelected` is truthy.\n *\n * A special directive is necessary because we cannot use interpolation inside the `selected`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * <div class=\"alert alert-warning\">\n *   **Note:** `ngSelected` does not interact with the `select` and `ngModel` directives, it only\n *   sets the `selected` attribute on the element. If you are using `ngModel` on the select, you\n *   should not use `ngSelected` on the options, as `ngModel` will set the select value and\n *   selected options.\n * </div>\n *\n * @example\n    <example name=\"ng-selected\">\n      <file name=\"index.html\">\n        <label>Check me to select: <input type=\"checkbox\" ng-model=\"selected\"></label><br/>\n        <select aria-label=\"ngSelected demo\">\n          <option>Hello!</option>\n          <option id=\"greet\" ng-selected=\"selected\">Greetings!</option>\n        </select>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should select Greetings!', function() {\n          expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy();\n          element(by.model('selected')).click();\n          expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy();\n        });\n      </file>\n    </example>\n *\n * @element OPTION\n * @param {expression} ngSelected If the {@link guide/expression expression} is truthy,\n *     then special attribute \"selected\" will be set on the element\n */\n\n/**\n * @ngdoc directive\n * @name ngOpen\n * @restrict A\n * @priority 100\n *\n * @description\n *\n * Sets the `open` attribute on the element, if the expression inside `ngOpen` is truthy.\n *\n * A special directive is necessary because we cannot use interpolation inside the `open`\n * attribute. See the {@link guide/interpolation interpolation guide} for more info.\n *\n * ## A note about browser compatibility\n *\n * Edge, Firefox, and Internet Explorer do not support the `details` element, it is\n * recommended to use {@link ng.ngShow} and {@link ng.ngHide} instead.\n *\n * @example\n     <example name=\"ng-open\">\n       <file name=\"index.html\">\n         <label>Check me check multiple: <input type=\"checkbox\" ng-model=\"open\"></label><br/>\n         <details id=\"details\" ng-open=\"open\">\n            <summary>Show/Hide me</summary>\n         </details>\n       </file>\n       <file name=\"protractor.js\" type=\"protractor\">\n         it('should toggle open', function() {\n           expect(element(by.id('details')).getAttribute('open')).toBeFalsy();\n           element(by.model('open')).click();\n           expect(element(by.id('details')).getAttribute('open')).toBeTruthy();\n         });\n       </file>\n     </example>\n *\n * @element DETAILS\n * @param {expression} ngOpen If the {@link guide/expression expression} is truthy,\n *     then special attribute \"open\" will be set on the element\n */\n\nvar ngAttributeAliasDirectives = {};\n\n// boolean attrs are evaluated\nforEach(BOOLEAN_ATTR, function(propName, attrName) {\n  // binding to multiple is not supported\n  if (propName === 'multiple') return;\n\n  function defaultLinkFn(scope, element, attr) {\n    scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {\n      attr.$set(attrName, !!value);\n    });\n  }\n\n  var normalized = directiveNormalize('ng-' + attrName);\n  var linkFn = defaultLinkFn;\n\n  if (propName === 'checked') {\n    linkFn = function(scope, element, attr) {\n      // ensuring ngChecked doesn't interfere with ngModel when both are set on the same input\n      if (attr.ngModel !== attr[normalized]) {\n        defaultLinkFn(scope, element, attr);\n      }\n    };\n  }\n\n  ngAttributeAliasDirectives[normalized] = function() {\n    return {\n      restrict: 'A',\n      priority: 100,\n      link: linkFn\n    };\n  };\n});\n\n// aliased input attrs are evaluated\nforEach(ALIASED_ATTR, function(htmlAttr, ngAttr) {\n  ngAttributeAliasDirectives[ngAttr] = function() {\n    return {\n      priority: 100,\n      link: function(scope, element, attr) {\n        //special case ngPattern when a literal regular expression value\n        //is used as the expression (this way we don't have to watch anything).\n        if (ngAttr === 'ngPattern' && attr.ngPattern.charAt(0) === '/') {\n          var match = attr.ngPattern.match(REGEX_STRING_REGEXP);\n          if (match) {\n            attr.$set('ngPattern', new RegExp(match[1], match[2]));\n            return;\n          }\n        }\n\n        scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) {\n          attr.$set(ngAttr, value);\n        });\n      }\n    };\n  };\n});\n\n// ng-src, ng-srcset, ng-href are interpolated\nforEach(['src', 'srcset', 'href'], function(attrName) {\n  var normalized = directiveNormalize('ng-' + attrName);\n  ngAttributeAliasDirectives[normalized] = function() {\n    return {\n      priority: 99, // it needs to run after the attributes are interpolated\n      link: function(scope, element, attr) {\n        var propName = attrName,\n            name = attrName;\n\n        if (attrName === 'href' &&\n            toString.call(element.prop('href')) === '[object SVGAnimatedString]') {\n          name = 'xlinkHref';\n          attr.$attr[name] = 'xlink:href';\n          propName = null;\n        }\n\n        attr.$observe(normalized, function(value) {\n          if (!value) {\n            if (attrName === 'href') {\n              attr.$set(name, null);\n            }\n            return;\n          }\n\n          attr.$set(name, value);\n\n          // Support: IE 9-11 only\n          // On IE, if \"ng:src\" directive declaration is used and \"src\" attribute doesn't exist\n          // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need\n          // to set the property as well to achieve the desired effect.\n          // We use attr[attrName] value since $set can sanitize the url.\n          if (msie && propName) element.prop(propName, attr[name]);\n        });\n      }\n    };\n  };\n});\n\n/* global -nullFormCtrl, -PENDING_CLASS, -SUBMITTED_CLASS\n */\nvar nullFormCtrl = {\n  $addControl: noop,\n  $$renameControl: nullFormRenameControl,\n  $removeControl: noop,\n  $setValidity: noop,\n  $setDirty: noop,\n  $setPristine: noop,\n  $setSubmitted: noop\n},\nPENDING_CLASS = 'ng-pending',\nSUBMITTED_CLASS = 'ng-submitted';\n\nfunction nullFormRenameControl(control, name) {\n  control.$name = name;\n}\n\n/**\n * @ngdoc type\n * @name form.FormController\n *\n * @property {boolean} $pristine True if user has not interacted with the form yet.\n * @property {boolean} $dirty True if user has already interacted with the form.\n * @property {boolean} $valid True if all of the containing forms and controls are valid.\n * @property {boolean} $invalid True if at least one containing control or form is invalid.\n * @property {boolean} $pending True if at least one containing control or form is pending.\n * @property {boolean} $submitted True if user has submitted the form even if its invalid.\n *\n * @property {Object} $error Is an object hash, containing references to controls or\n *  forms with failing validators, where:\n *\n *  - keys are validation tokens (error names),\n *  - values are arrays of controls or forms that have a failing validator for given error name.\n *\n *  Built-in validation tokens:\n *\n *  - `email`\n *  - `max`\n *  - `maxlength`\n *  - `min`\n *  - `minlength`\n *  - `number`\n *  - `pattern`\n *  - `required`\n *  - `url`\n *  - `date`\n *  - `datetimelocal`\n *  - `time`\n *  - `week`\n *  - `month`\n *\n * @description\n * `FormController` keeps track of all its controls and nested forms as well as the state of them,\n * such as being valid/invalid or dirty/pristine.\n *\n * Each {@link ng.directive:form form} directive creates an instance\n * of `FormController`.\n *\n */\n//asks for $scope to fool the BC controller module\nFormController.$inject = ['$element', '$attrs', '$scope', '$animate', '$interpolate'];\nfunction FormController($element, $attrs, $scope, $animate, $interpolate) {\n  this.$$controls = [];\n\n  // init state\n  this.$error = {};\n  this.$$success = {};\n  this.$pending = undefined;\n  this.$name = $interpolate($attrs.name || $attrs.ngForm || '')($scope);\n  this.$dirty = false;\n  this.$pristine = true;\n  this.$valid = true;\n  this.$invalid = false;\n  this.$submitted = false;\n  this.$$parentForm = nullFormCtrl;\n\n  this.$$element = $element;\n  this.$$animate = $animate;\n\n  setupValidity(this);\n}\n\nFormController.prototype = {\n  /**\n   * @ngdoc method\n   * @name form.FormController#$rollbackViewValue\n   *\n   * @description\n   * Rollback all form controls pending updates to the `$modelValue`.\n   *\n   * Updates may be pending by a debounced event or because the input is waiting for a some future\n   * event defined in `ng-model-options`. This method is typically needed by the reset button of\n   * a form that uses `ng-model-options` to pend updates.\n   */\n  $rollbackViewValue: function() {\n    forEach(this.$$controls, function(control) {\n      control.$rollbackViewValue();\n    });\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$commitViewValue\n   *\n   * @description\n   * Commit all form controls pending updates to the `$modelValue`.\n   *\n   * Updates may be pending by a debounced event or because the input is waiting for a some future\n   * event defined in `ng-model-options`. This method is rarely needed as `NgModelController`\n   * usually handles calling this in response to input events.\n   */\n  $commitViewValue: function() {\n    forEach(this.$$controls, function(control) {\n      control.$commitViewValue();\n    });\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$addControl\n   * @param {object} control control object, either a {@link form.FormController} or an\n   * {@link ngModel.NgModelController}\n   *\n   * @description\n   * Register a control with the form. Input elements using ngModelController do this automatically\n   * when they are linked.\n   *\n   * Note that the current state of the control will not be reflected on the new parent form. This\n   * is not an issue with normal use, as freshly compiled and linked controls are in a `$pristine`\n   * state.\n   *\n   * However, if the method is used programmatically, for example by adding dynamically created controls,\n   * or controls that have been previously removed without destroying their corresponding DOM element,\n   * it's the developers responsibility to make sure the current state propagates to the parent form.\n   *\n   * For example, if an input control is added that is already `$dirty` and has `$error` properties,\n   * calling `$setDirty()` and `$validate()` afterwards will propagate the state to the parent form.\n   */\n  $addControl: function(control) {\n    // Breaking change - before, inputs whose name was \"hasOwnProperty\" were quietly ignored\n    // and not added to the scope.  Now we throw an error.\n    assertNotHasOwnProperty(control.$name, 'input');\n    this.$$controls.push(control);\n\n    if (control.$name) {\n      this[control.$name] = control;\n    }\n\n    control.$$parentForm = this;\n  },\n\n  // Private API: rename a form control\n  $$renameControl: function(control, newName) {\n    var oldName = control.$name;\n\n    if (this[oldName] === control) {\n      delete this[oldName];\n    }\n    this[newName] = control;\n    control.$name = newName;\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$removeControl\n   * @param {object} control control object, either a {@link form.FormController} or an\n   * {@link ngModel.NgModelController}\n   *\n   * @description\n   * Deregister a control from the form.\n   *\n   * Input elements using ngModelController do this automatically when they are destroyed.\n   *\n   * Note that only the removed control's validation state (`$errors`etc.) will be removed from the\n   * form. `$dirty`, `$submitted` states will not be changed, because the expected behavior can be\n   * different from case to case. For example, removing the only `$dirty` control from a form may or\n   * may not mean that the form is still `$dirty`.\n   */\n  $removeControl: function(control) {\n    if (control.$name && this[control.$name] === control) {\n      delete this[control.$name];\n    }\n    forEach(this.$pending, function(value, name) {\n      // eslint-disable-next-line no-invalid-this\n      this.$setValidity(name, null, control);\n    }, this);\n    forEach(this.$error, function(value, name) {\n      // eslint-disable-next-line no-invalid-this\n      this.$setValidity(name, null, control);\n    }, this);\n    forEach(this.$$success, function(value, name) {\n      // eslint-disable-next-line no-invalid-this\n      this.$setValidity(name, null, control);\n    }, this);\n\n    arrayRemove(this.$$controls, control);\n    control.$$parentForm = nullFormCtrl;\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$setDirty\n   *\n   * @description\n   * Sets the form to a dirty state.\n   *\n   * This method can be called to add the 'ng-dirty' class and set the form to a dirty\n   * state (ng-dirty class). This method will also propagate to parent forms.\n   */\n  $setDirty: function() {\n    this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);\n    this.$$animate.addClass(this.$$element, DIRTY_CLASS);\n    this.$dirty = true;\n    this.$pristine = false;\n    this.$$parentForm.$setDirty();\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$setPristine\n   *\n   * @description\n   * Sets the form to its pristine state.\n   *\n   * This method sets the form's `$pristine` state to true, the `$dirty` state to false, removes\n   * the `ng-dirty` class and adds the `ng-pristine` class. Additionally, it sets the `$submitted`\n   * state to false.\n   *\n   * This method will also propagate to all the controls contained in this form.\n   *\n   * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after\n   * saving or resetting it.\n   */\n  $setPristine: function() {\n    this.$$animate.setClass(this.$$element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);\n    this.$dirty = false;\n    this.$pristine = true;\n    this.$submitted = false;\n    forEach(this.$$controls, function(control) {\n      control.$setPristine();\n    });\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$setUntouched\n   *\n   * @description\n   * Sets the form to its untouched state.\n   *\n   * This method can be called to remove the 'ng-touched' class and set the form controls to their\n   * untouched state (ng-untouched class).\n   *\n   * Setting a form controls back to their untouched state is often useful when setting the form\n   * back to its pristine state.\n   */\n  $setUntouched: function() {\n    forEach(this.$$controls, function(control) {\n      control.$setUntouched();\n    });\n  },\n\n  /**\n   * @ngdoc method\n   * @name form.FormController#$setSubmitted\n   *\n   * @description\n   * Sets the form to its submitted state.\n   */\n  $setSubmitted: function() {\n    this.$$animate.addClass(this.$$element, SUBMITTED_CLASS);\n    this.$submitted = true;\n    this.$$parentForm.$setSubmitted();\n  }\n};\n\n/**\n * @ngdoc method\n * @name form.FormController#$setValidity\n *\n * @description\n * Sets the validity of a form control.\n *\n * This method will also propagate to parent forms.\n */\naddSetValidityMethod({\n  clazz: FormController,\n  set: function(object, property, controller) {\n    var list = object[property];\n    if (!list) {\n      object[property] = [controller];\n    } else {\n      var index = list.indexOf(controller);\n      if (index === -1) {\n        list.push(controller);\n      }\n    }\n  },\n  unset: function(object, property, controller) {\n    var list = object[property];\n    if (!list) {\n      return;\n    }\n    arrayRemove(list, controller);\n    if (list.length === 0) {\n      delete object[property];\n    }\n  }\n});\n\n/**\n * @ngdoc directive\n * @name ngForm\n * @restrict EAC\n *\n * @description\n * Nestable alias of {@link ng.directive:form `form`} directive. HTML\n * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a\n * sub-group of controls needs to be determined.\n *\n * Note: the purpose of `ngForm` is to group controls,\n * but not to be a replacement for the `<form>` tag with all of its capabilities\n * (e.g. posting to the server, ...).\n *\n * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into\n *                       related scope, under this name.\n *\n */\n\n /**\n * @ngdoc directive\n * @name form\n * @restrict E\n *\n * @description\n * Directive that instantiates\n * {@link form.FormController FormController}.\n *\n * If the `name` attribute is specified, the form controller is published onto the current scope under\n * this name.\n *\n * # Alias: {@link ng.directive:ngForm `ngForm`}\n *\n * In Angular, forms can be nested. This means that the outer form is valid when all of the child\n * forms are valid as well. However, browsers do not allow nesting of `<form>` elements, so\n * Angular provides the {@link ng.directive:ngForm `ngForm`} directive, which behaves identically to\n * `form` but can be nested. Nested forms can be useful, for example, if the validity of a sub-group\n * of controls needs to be determined.\n *\n * # CSS classes\n *  - `ng-valid` is set if the form is valid.\n *  - `ng-invalid` is set if the form is invalid.\n *  - `ng-pending` is set if the form is pending.\n *  - `ng-pristine` is set if the form is pristine.\n *  - `ng-dirty` is set if the form is dirty.\n *  - `ng-submitted` is set if the form was submitted.\n *\n * Keep in mind that ngAnimate can detect each of these classes when added and removed.\n *\n *\n * # Submitting a form and preventing the default action\n *\n * Since the role of forms in client-side Angular applications is different than in classical\n * roundtrip apps, it is desirable for the browser not to translate the form submission into a full\n * page reload that sends the data to the server. Instead some javascript logic should be triggered\n * to handle the form submission in an application-specific way.\n *\n * For this reason, Angular prevents the default action (form submission to the server) unless the\n * `<form>` element has an `action` attribute specified.\n *\n * You can use one of the following two ways to specify what javascript method should be called when\n * a form is submitted:\n *\n * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element\n * - {@link ng.directive:ngClick ngClick} directive on the first\n  *  button or input field of type submit (input[type=submit])\n *\n * To prevent double execution of the handler, use only one of the {@link ng.directive:ngSubmit ngSubmit}\n * or {@link ng.directive:ngClick ngClick} directives.\n * This is because of the following form submission rules in the HTML specification:\n *\n * - If a form has only one input field then hitting enter in this field triggers form submit\n * (`ngSubmit`)\n * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter\n * doesn't trigger submit\n * - if a form has one or more input fields and one or more buttons or input[type=submit] then\n * hitting enter in any of the input fields will trigger the click handler on the *first* button or\n * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`)\n *\n * Any pending `ngModelOptions` changes will take place immediately when an enclosing form is\n * submitted. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`\n * to have access to the updated model.\n *\n * ## Animation Hooks\n *\n * Animations in ngForm are triggered when any of the associated CSS classes are added and removed.\n * These classes are: `.ng-pristine`, `.ng-dirty`, `.ng-invalid` and `.ng-valid` as well as any\n * other validations that are performed within the form. Animations in ngForm are similar to how\n * they work in ngClass and animations can be hooked into using CSS transitions, keyframes as well\n * as JS animations.\n *\n * The following example shows a simple way to utilize CSS transitions to style a form element\n * that has been rendered as invalid after it has been validated:\n *\n * <pre>\n * //be sure to include ngAnimate as a module to hook into more\n * //advanced animations\n * .my-form {\n *   transition:0.5s linear all;\n *   background: white;\n * }\n * .my-form.ng-invalid {\n *   background: red;\n *   color:white;\n * }\n * </pre>\n *\n * @example\n    <example name=\"ng-form\" deps=\"angular-animate.js\" animations=\"true\" fixBase=\"true\" module=\"formExample\">\n      <file name=\"index.html\">\n       <script>\n         angular.module('formExample', [])\n           .controller('FormController', ['$scope', function($scope) {\n             $scope.userType = 'guest';\n           }]);\n       </script>\n       <style>\n        .my-form {\n          transition:all linear 0.5s;\n          background: transparent;\n        }\n        .my-form.ng-invalid {\n          background: red;\n        }\n       </style>\n       <form name=\"myForm\" ng-controller=\"FormController\" class=\"my-form\">\n         userType: <input name=\"input\" ng-model=\"userType\" required>\n         <span class=\"error\" ng-show=\"myForm.input.$error.required\">Required!</span><br>\n         <code>userType = {{userType}}</code><br>\n         <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br>\n         <code>myForm.input.$error = {{myForm.input.$error}}</code><br>\n         <code>myForm.$valid = {{myForm.$valid}}</code><br>\n         <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br>\n        </form>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should initialize to model', function() {\n          var userType = element(by.binding('userType'));\n          var valid = element(by.binding('myForm.input.$valid'));\n\n          expect(userType.getText()).toContain('guest');\n          expect(valid.getText()).toContain('true');\n        });\n\n        it('should be invalid if empty', function() {\n          var userType = element(by.binding('userType'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var userInput = element(by.model('userType'));\n\n          userInput.clear();\n          userInput.sendKeys('');\n\n          expect(userType.getText()).toEqual('userType =');\n          expect(valid.getText()).toContain('false');\n        });\n      </file>\n    </example>\n *\n * @param {string=} name Name of the form. If specified, the form controller will be published into\n *                       related scope, under this name.\n */\nvar formDirectiveFactory = function(isNgForm) {\n  return ['$timeout', '$parse', function($timeout, $parse) {\n    var formDirective = {\n      name: 'form',\n      restrict: isNgForm ? 'EAC' : 'E',\n      require: ['form', '^^?form'], //first is the form's own ctrl, second is an optional parent form\n      controller: FormController,\n      compile: function ngFormCompile(formElement, attr) {\n        // Setup initial state of the control\n        formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS);\n\n        var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false);\n\n        return {\n          pre: function ngFormPreLink(scope, formElement, attr, ctrls) {\n            var controller = ctrls[0];\n\n            // if `action` attr is not present on the form, prevent the default action (submission)\n            if (!('action' in attr)) {\n              // we can't use jq events because if a form is destroyed during submission the default\n              // action is not prevented. see #1238\n              //\n              // IE 9 is not affected because it doesn't fire a submit event and try to do a full\n              // page reload if the form was destroyed by submission of the form via a click handler\n              // on a button in the form. Looks like an IE9 specific bug.\n              var handleFormSubmission = function(event) {\n                scope.$apply(function() {\n                  controller.$commitViewValue();\n                  controller.$setSubmitted();\n                });\n\n                event.preventDefault();\n              };\n\n              formElement[0].addEventListener('submit', handleFormSubmission);\n\n              // unregister the preventDefault listener so that we don't not leak memory but in a\n              // way that will achieve the prevention of the default action.\n              formElement.on('$destroy', function() {\n                $timeout(function() {\n                  formElement[0].removeEventListener('submit', handleFormSubmission);\n                }, 0, false);\n              });\n            }\n\n            var parentFormCtrl = ctrls[1] || controller.$$parentForm;\n            parentFormCtrl.$addControl(controller);\n\n            var setter = nameAttr ? getSetter(controller.$name) : noop;\n\n            if (nameAttr) {\n              setter(scope, controller);\n              attr.$observe(nameAttr, function(newValue) {\n                if (controller.$name === newValue) return;\n                setter(scope, undefined);\n                controller.$$parentForm.$$renameControl(controller, newValue);\n                setter = getSetter(controller.$name);\n                setter(scope, controller);\n              });\n            }\n            formElement.on('$destroy', function() {\n              controller.$$parentForm.$removeControl(controller);\n              setter(scope, undefined);\n              extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards\n            });\n          }\n        };\n      }\n    };\n\n    return formDirective;\n\n    function getSetter(expression) {\n      if (expression === '') {\n        //create an assignable expression, so forms with an empty name can be renamed later\n        return $parse('this[\"\"]').assign;\n      }\n      return $parse(expression).assign || noop;\n    }\n  }];\n};\n\nvar formDirective = formDirectiveFactory();\nvar ngFormDirective = formDirectiveFactory(true);\n\n\n\n// helper methods\nfunction setupValidity(instance) {\n  instance.$$classCache = {};\n  instance.$$classCache[INVALID_CLASS] = !(instance.$$classCache[VALID_CLASS] = instance.$$element.hasClass(VALID_CLASS));\n}\nfunction addSetValidityMethod(context) {\n  var clazz = context.clazz,\n      set = context.set,\n      unset = context.unset;\n\n  clazz.prototype.$setValidity = function(validationErrorKey, state, controller) {\n    if (isUndefined(state)) {\n      createAndSet(this, '$pending', validationErrorKey, controller);\n    } else {\n      unsetAndCleanup(this, '$pending', validationErrorKey, controller);\n    }\n    if (!isBoolean(state)) {\n      unset(this.$error, validationErrorKey, controller);\n      unset(this.$$success, validationErrorKey, controller);\n    } else {\n      if (state) {\n        unset(this.$error, validationErrorKey, controller);\n        set(this.$$success, validationErrorKey, controller);\n      } else {\n        set(this.$error, validationErrorKey, controller);\n        unset(this.$$success, validationErrorKey, controller);\n      }\n    }\n    if (this.$pending) {\n      cachedToggleClass(this, PENDING_CLASS, true);\n      this.$valid = this.$invalid = undefined;\n      toggleValidationCss(this, '', null);\n    } else {\n      cachedToggleClass(this, PENDING_CLASS, false);\n      this.$valid = isObjectEmpty(this.$error);\n      this.$invalid = !this.$valid;\n      toggleValidationCss(this, '', this.$valid);\n    }\n\n    // re-read the state as the set/unset methods could have\n    // combined state in this.$error[validationError] (used for forms),\n    // where setting/unsetting only increments/decrements the value,\n    // and does not replace it.\n    var combinedState;\n    if (this.$pending && this.$pending[validationErrorKey]) {\n      combinedState = undefined;\n    } else if (this.$error[validationErrorKey]) {\n      combinedState = false;\n    } else if (this.$$success[validationErrorKey]) {\n      combinedState = true;\n    } else {\n      combinedState = null;\n    }\n\n    toggleValidationCss(this, validationErrorKey, combinedState);\n    this.$$parentForm.$setValidity(validationErrorKey, combinedState, this);\n  };\n\n  function createAndSet(ctrl, name, value, controller) {\n    if (!ctrl[name]) {\n      ctrl[name] = {};\n    }\n    set(ctrl[name], value, controller);\n  }\n\n  function unsetAndCleanup(ctrl, name, value, controller) {\n    if (ctrl[name]) {\n      unset(ctrl[name], value, controller);\n    }\n    if (isObjectEmpty(ctrl[name])) {\n      ctrl[name] = undefined;\n    }\n  }\n\n  function cachedToggleClass(ctrl, className, switchValue) {\n    if (switchValue && !ctrl.$$classCache[className]) {\n      ctrl.$$animate.addClass(ctrl.$$element, className);\n      ctrl.$$classCache[className] = true;\n    } else if (!switchValue && ctrl.$$classCache[className]) {\n      ctrl.$$animate.removeClass(ctrl.$$element, className);\n      ctrl.$$classCache[className] = false;\n    }\n  }\n\n  function toggleValidationCss(ctrl, validationErrorKey, isValid) {\n    validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';\n\n    cachedToggleClass(ctrl, VALID_CLASS + validationErrorKey, isValid === true);\n    cachedToggleClass(ctrl, INVALID_CLASS + validationErrorKey, isValid === false);\n  }\n}\n\nfunction isObjectEmpty(obj) {\n  if (obj) {\n    for (var prop in obj) {\n      if (obj.hasOwnProperty(prop)) {\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\n/* global\n  VALID_CLASS: false,\n  INVALID_CLASS: false,\n  PRISTINE_CLASS: false,\n  DIRTY_CLASS: false,\n  ngModelMinErr: false\n*/\n\n// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231\nvar ISO_DATE_REGEXP = /^\\d{4,}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+(?:[+-][0-2]\\d:[0-5]\\d|Z)$/;\n// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)\n// Note: We are being more lenient, because browsers are too.\n//   1. Scheme\n//   2. Slashes\n//   3. Username\n//   4. Password\n//   5. Hostname\n//   6. Port\n//   7. Path\n//   8. Query\n//   9. Fragment\n//                 1111111111111111 222   333333    44444        55555555555555555555555     666     77777777     8888888     999\nvar URL_REGEXP = /^[a-z][a-z\\d.+-]*:\\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\\s:/?#]+|\\[[a-f\\d:]+])(?::\\d+)?(?:\\/[^?#]*)?(?:\\?[^#]*)?(?:#.*)?$/i;\n// eslint-disable-next-line max-len\nvar EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;\nvar NUMBER_REGEXP = /^\\s*(-|\\+)?(\\d+|(\\d*(\\.\\d*)))([eE][+-]?\\d+)?\\s*$/;\nvar DATE_REGEXP = /^(\\d{4,})-(\\d{2})-(\\d{2})$/;\nvar DATETIMELOCAL_REGEXP = /^(\\d{4,})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d)(?::(\\d\\d)(\\.\\d{1,3})?)?$/;\nvar WEEK_REGEXP = /^(\\d{4,})-W(\\d\\d)$/;\nvar MONTH_REGEXP = /^(\\d{4,})-(\\d\\d)$/;\nvar TIME_REGEXP = /^(\\d\\d):(\\d\\d)(?::(\\d\\d)(\\.\\d{1,3})?)?$/;\n\nvar PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown';\nvar PARTIAL_VALIDATION_TYPES = createMap();\nforEach('date,datetime-local,month,time,week'.split(','), function(type) {\n  PARTIAL_VALIDATION_TYPES[type] = true;\n});\n\nvar inputType = {\n\n  /**\n   * @ngdoc input\n   * @name input[text]\n   *\n   * @description\n   * Standard HTML text input with angular data binding, inherited by most of the `input` elements.\n   *\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} required Adds `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n   *    minlength.\n   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of\n   *    any length.\n   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string\n   *    that contains the regular expression body that will be converted to a regular expression\n   *    as in the ngPattern directive.\n   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n   *    If the expression evaluates to a RegExp object, then this is used directly.\n   *    If the expression evaluates to a string, then it will be converted to a RegExp\n   *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n   *    `new RegExp('^abc$')`.<br />\n   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n   *    start at the index of the last search's match, thus not taking the whole input value into\n   *    account.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.\n   *    This parameter is ignored for input[type=password] controls, which will never trim the\n   *    input.\n   *\n   * @example\n      <example name=\"text-input-directive\" module=\"textInputExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('textInputExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.example = {\n                 text: 'guest',\n                 word: /^\\s*\\w*\\s*$/\n               };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>Single word:\n             <input type=\"text\" name=\"input\" ng-model=\"example.text\"\n                    ng-pattern=\"example.word\" required ng-trim=\"false\">\n           </label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n               Required!</span>\n             <span class=\"error\" ng-show=\"myForm.input.$error.pattern\">\n               Single word only!</span>\n           </div>\n           <code>text = {{example.text}}</code><br/>\n           <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br/>\n           <code>myForm.input.$error = {{myForm.input.$error}}</code><br/>\n           <code>myForm.$valid = {{myForm.$valid}}</code><br/>\n           <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br/>\n          </form>\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var text = element(by.binding('example.text'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var input = element(by.model('example.text'));\n\n          it('should initialize to model', function() {\n            expect(text.getText()).toContain('guest');\n            expect(valid.getText()).toContain('true');\n          });\n\n          it('should be invalid if empty', function() {\n            input.clear();\n            input.sendKeys('');\n\n            expect(text.getText()).toEqual('text =');\n            expect(valid.getText()).toContain('false');\n          });\n\n          it('should be invalid if multi word', function() {\n            input.clear();\n            input.sendKeys('hello world');\n\n            expect(valid.getText()).toContain('false');\n          });\n        </file>\n      </example>\n   */\n  'text': textInputType,\n\n    /**\n     * @ngdoc input\n     * @name input[date]\n     *\n     * @description\n     * Input with date validation and transformation. In browsers that do not yet support\n     * the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601\n     * date format (yyyy-MM-dd), for example: `2009-01-06`. Since many\n     * modern browsers do not yet support this input type, it is important to provide cues to users on the\n     * expected input format via a placeholder or label.\n     *\n     * The model must always be a Date object, otherwise Angular will throw an error.\n     * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n     *\n     * The timezone to be used to read/write the `Date` instance in the model can be defined using\n     * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n     *\n     * @param {string} ngModel Assignable angular expression to data-bind to.\n     * @param {string=} name Property name of the form under which the control is published.\n     * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a\n     *   valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute\n     *   (e.g. `min=\"{{minDate | date:'yyyy-MM-dd'}}\"`). Note that `min` will also add native HTML5\n     *   constraint validation.\n     * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be\n     *   a valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute\n     *   (e.g. `max=\"{{maxDate | date:'yyyy-MM-dd'}}\"`). Note that `max` will also add native HTML5\n     *   constraint validation.\n     * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO date string\n     *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n     * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO date string\n     *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n     * @param {string=} required Sets `required` validation error key if the value is not entered.\n     * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n     *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n     *    `required` when you want to data-bind to the `required` attribute.\n     * @param {string=} ngChange Angular expression to be executed when input changes due to user\n     *    interaction with the input element.\n     *\n     * @example\n     <example name=\"date-input-directive\" module=\"dateInputExample\">\n     <file name=\"index.html\">\n       <script>\n          angular.module('dateInputExample', [])\n            .controller('DateController', ['$scope', function($scope) {\n              $scope.example = {\n                value: new Date(2013, 9, 22)\n              };\n            }]);\n       </script>\n       <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n          <label for=\"exampleInput\">Pick a date in 2013:</label>\n          <input type=\"date\" id=\"exampleInput\" name=\"input\" ng-model=\"example.value\"\n              placeholder=\"yyyy-MM-dd\" min=\"2013-01-01\" max=\"2013-12-31\" required />\n          <div role=\"alert\">\n            <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n                Required!</span>\n            <span class=\"error\" ng-show=\"myForm.input.$error.date\">\n                Not a valid date!</span>\n           </div>\n           <tt>value = {{example.value | date: \"yyyy-MM-dd\"}}</tt><br/>\n           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n       </form>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n        var value = element(by.binding('example.value | date: \"yyyy-MM-dd\"'));\n        var valid = element(by.binding('myForm.input.$valid'));\n\n        // currently protractor/webdriver does not support\n        // sending keys to all known HTML5 input controls\n        // for various browsers (see https://github.com/angular/protractor/issues/562).\n        function setInput(val) {\n          // set the value of the element and force validation.\n          var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n          \"ipt.value = '\" + val + \"';\" +\n          \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n          browser.executeScript(scr);\n        }\n\n        it('should initialize to model', function() {\n          expect(value.getText()).toContain('2013-10-22');\n          expect(valid.getText()).toContain('myForm.input.$valid = true');\n        });\n\n        it('should be invalid if empty', function() {\n          setInput('');\n          expect(value.getText()).toEqual('value =');\n          expect(valid.getText()).toContain('myForm.input.$valid = false');\n        });\n\n        it('should be invalid if over max', function() {\n          setInput('2015-01-01');\n          expect(value.getText()).toContain('');\n          expect(valid.getText()).toContain('myForm.input.$valid = false');\n        });\n     </file>\n     </example>\n     */\n  'date': createDateInputType('date', DATE_REGEXP,\n         createDateParser(DATE_REGEXP, ['yyyy', 'MM', 'dd']),\n         'yyyy-MM-dd'),\n\n   /**\n    * @ngdoc input\n    * @name input[datetime-local]\n    *\n    * @description\n    * Input with datetime validation and transformation. In browsers that do not yet support\n    * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601\n    * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`.\n    *\n    * The model must always be a Date object, otherwise Angular will throw an error.\n    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n    *\n    * The timezone to be used to read/write the `Date` instance in the model can be defined using\n    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n    *\n    * @param {string} ngModel Assignable angular expression to data-bind to.\n    * @param {string=} name Property name of the form under which the control is published.\n    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n    *   This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation\n    *   inside this attribute (e.g. `min=\"{{minDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}\"`).\n    *   Note that `min` will also add native HTML5 constraint validation.\n    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n    *   This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation\n    *   inside this attribute (e.g. `max=\"{{maxDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}\"`).\n    *   Note that `max` will also add native HTML5 constraint validation.\n    * @param {(date|string)=} ngMin Sets the `min` validation error key to the Date / ISO datetime string\n    *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n    * @param {(date|string)=} ngMax Sets the `max` validation error key to the Date / ISO datetime string\n    *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n    * @param {string=} required Sets `required` validation error key if the value is not entered.\n    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n    *    `required` when you want to data-bind to the `required` attribute.\n    * @param {string=} ngChange Angular expression to be executed when input changes due to user\n    *    interaction with the input element.\n    *\n    * @example\n    <example name=\"datetimelocal-input-directive\" module=\"dateExample\">\n    <file name=\"index.html\">\n      <script>\n        angular.module('dateExample', [])\n          .controller('DateController', ['$scope', function($scope) {\n            $scope.example = {\n              value: new Date(2010, 11, 28, 14, 57)\n            };\n          }]);\n      </script>\n      <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n        <label for=\"exampleInput\">Pick a date between in 2013:</label>\n        <input type=\"datetime-local\" id=\"exampleInput\" name=\"input\" ng-model=\"example.value\"\n            placeholder=\"yyyy-MM-ddTHH:mm:ss\" min=\"2001-01-01T00:00:00\" max=\"2013-12-31T00:00:00\" required />\n        <div role=\"alert\">\n          <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n              Required!</span>\n          <span class=\"error\" ng-show=\"myForm.input.$error.datetimelocal\">\n              Not a valid date!</span>\n        </div>\n        <tt>value = {{example.value | date: \"yyyy-MM-ddTHH:mm:ss\"}}</tt><br/>\n        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n      </form>\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var value = element(by.binding('example.value | date: \"yyyy-MM-ddTHH:mm:ss\"'));\n      var valid = element(by.binding('myForm.input.$valid'));\n\n      // currently protractor/webdriver does not support\n      // sending keys to all known HTML5 input controls\n      // for various browsers (https://github.com/angular/protractor/issues/562).\n      function setInput(val) {\n        // set the value of the element and force validation.\n        var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n        \"ipt.value = '\" + val + \"';\" +\n        \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n        browser.executeScript(scr);\n      }\n\n      it('should initialize to model', function() {\n        expect(value.getText()).toContain('2010-12-28T14:57:00');\n        expect(valid.getText()).toContain('myForm.input.$valid = true');\n      });\n\n      it('should be invalid if empty', function() {\n        setInput('');\n        expect(value.getText()).toEqual('value =');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n\n      it('should be invalid if over max', function() {\n        setInput('2015-01-01T23:59:00');\n        expect(value.getText()).toContain('');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n    </file>\n    </example>\n    */\n  'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP,\n      createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']),\n      'yyyy-MM-ddTHH:mm:ss.sss'),\n\n  /**\n   * @ngdoc input\n   * @name input[time]\n   *\n   * @description\n   * Input with time validation and transformation. In browsers that do not yet support\n   * the HTML5 time input, a text element will be used. In that case, the text must be entered in a valid ISO-8601\n   * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a\n   * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`.\n   *\n   * The model must always be a Date object, otherwise Angular will throw an error.\n   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n   *\n   * The timezone to be used to read/write the `Date` instance in the model can be defined using\n   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n   *   This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this\n   *   attribute (e.g. `min=\"{{minTime | date:'HH:mm:ss'}}\"`). Note that `min` will also add\n   *   native HTML5 constraint validation.\n   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n   *   This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this\n   *   attribute (e.g. `max=\"{{maxTime | date:'HH:mm:ss'}}\"`). Note that `max` will also add\n   *   native HTML5 constraint validation.\n   * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO time string the\n   *   `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n   * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO time string the\n   *   `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n   <example name=\"time-input-directive\" module=\"timeExample\">\n   <file name=\"index.html\">\n     <script>\n      angular.module('timeExample', [])\n        .controller('DateController', ['$scope', function($scope) {\n          $scope.example = {\n            value: new Date(1970, 0, 1, 14, 57, 0)\n          };\n        }]);\n     </script>\n     <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n        <label for=\"exampleInput\">Pick a time between 8am and 5pm:</label>\n        <input type=\"time\" id=\"exampleInput\" name=\"input\" ng-model=\"example.value\"\n            placeholder=\"HH:mm:ss\" min=\"08:00:00\" max=\"17:00:00\" required />\n        <div role=\"alert\">\n          <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n              Required!</span>\n          <span class=\"error\" ng-show=\"myForm.input.$error.time\">\n              Not a valid date!</span>\n        </div>\n        <tt>value = {{example.value | date: \"HH:mm:ss\"}}</tt><br/>\n        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n     </form>\n   </file>\n   <file name=\"protractor.js\" type=\"protractor\">\n      var value = element(by.binding('example.value | date: \"HH:mm:ss\"'));\n      var valid = element(by.binding('myForm.input.$valid'));\n\n      // currently protractor/webdriver does not support\n      // sending keys to all known HTML5 input controls\n      // for various browsers (https://github.com/angular/protractor/issues/562).\n      function setInput(val) {\n        // set the value of the element and force validation.\n        var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n        \"ipt.value = '\" + val + \"';\" +\n        \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n        browser.executeScript(scr);\n      }\n\n      it('should initialize to model', function() {\n        expect(value.getText()).toContain('14:57:00');\n        expect(valid.getText()).toContain('myForm.input.$valid = true');\n      });\n\n      it('should be invalid if empty', function() {\n        setInput('');\n        expect(value.getText()).toEqual('value =');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n\n      it('should be invalid if over max', function() {\n        setInput('23:59:00');\n        expect(value.getText()).toContain('');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n   </file>\n   </example>\n   */\n  'time': createDateInputType('time', TIME_REGEXP,\n      createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']),\n     'HH:mm:ss.sss'),\n\n   /**\n    * @ngdoc input\n    * @name input[week]\n    *\n    * @description\n    * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support\n    * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601\n    * week format (yyyy-W##), for example: `2013-W02`.\n    *\n    * The model must always be a Date object, otherwise Angular will throw an error.\n    * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n    *\n    * The timezone to be used to read/write the `Date` instance in the model can be defined using\n    * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n    *\n    * @param {string} ngModel Assignable angular expression to data-bind to.\n    * @param {string=} name Property name of the form under which the control is published.\n    * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n    *   This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this\n    *   attribute (e.g. `min=\"{{minWeek | date:'yyyy-Www'}}\"`). Note that `min` will also add\n    *   native HTML5 constraint validation.\n    * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n    *   This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this\n    *   attribute (e.g. `max=\"{{maxWeek | date:'yyyy-Www'}}\"`). Note that `max` will also add\n    *   native HTML5 constraint validation.\n    * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string\n    *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n    * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string\n    *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n    * @param {string=} required Sets `required` validation error key if the value is not entered.\n    * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n    *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n    *    `required` when you want to data-bind to the `required` attribute.\n    * @param {string=} ngChange Angular expression to be executed when input changes due to user\n    *    interaction with the input element.\n    *\n    * @example\n    <example name=\"week-input-directive\" module=\"weekExample\">\n    <file name=\"index.html\">\n      <script>\n      angular.module('weekExample', [])\n        .controller('DateController', ['$scope', function($scope) {\n          $scope.example = {\n            value: new Date(2013, 0, 3)\n          };\n        }]);\n      </script>\n      <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n        <label>Pick a date between in 2013:\n          <input id=\"exampleInput\" type=\"week\" name=\"input\" ng-model=\"example.value\"\n                 placeholder=\"YYYY-W##\" min=\"2012-W32\"\n                 max=\"2013-W52\" required />\n        </label>\n        <div role=\"alert\">\n          <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n              Required!</span>\n          <span class=\"error\" ng-show=\"myForm.input.$error.week\">\n              Not a valid date!</span>\n        </div>\n        <tt>value = {{example.value | date: \"yyyy-Www\"}}</tt><br/>\n        <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n        <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n        <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n        <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n      </form>\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var value = element(by.binding('example.value | date: \"yyyy-Www\"'));\n      var valid = element(by.binding('myForm.input.$valid'));\n\n      // currently protractor/webdriver does not support\n      // sending keys to all known HTML5 input controls\n      // for various browsers (https://github.com/angular/protractor/issues/562).\n      function setInput(val) {\n        // set the value of the element and force validation.\n        var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n        \"ipt.value = '\" + val + \"';\" +\n        \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n        browser.executeScript(scr);\n      }\n\n      it('should initialize to model', function() {\n        expect(value.getText()).toContain('2013-W01');\n        expect(valid.getText()).toContain('myForm.input.$valid = true');\n      });\n\n      it('should be invalid if empty', function() {\n        setInput('');\n        expect(value.getText()).toEqual('value =');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n\n      it('should be invalid if over max', function() {\n        setInput('2015-W01');\n        expect(value.getText()).toContain('');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n    </file>\n    </example>\n    */\n  'week': createDateInputType('week', WEEK_REGEXP, weekParser, 'yyyy-Www'),\n\n  /**\n   * @ngdoc input\n   * @name input[month]\n   *\n   * @description\n   * Input with month validation and transformation. In browsers that do not yet support\n   * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601\n   * month format (yyyy-MM), for example: `2009-01`.\n   *\n   * The model must always be a Date object, otherwise Angular will throw an error.\n   * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.\n   * If the model is not set to the first of the month, the next view to model update will set it\n   * to the first of the month.\n   *\n   * The timezone to be used to read/write the `Date` instance in the model can be defined using\n   * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n   *   This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this\n   *   attribute (e.g. `min=\"{{minMonth | date:'yyyy-MM'}}\"`). Note that `min` will also add\n   *   native HTML5 constraint validation.\n   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n   *   This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this\n   *   attribute (e.g. `max=\"{{maxMonth | date:'yyyy-MM'}}\"`). Note that `max` will also add\n   *   native HTML5 constraint validation.\n   * @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string\n   *   the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.\n   * @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string\n   *   the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.\n\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n   <example name=\"month-input-directive\" module=\"monthExample\">\n   <file name=\"index.html\">\n     <script>\n      angular.module('monthExample', [])\n        .controller('DateController', ['$scope', function($scope) {\n          $scope.example = {\n            value: new Date(2013, 9, 1)\n          };\n        }]);\n     </script>\n     <form name=\"myForm\" ng-controller=\"DateController as dateCtrl\">\n       <label for=\"exampleInput\">Pick a month in 2013:</label>\n       <input id=\"exampleInput\" type=\"month\" name=\"input\" ng-model=\"example.value\"\n          placeholder=\"yyyy-MM\" min=\"2013-01\" max=\"2013-12\" required />\n       <div role=\"alert\">\n         <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n            Required!</span>\n         <span class=\"error\" ng-show=\"myForm.input.$error.month\">\n            Not a valid month!</span>\n       </div>\n       <tt>value = {{example.value | date: \"yyyy-MM\"}}</tt><br/>\n       <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n       <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n       <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n       <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n     </form>\n   </file>\n   <file name=\"protractor.js\" type=\"protractor\">\n      var value = element(by.binding('example.value | date: \"yyyy-MM\"'));\n      var valid = element(by.binding('myForm.input.$valid'));\n\n      // currently protractor/webdriver does not support\n      // sending keys to all known HTML5 input controls\n      // for various browsers (https://github.com/angular/protractor/issues/562).\n      function setInput(val) {\n        // set the value of the element and force validation.\n        var scr = \"var ipt = document.getElementById('exampleInput'); \" +\n        \"ipt.value = '\" + val + \"';\" +\n        \"angular.element(ipt).scope().$apply(function(s) { s.myForm[ipt.name].$setViewValue('\" + val + \"'); });\";\n        browser.executeScript(scr);\n      }\n\n      it('should initialize to model', function() {\n        expect(value.getText()).toContain('2013-10');\n        expect(valid.getText()).toContain('myForm.input.$valid = true');\n      });\n\n      it('should be invalid if empty', function() {\n        setInput('');\n        expect(value.getText()).toEqual('value =');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n\n      it('should be invalid if over max', function() {\n        setInput('2015-01');\n        expect(value.getText()).toContain('');\n        expect(valid.getText()).toContain('myForm.input.$valid = false');\n      });\n   </file>\n   </example>\n   */\n  'month': createDateInputType('month', MONTH_REGEXP,\n     createDateParser(MONTH_REGEXP, ['yyyy', 'MM']),\n     'yyyy-MM'),\n\n  /**\n   * @ngdoc input\n   * @name input[number]\n   *\n   * @description\n   * Text input with number validation and transformation. Sets the `number` validation\n   * error if not a valid number.\n   *\n   * <div class=\"alert alert-warning\">\n   * The model must always be of type `number` otherwise Angular will throw an error.\n   * Be aware that a string containing a number is not enough. See the {@link ngModel:numfmt}\n   * error docs for more information and an example of how to convert your model if necessary.\n   * </div>\n   *\n   * ## Issues with HTML5 constraint validation\n   *\n   * In browsers that follow the\n   * [HTML5 specification](https://html.spec.whatwg.org/multipage/forms.html#number-state-%28type=number%29),\n   * `input[number]` does not work as expected with {@link ngModelOptions `ngModelOptions.allowInvalid`}.\n   * If a non-number is entered in the input, the browser will report the value as an empty string,\n   * which means the view / model values in `ngModel` and subsequently the scope value\n   * will also be an empty string.\n   *\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.\n   *    Can be interpolated.\n   * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.\n   *    Can be interpolated.\n   * @param {string=} ngMin Like `min`, sets the `min` validation error key if the value entered is less than `ngMin`,\n   *    but does not trigger HTML5 native validation. Takes an expression.\n   * @param {string=} ngMax Like `max`, sets the `max` validation error key if the value entered is greater than `ngMax`,\n   *    but does not trigger HTML5 native validation. Takes an expression.\n   * @param {string=} step Sets the `step` validation error key if the value entered does not fit the `step` constraint.\n   *    Can be interpolated.\n   * @param {string=} ngStep Like `step`, sets the `step` validation error key if the value entered does not fit the `ngStep` constraint,\n   *    but does not trigger HTML5 native validation. Takes an expression.\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n   *    minlength.\n   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of\n   *    any length.\n   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string\n   *    that contains the regular expression body that will be converted to a regular expression\n   *    as in the ngPattern directive.\n   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n   *    If the expression evaluates to a RegExp object, then this is used directly.\n   *    If the expression evaluates to a string, then it will be converted to a RegExp\n   *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n   *    `new RegExp('^abc$')`.<br />\n   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n   *    start at the index of the last search's match, thus not taking the whole input value into\n   *    account.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n      <example name=\"number-input-directive\" module=\"numberExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('numberExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.example = {\n                 value: 12\n               };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>Number:\n             <input type=\"number\" name=\"input\" ng-model=\"example.value\"\n                    min=\"0\" max=\"99\" required>\n          </label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n               Required!</span>\n             <span class=\"error\" ng-show=\"myForm.input.$error.number\">\n               Not valid number!</span>\n           </div>\n           <tt>value = {{example.value}}</tt><br/>\n           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n          </form>\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var value = element(by.binding('example.value'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var input = element(by.model('example.value'));\n\n          it('should initialize to model', function() {\n            expect(value.getText()).toContain('12');\n            expect(valid.getText()).toContain('true');\n          });\n\n          it('should be invalid if empty', function() {\n            input.clear();\n            input.sendKeys('');\n            expect(value.getText()).toEqual('value =');\n            expect(valid.getText()).toContain('false');\n          });\n\n          it('should be invalid if over max', function() {\n            input.clear();\n            input.sendKeys('123');\n            expect(value.getText()).toEqual('value =');\n            expect(valid.getText()).toContain('false');\n          });\n        </file>\n      </example>\n   */\n  'number': numberInputType,\n\n\n  /**\n   * @ngdoc input\n   * @name input[url]\n   *\n   * @description\n   * Text input with URL validation. Sets the `url` validation error key if the content is not a\n   * valid URL.\n   *\n   * <div class=\"alert alert-warning\">\n   * **Note:** `input[url]` uses a regex to validate urls that is derived from the regex\n   * used in Chromium. If you need stricter validation, you can use `ng-pattern` or modify\n   * the built-in validators (see the {@link guide/forms Forms guide})\n   * </div>\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n   *    minlength.\n   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of\n   *    any length.\n   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string\n   *    that contains the regular expression body that will be converted to a regular expression\n   *    as in the ngPattern directive.\n   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n   *    If the expression evaluates to a RegExp object, then this is used directly.\n   *    If the expression evaluates to a string, then it will be converted to a RegExp\n   *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n   *    `new RegExp('^abc$')`.<br />\n   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n   *    start at the index of the last search's match, thus not taking the whole input value into\n   *    account.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n      <example name=\"url-input-directive\" module=\"urlExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('urlExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.url = {\n                 text: 'http://google.com'\n               };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>URL:\n             <input type=\"url\" name=\"input\" ng-model=\"url.text\" required>\n           <label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n               Required!</span>\n             <span class=\"error\" ng-show=\"myForm.input.$error.url\">\n               Not valid url!</span>\n           </div>\n           <tt>text = {{url.text}}</tt><br/>\n           <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n           <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n           <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n           <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n           <tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/>\n          </form>\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var text = element(by.binding('url.text'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var input = element(by.model('url.text'));\n\n          it('should initialize to model', function() {\n            expect(text.getText()).toContain('http://google.com');\n            expect(valid.getText()).toContain('true');\n          });\n\n          it('should be invalid if empty', function() {\n            input.clear();\n            input.sendKeys('');\n\n            expect(text.getText()).toEqual('text =');\n            expect(valid.getText()).toContain('false');\n          });\n\n          it('should be invalid if not url', function() {\n            input.clear();\n            input.sendKeys('box');\n\n            expect(valid.getText()).toContain('false');\n          });\n        </file>\n      </example>\n   */\n  'url': urlInputType,\n\n\n  /**\n   * @ngdoc input\n   * @name input[email]\n   *\n   * @description\n   * Text input with email validation. Sets the `email` validation error key if not a valid email\n   * address.\n   *\n   * <div class=\"alert alert-warning\">\n   * **Note:** `input[email]` uses a regex to validate email addresses that is derived from the regex\n   * used in Chromium. If you need stricter validation (e.g. requiring a top-level domain), you can\n   * use `ng-pattern` or modify the built-in validators (see the {@link guide/forms Forms guide})\n   * </div>\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} required Sets `required` validation error key if the value is not entered.\n   * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n   *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n   *    `required` when you want to data-bind to the `required` attribute.\n   * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n   *    minlength.\n   * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n   *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of\n   *    any length.\n   * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string\n   *    that contains the regular expression body that will be converted to a regular expression\n   *    as in the ngPattern directive.\n   * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n   *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n   *    If the expression evaluates to a RegExp object, then this is used directly.\n   *    If the expression evaluates to a string, then it will be converted to a RegExp\n   *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n   *    `new RegExp('^abc$')`.<br />\n   *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n   *    start at the index of the last search's match, thus not taking the whole input value into\n   *    account.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n      <example name=\"email-input-directive\" module=\"emailExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('emailExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.email = {\n                 text: 'me@example.com'\n               };\n             }]);\n         </script>\n           <form name=\"myForm\" ng-controller=\"ExampleController\">\n             <label>Email:\n               <input type=\"email\" name=\"input\" ng-model=\"email.text\" required>\n             </label>\n             <div role=\"alert\">\n               <span class=\"error\" ng-show=\"myForm.input.$error.required\">\n                 Required!</span>\n               <span class=\"error\" ng-show=\"myForm.input.$error.email\">\n                 Not valid email!</span>\n             </div>\n             <tt>text = {{email.text}}</tt><br/>\n             <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>\n             <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>\n             <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n             <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n             <tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>\n           </form>\n         </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var text = element(by.binding('email.text'));\n          var valid = element(by.binding('myForm.input.$valid'));\n          var input = element(by.model('email.text'));\n\n          it('should initialize to model', function() {\n            expect(text.getText()).toContain('me@example.com');\n            expect(valid.getText()).toContain('true');\n          });\n\n          it('should be invalid if empty', function() {\n            input.clear();\n            input.sendKeys('');\n            expect(text.getText()).toEqual('text =');\n            expect(valid.getText()).toContain('false');\n          });\n\n          it('should be invalid if not email', function() {\n            input.clear();\n            input.sendKeys('xxx');\n\n            expect(valid.getText()).toContain('false');\n          });\n        </file>\n      </example>\n   */\n  'email': emailInputType,\n\n\n  /**\n   * @ngdoc input\n   * @name input[radio]\n   *\n   * @description\n   * HTML radio button.\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string} value The value to which the `ngModel` expression should be set when selected.\n   *    Note that `value` only supports `string` values, i.e. the scope model needs to be a string,\n   *    too. Use `ngValue` if you need complex models (`number`, `object`, ...).\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   * @param {string} ngValue Angular expression to which `ngModel` will be be set when the radio\n   *    is selected. Should be used instead of the `value` attribute if you need\n   *    a non-string `ngModel` (`boolean`, `array`, ...).\n   *\n   * @example\n      <example name=\"radio-input-directive\" module=\"radioExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('radioExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.color = {\n                 name: 'blue'\n               };\n               $scope.specialValue = {\n                 \"id\": \"12345\",\n                 \"value\": \"green\"\n               };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>\n             <input type=\"radio\" ng-model=\"color.name\" value=\"red\">\n             Red\n           </label><br/>\n           <label>\n             <input type=\"radio\" ng-model=\"color.name\" ng-value=\"specialValue\">\n             Green\n           </label><br/>\n           <label>\n             <input type=\"radio\" ng-model=\"color.name\" value=\"blue\">\n             Blue\n           </label><br/>\n           <tt>color = {{color.name | json}}</tt><br/>\n          </form>\n          Note that `ng-value=\"specialValue\"` sets radio item's value to be the value of `$scope.specialValue`.\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          it('should change state', function() {\n            var inputs = element.all(by.model('color.name'));\n            var color = element(by.binding('color.name'));\n\n            expect(color.getText()).toContain('blue');\n\n            inputs.get(0).click();\n            expect(color.getText()).toContain('red');\n\n            inputs.get(1).click();\n            expect(color.getText()).toContain('green');\n          });\n        </file>\n      </example>\n   */\n  'radio': radioInputType,\n\n  /**\n   * @ngdoc input\n   * @name input[range]\n   *\n   * @description\n   * Native range input with validation and transformation.\n   *\n   * The model for the range input must always be a `Number`.\n   *\n   * IE9 and other browsers that do not support the `range` type fall back\n   * to a text input without any default values for `min`, `max` and `step`. Model binding,\n   * validation and number parsing are nevertheless supported.\n   *\n   * Browsers that support range (latest Chrome, Safari, Firefox, Edge) treat `input[range]`\n   * in a way that never allows the input to hold an invalid value. That means:\n   * - any non-numerical value is set to `(max + min) / 2`.\n   * - any numerical value that is less than the current min val, or greater than the current max val\n   * is set to the min / max val respectively.\n   * - additionally, the current `step` is respected, so the nearest value that satisfies a step\n   * is used.\n   *\n   * See the [HTML Spec on input[type=range]](https://www.w3.org/TR/html5/forms.html#range-state-(type=range))\n   * for more info.\n   *\n   * This has the following consequences for Angular:\n   *\n   * Since the element value should always reflect the current model value, a range input\n   * will set the bound ngModel expression to the value that the browser has set for the\n   * input element. For example, in the following input `<input type=\"range\" ng-model=\"model.value\">`,\n   * if the application sets `model.value = null`, the browser will set the input to `'50'`.\n   * Angular will then set the model to `50`, to prevent input and model value being out of sync.\n   *\n   * That means the model for range will immediately be set to `50` after `ngModel` has been\n   * initialized. It also means a range input can never have the required error.\n   *\n   * This does not only affect changes to the model value, but also to the values of the `min`,\n   * `max`, and `step` attributes. When these change in a way that will cause the browser to modify\n   * the input value, Angular will also update the model value.\n   *\n   * Automatic value adjustment also means that a range input element can never have the `required`,\n   * `min`, or `max` errors.\n   *\n   * However, `step` is currently only fully implemented by Firefox. Other browsers have problems\n   * when the step value changes dynamically - they do not adjust the element value correctly, but\n   * instead may set the `stepMismatch` error. If that's the case, the Angular will set the `step`\n   * error on the input, and set the model to `undefined`.\n   *\n   * Note that `input[range]` is not compatible with`ngMax`, `ngMin`, and `ngStep`, because they do\n   * not set the `min` and `max` attributes, which means that the browser won't automatically adjust\n   * the input value based on their values, and will always assume min = 0, max = 100, and step = 1.\n   *\n   * @param {string}  ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {string=} min Sets the `min` validation to ensure that the value entered is greater\n   *                  than `min`. Can be interpolated.\n   * @param {string=} max Sets the `max` validation to ensure that the value entered is less than `max`.\n   *                  Can be interpolated.\n   * @param {string=} step Sets the `step` validation to ensure that the value entered matches the `step`\n   *                  Can be interpolated.\n   * @param {string=} ngChange Angular expression to be executed when the ngModel value changes due\n   *                  to user interaction with the input element.\n   * @param {expression=} ngChecked If the expression is truthy, then the `checked` attribute will be set on the\n   *                      element. **Note** : `ngChecked` should not be used alongside `ngModel`.\n   *                      Checkout {@link ng.directive:ngChecked ngChecked} for usage.\n   *\n   * @example\n      <example name=\"range-input-directive\" module=\"rangeExample\">\n        <file name=\"index.html\">\n          <script>\n            angular.module('rangeExample', [])\n              .controller('ExampleController', ['$scope', function($scope) {\n                $scope.value = 75;\n                $scope.min = 10;\n                $scope.max = 90;\n              }]);\n          </script>\n          <form name=\"myForm\" ng-controller=\"ExampleController\">\n\n            Model as range: <input type=\"range\" name=\"range\" ng-model=\"value\" min=\"{{min}}\"  max=\"{{max}}\">\n            <hr>\n            Model as number: <input type=\"number\" ng-model=\"value\"><br>\n            Min: <input type=\"number\" ng-model=\"min\"><br>\n            Max: <input type=\"number\" ng-model=\"max\"><br>\n            value = <code>{{value}}</code><br/>\n            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>\n            myForm.range.$error = <code>{{myForm.range.$error}}</code>\n          </form>\n        </file>\n      </example>\n\n   * ## Range Input with ngMin & ngMax attributes\n\n   * @example\n      <example name=\"range-input-directive-ng\" module=\"rangeExample\">\n        <file name=\"index.html\">\n          <script>\n            angular.module('rangeExample', [])\n              .controller('ExampleController', ['$scope', function($scope) {\n                $scope.value = 75;\n                $scope.min = 10;\n                $scope.max = 90;\n              }]);\n          </script>\n          <form name=\"myForm\" ng-controller=\"ExampleController\">\n            Model as range: <input type=\"range\" name=\"range\" ng-model=\"value\" ng-min=\"min\" ng-max=\"max\">\n            <hr>\n            Model as number: <input type=\"number\" ng-model=\"value\"><br>\n            Min: <input type=\"number\" ng-model=\"min\"><br>\n            Max: <input type=\"number\" ng-model=\"max\"><br>\n            value = <code>{{value}}</code><br/>\n            myForm.range.$valid = <code>{{myForm.range.$valid}}</code><br/>\n            myForm.range.$error = <code>{{myForm.range.$error}}</code>\n          </form>\n        </file>\n      </example>\n\n   */\n  'range': rangeInputType,\n\n  /**\n   * @ngdoc input\n   * @name input[checkbox]\n   *\n   * @description\n   * HTML checkbox.\n   *\n   * @param {string} ngModel Assignable angular expression to data-bind to.\n   * @param {string=} name Property name of the form under which the control is published.\n   * @param {expression=} ngTrueValue The value to which the expression should be set when selected.\n   * @param {expression=} ngFalseValue The value to which the expression should be set when not selected.\n   * @param {string=} ngChange Angular expression to be executed when input changes due to user\n   *    interaction with the input element.\n   *\n   * @example\n      <example name=\"checkbox-input-directive\" module=\"checkboxExample\">\n        <file name=\"index.html\">\n         <script>\n           angular.module('checkboxExample', [])\n             .controller('ExampleController', ['$scope', function($scope) {\n               $scope.checkboxModel = {\n                value1 : true,\n                value2 : 'YES'\n              };\n             }]);\n         </script>\n         <form name=\"myForm\" ng-controller=\"ExampleController\">\n           <label>Value1:\n             <input type=\"checkbox\" ng-model=\"checkboxModel.value1\">\n           </label><br/>\n           <label>Value2:\n             <input type=\"checkbox\" ng-model=\"checkboxModel.value2\"\n                    ng-true-value=\"'YES'\" ng-false-value=\"'NO'\">\n            </label><br/>\n           <tt>value1 = {{checkboxModel.value1}}</tt><br/>\n           <tt>value2 = {{checkboxModel.value2}}</tt><br/>\n          </form>\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          it('should change state', function() {\n            var value1 = element(by.binding('checkboxModel.value1'));\n            var value2 = element(by.binding('checkboxModel.value2'));\n\n            expect(value1.getText()).toContain('true');\n            expect(value2.getText()).toContain('YES');\n\n            element(by.model('checkboxModel.value1')).click();\n            element(by.model('checkboxModel.value2')).click();\n\n            expect(value1.getText()).toContain('false');\n            expect(value2.getText()).toContain('NO');\n          });\n        </file>\n      </example>\n   */\n  'checkbox': checkboxInputType,\n\n  'hidden': noop,\n  'button': noop,\n  'submit': noop,\n  'reset': noop,\n  'file': noop\n};\n\nfunction stringBasedInputType(ctrl) {\n  ctrl.$formatters.push(function(value) {\n    return ctrl.$isEmpty(value) ? value : value.toString();\n  });\n}\n\nfunction textInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n  stringBasedInputType(ctrl);\n}\n\nfunction baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  var type = lowercase(element[0].type);\n\n  // In composition mode, users are still inputting intermediate text buffer,\n  // hold the listener until composition is done.\n  // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent\n  if (!$sniffer.android) {\n    var composing = false;\n\n    element.on('compositionstart', function() {\n      composing = true;\n    });\n\n    element.on('compositionend', function() {\n      composing = false;\n      listener();\n    });\n  }\n\n  var timeout;\n\n  var listener = function(ev) {\n    if (timeout) {\n      $browser.defer.cancel(timeout);\n      timeout = null;\n    }\n    if (composing) return;\n    var value = element.val(),\n        event = ev && ev.type;\n\n    // By default we will trim the value\n    // If the attribute ng-trim exists we will avoid trimming\n    // If input type is 'password', the value is never trimmed\n    if (type !== 'password' && (!attr.ngTrim || attr.ngTrim !== 'false')) {\n      value = trim(value);\n    }\n\n    // If a control is suffering from bad input (due to native validators), browsers discard its\n    // value, so it may be necessary to revalidate (by calling $setViewValue again) even if the\n    // control's value is the same empty value twice in a row.\n    if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) {\n      ctrl.$setViewValue(value, event);\n    }\n  };\n\n  // if the browser does support \"input\" event, we are fine - except on IE9 which doesn't fire the\n  // input event on backspace, delete or cut\n  if ($sniffer.hasEvent('input')) {\n    element.on('input', listener);\n  } else {\n    var deferListener = function(ev, input, origValue) {\n      if (!timeout) {\n        timeout = $browser.defer(function() {\n          timeout = null;\n          if (!input || input.value !== origValue) {\n            listener(ev);\n          }\n        });\n      }\n    };\n\n    element.on('keydown', /** @this */ function(event) {\n      var key = event.keyCode;\n\n      // ignore\n      //    command            modifiers                   arrows\n      if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;\n\n      deferListener(event, this, this.value);\n    });\n\n    // if user modifies input value using context menu in IE, we need \"paste\" and \"cut\" events to catch it\n    if ($sniffer.hasEvent('paste')) {\n      element.on('paste cut', deferListener);\n    }\n  }\n\n  // if user paste into input using mouse on older browser\n  // or form autocomplete on newer browser, we need \"change\" event to catch it\n  element.on('change', listener);\n\n  // Some native input types (date-family) have the ability to change validity without\n  // firing any input/change events.\n  // For these event types, when native validators are present and the browser supports the type,\n  // check for validity changes on various DOM events.\n  if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) {\n    element.on(PARTIAL_VALIDATION_EVENTS, /** @this */ function(ev) {\n      if (!timeout) {\n        var validity = this[VALIDITY_STATE_PROPERTY];\n        var origBadInput = validity.badInput;\n        var origTypeMismatch = validity.typeMismatch;\n        timeout = $browser.defer(function() {\n          timeout = null;\n          if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) {\n            listener(ev);\n          }\n        });\n      }\n    });\n  }\n\n  ctrl.$render = function() {\n    // Workaround for Firefox validation #12102.\n    var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue;\n    if (element.val() !== value) {\n      element.val(value);\n    }\n  };\n}\n\nfunction weekParser(isoWeek, existingDate) {\n  if (isDate(isoWeek)) {\n    return isoWeek;\n  }\n\n  if (isString(isoWeek)) {\n    WEEK_REGEXP.lastIndex = 0;\n    var parts = WEEK_REGEXP.exec(isoWeek);\n    if (parts) {\n      var year = +parts[1],\n          week = +parts[2],\n          hours = 0,\n          minutes = 0,\n          seconds = 0,\n          milliseconds = 0,\n          firstThurs = getFirstThursdayOfYear(year),\n          addDays = (week - 1) * 7;\n\n      if (existingDate) {\n        hours = existingDate.getHours();\n        minutes = existingDate.getMinutes();\n        seconds = existingDate.getSeconds();\n        milliseconds = existingDate.getMilliseconds();\n      }\n\n      return new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds);\n    }\n  }\n\n  return NaN;\n}\n\nfunction createDateParser(regexp, mapping) {\n  return function(iso, date) {\n    var parts, map;\n\n    if (isDate(iso)) {\n      return iso;\n    }\n\n    if (isString(iso)) {\n      // When a date is JSON'ified to wraps itself inside of an extra\n      // set of double quotes. This makes the date parsing code unable\n      // to match the date string and parse it as a date.\n      if (iso.charAt(0) === '\"' && iso.charAt(iso.length - 1) === '\"') {\n        iso = iso.substring(1, iso.length - 1);\n      }\n      if (ISO_DATE_REGEXP.test(iso)) {\n        return new Date(iso);\n      }\n      regexp.lastIndex = 0;\n      parts = regexp.exec(iso);\n\n      if (parts) {\n        parts.shift();\n        if (date) {\n          map = {\n            yyyy: date.getFullYear(),\n            MM: date.getMonth() + 1,\n            dd: date.getDate(),\n            HH: date.getHours(),\n            mm: date.getMinutes(),\n            ss: date.getSeconds(),\n            sss: date.getMilliseconds() / 1000\n          };\n        } else {\n          map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 };\n        }\n\n        forEach(parts, function(part, index) {\n          if (index < mapping.length) {\n            map[mapping[index]] = +part;\n          }\n        });\n        return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss * 1000 || 0);\n      }\n    }\n\n    return NaN;\n  };\n}\n\nfunction createDateInputType(type, regexp, parseDate, format) {\n  return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {\n    badInputChecker(scope, element, attr, ctrl);\n    baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n    var timezone = ctrl && ctrl.$options.getOption('timezone');\n    var previousDate;\n\n    ctrl.$$parserName = type;\n    ctrl.$parsers.push(function(value) {\n      if (ctrl.$isEmpty(value)) return null;\n      if (regexp.test(value)) {\n        // Note: We cannot read ctrl.$modelValue, as there might be a different\n        // parser/formatter in the processing chain so that the model\n        // contains some different data format!\n        var parsedDate = parseDate(value, previousDate);\n        if (timezone) {\n          parsedDate = convertTimezoneToLocal(parsedDate, timezone);\n        }\n        return parsedDate;\n      }\n      return undefined;\n    });\n\n    ctrl.$formatters.push(function(value) {\n      if (value && !isDate(value)) {\n        throw ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);\n      }\n      if (isValidDate(value)) {\n        previousDate = value;\n        if (previousDate && timezone) {\n          previousDate = convertTimezoneToLocal(previousDate, timezone, true);\n        }\n        return $filter('date')(value, format, timezone);\n      } else {\n        previousDate = null;\n        return '';\n      }\n    });\n\n    if (isDefined(attr.min) || attr.ngMin) {\n      var minVal;\n      ctrl.$validators.min = function(value) {\n        return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal;\n      };\n      attr.$observe('min', function(val) {\n        minVal = parseObservedDateValue(val);\n        ctrl.$validate();\n      });\n    }\n\n    if (isDefined(attr.max) || attr.ngMax) {\n      var maxVal;\n      ctrl.$validators.max = function(value) {\n        return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal;\n      };\n      attr.$observe('max', function(val) {\n        maxVal = parseObservedDateValue(val);\n        ctrl.$validate();\n      });\n    }\n\n    function isValidDate(value) {\n      // Invalid Date: getTime() returns NaN\n      return value && !(value.getTime && value.getTime() !== value.getTime());\n    }\n\n    function parseObservedDateValue(val) {\n      return isDefined(val) && !isDate(val) ? parseDate(val) || undefined : val;\n    }\n  };\n}\n\nfunction badInputChecker(scope, element, attr, ctrl) {\n  var node = element[0];\n  var nativeValidation = ctrl.$$hasNativeValidators = isObject(node.validity);\n  if (nativeValidation) {\n    ctrl.$parsers.push(function(value) {\n      var validity = element.prop(VALIDITY_STATE_PROPERTY) || {};\n      return validity.badInput || validity.typeMismatch ? undefined : value;\n    });\n  }\n}\n\nfunction numberFormatterParser(ctrl) {\n  ctrl.$$parserName = 'number';\n  ctrl.$parsers.push(function(value) {\n    if (ctrl.$isEmpty(value))      return null;\n    if (NUMBER_REGEXP.test(value)) return parseFloat(value);\n    return undefined;\n  });\n\n  ctrl.$formatters.push(function(value) {\n    if (!ctrl.$isEmpty(value)) {\n      if (!isNumber(value)) {\n        throw ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value);\n      }\n      value = value.toString();\n    }\n    return value;\n  });\n}\n\nfunction parseNumberAttrVal(val) {\n  if (isDefined(val) && !isNumber(val)) {\n    val = parseFloat(val);\n  }\n  return !isNumberNaN(val) ? val : undefined;\n}\n\nfunction isNumberInteger(num) {\n  // See http://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript#14794066\n  // (minus the assumption that `num` is a number)\n\n  // eslint-disable-next-line no-bitwise\n  return (num | 0) === num;\n}\n\nfunction countDecimals(num) {\n  var numString = num.toString();\n  var decimalSymbolIndex = numString.indexOf('.');\n\n  if (decimalSymbolIndex === -1) {\n    if (-1 < num && num < 1) {\n      // It may be in the exponential notation format (`1e-X`)\n      var match = /e-(\\d+)$/.exec(numString);\n\n      if (match) {\n        return Number(match[1]);\n      }\n    }\n\n    return 0;\n  }\n\n  return numString.length - decimalSymbolIndex - 1;\n}\n\nfunction isValidForStep(viewValue, stepBase, step) {\n  // At this point `stepBase` and `step` are expected to be non-NaN values\n  // and `viewValue` is expected to be a valid stringified number.\n  var value = Number(viewValue);\n\n  var isNonIntegerValue = !isNumberInteger(value);\n  var isNonIntegerStepBase = !isNumberInteger(stepBase);\n  var isNonIntegerStep = !isNumberInteger(step);\n\n  // Due to limitations in Floating Point Arithmetic (e.g. `0.3 - 0.2 !== 0.1` or\n  // `0.5 % 0.1 !== 0`), we need to convert all numbers to integers.\n  if (isNonIntegerValue || isNonIntegerStepBase || isNonIntegerStep) {\n    var valueDecimals = isNonIntegerValue ? countDecimals(value) : 0;\n    var stepBaseDecimals = isNonIntegerStepBase ? countDecimals(stepBase) : 0;\n    var stepDecimals = isNonIntegerStep ? countDecimals(step) : 0;\n\n    var decimalCount = Math.max(valueDecimals, stepBaseDecimals, stepDecimals);\n    var multiplier = Math.pow(10, decimalCount);\n\n    value = value * multiplier;\n    stepBase = stepBase * multiplier;\n    step = step * multiplier;\n\n    if (isNonIntegerValue) value = Math.round(value);\n    if (isNonIntegerStepBase) stepBase = Math.round(stepBase);\n    if (isNonIntegerStep) step = Math.round(step);\n  }\n\n  return (value - stepBase) % step === 0;\n}\n\nfunction numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  badInputChecker(scope, element, attr, ctrl);\n  numberFormatterParser(ctrl);\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n\n  var minVal;\n  var maxVal;\n\n  if (isDefined(attr.min) || attr.ngMin) {\n    ctrl.$validators.min = function(value) {\n      return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;\n    };\n\n    attr.$observe('min', function(val) {\n      minVal = parseNumberAttrVal(val);\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    });\n  }\n\n  if (isDefined(attr.max) || attr.ngMax) {\n    ctrl.$validators.max = function(value) {\n      return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;\n    };\n\n    attr.$observe('max', function(val) {\n      maxVal = parseNumberAttrVal(val);\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    });\n  }\n\n  if (isDefined(attr.step) || attr.ngStep) {\n    var stepVal;\n    ctrl.$validators.step = function(modelValue, viewValue) {\n      return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) ||\n             isValidForStep(viewValue, minVal || 0, stepVal);\n    };\n\n    attr.$observe('step', function(val) {\n      stepVal = parseNumberAttrVal(val);\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    });\n  }\n}\n\nfunction rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  badInputChecker(scope, element, attr, ctrl);\n  numberFormatterParser(ctrl);\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n\n  var supportsRange = ctrl.$$hasNativeValidators && element[0].type === 'range',\n      minVal = supportsRange ? 0 : undefined,\n      maxVal = supportsRange ? 100 : undefined,\n      stepVal = supportsRange ? 1 : undefined,\n      validity = element[0].validity,\n      hasMinAttr = isDefined(attr.min),\n      hasMaxAttr = isDefined(attr.max),\n      hasStepAttr = isDefined(attr.step);\n\n  var originalRender = ctrl.$render;\n\n  ctrl.$render = supportsRange && isDefined(validity.rangeUnderflow) && isDefined(validity.rangeOverflow) ?\n    //Browsers that implement range will set these values automatically, but reading the adjusted values after\n    //$render would cause the min / max validators to be applied with the wrong value\n    function rangeRender() {\n      originalRender();\n      ctrl.$setViewValue(element.val());\n    } :\n    originalRender;\n\n  if (hasMinAttr) {\n    ctrl.$validators.min = supportsRange ?\n      // Since all browsers set the input to a valid value, we don't need to check validity\n      function noopMinValidator() { return true; } :\n      // non-support browsers validate the min val\n      function minValidator(modelValue, viewValue) {\n        return ctrl.$isEmpty(viewValue) || isUndefined(minVal) || viewValue >= minVal;\n      };\n\n    setInitialValueAndObserver('min', minChange);\n  }\n\n  if (hasMaxAttr) {\n    ctrl.$validators.max = supportsRange ?\n      // Since all browsers set the input to a valid value, we don't need to check validity\n      function noopMaxValidator() { return true; } :\n      // non-support browsers validate the max val\n      function maxValidator(modelValue, viewValue) {\n        return ctrl.$isEmpty(viewValue) || isUndefined(maxVal) || viewValue <= maxVal;\n      };\n\n    setInitialValueAndObserver('max', maxChange);\n  }\n\n  if (hasStepAttr) {\n    ctrl.$validators.step = supportsRange ?\n      function nativeStepValidator() {\n        // Currently, only FF implements the spec on step change correctly (i.e. adjusting the\n        // input element value to a valid value). It's possible that other browsers set the stepMismatch\n        // validity error instead, so we can at least report an error in that case.\n        return !validity.stepMismatch;\n      } :\n      // ngStep doesn't set the setp attr, so the browser doesn't adjust the input value as setting step would\n      function stepValidator(modelValue, viewValue) {\n        return ctrl.$isEmpty(viewValue) || isUndefined(stepVal) ||\n               isValidForStep(viewValue, minVal || 0, stepVal);\n      };\n\n    setInitialValueAndObserver('step', stepChange);\n  }\n\n  function setInitialValueAndObserver(htmlAttrName, changeFn) {\n    // interpolated attributes set the attribute value only after a digest, but we need the\n    // attribute value when the input is first rendered, so that the browser can adjust the\n    // input value based on the min/max value\n    element.attr(htmlAttrName, attr[htmlAttrName]);\n    attr.$observe(htmlAttrName, changeFn);\n  }\n\n  function minChange(val) {\n    minVal = parseNumberAttrVal(val);\n    // ignore changes before model is initialized\n    if (isNumberNaN(ctrl.$modelValue)) {\n      return;\n    }\n\n    if (supportsRange) {\n      var elVal = element.val();\n      // IE11 doesn't set the el val correctly if the minVal is greater than the element value\n      if (minVal > elVal) {\n        elVal = minVal;\n        element.val(elVal);\n      }\n      ctrl.$setViewValue(elVal);\n    } else {\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    }\n  }\n\n  function maxChange(val) {\n    maxVal = parseNumberAttrVal(val);\n    // ignore changes before model is initialized\n    if (isNumberNaN(ctrl.$modelValue)) {\n      return;\n    }\n\n    if (supportsRange) {\n      var elVal = element.val();\n      // IE11 doesn't set the el val correctly if the maxVal is less than the element value\n      if (maxVal < elVal) {\n        element.val(maxVal);\n        // IE11 and Chrome don't set the value to the minVal when max < min\n        elVal = maxVal < minVal ? minVal : maxVal;\n      }\n      ctrl.$setViewValue(elVal);\n    } else {\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    }\n  }\n\n  function stepChange(val) {\n    stepVal = parseNumberAttrVal(val);\n    // ignore changes before model is initialized\n    if (isNumberNaN(ctrl.$modelValue)) {\n      return;\n    }\n\n    // Some browsers don't adjust the input value correctly, but set the stepMismatch error\n    if (supportsRange && ctrl.$viewValue !== element.val()) {\n      ctrl.$setViewValue(element.val());\n    } else {\n      // TODO(matsko): implement validateLater to reduce number of validations\n      ctrl.$validate();\n    }\n  }\n}\n\nfunction urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  // Note: no badInputChecker here by purpose as `url` is only a validation\n  // in browsers, i.e. we can always read out input.value even if it is not valid!\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n  stringBasedInputType(ctrl);\n\n  ctrl.$$parserName = 'url';\n  ctrl.$validators.url = function(modelValue, viewValue) {\n    var value = modelValue || viewValue;\n    return ctrl.$isEmpty(value) || URL_REGEXP.test(value);\n  };\n}\n\nfunction emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {\n  // Note: no badInputChecker here by purpose as `url` is only a validation\n  // in browsers, i.e. we can always read out input.value even if it is not valid!\n  baseInputType(scope, element, attr, ctrl, $sniffer, $browser);\n  stringBasedInputType(ctrl);\n\n  ctrl.$$parserName = 'email';\n  ctrl.$validators.email = function(modelValue, viewValue) {\n    var value = modelValue || viewValue;\n    return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);\n  };\n}\n\nfunction radioInputType(scope, element, attr, ctrl) {\n  var doTrim = !attr.ngTrim || trim(attr.ngTrim) !== 'false';\n  // make the name unique, if not defined\n  if (isUndefined(attr.name)) {\n    element.attr('name', nextUid());\n  }\n\n  var listener = function(ev) {\n    var value;\n    if (element[0].checked) {\n      value = attr.value;\n      if (doTrim) {\n        value = trim(value);\n      }\n      ctrl.$setViewValue(value, ev && ev.type);\n    }\n  };\n\n  element.on('click', listener);\n\n  ctrl.$render = function() {\n    var value = attr.value;\n    if (doTrim) {\n      value = trim(value);\n    }\n    element[0].checked = (value === ctrl.$viewValue);\n  };\n\n  attr.$observe('value', ctrl.$render);\n}\n\nfunction parseConstantExpr($parse, context, name, expression, fallback) {\n  var parseFn;\n  if (isDefined(expression)) {\n    parseFn = $parse(expression);\n    if (!parseFn.constant) {\n      throw ngModelMinErr('constexpr', 'Expected constant expression for `{0}`, but saw ' +\n                                   '`{1}`.', name, expression);\n    }\n    return parseFn(context);\n  }\n  return fallback;\n}\n\nfunction checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) {\n  var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true);\n  var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false);\n\n  var listener = function(ev) {\n    ctrl.$setViewValue(element[0].checked, ev && ev.type);\n  };\n\n  element.on('click', listener);\n\n  ctrl.$render = function() {\n    element[0].checked = ctrl.$viewValue;\n  };\n\n  // Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false`\n  // This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert\n  // it to a boolean.\n  ctrl.$isEmpty = function(value) {\n    return value === false;\n  };\n\n  ctrl.$formatters.push(function(value) {\n    return equals(value, trueValue);\n  });\n\n  ctrl.$parsers.push(function(value) {\n    return value ? trueValue : falseValue;\n  });\n}\n\n\n/**\n * @ngdoc directive\n * @name textarea\n * @restrict E\n *\n * @description\n * HTML textarea element control with angular data-binding. The data-binding and validation\n * properties of this element are exactly the same as those of the\n * {@link ng.directive:input input element}.\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} name Property name of the form under which the control is published.\n * @param {string=} required Sets `required` validation error key if the value is not entered.\n * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n *    `required` when you want to data-bind to the `required` attribute.\n * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n *    minlength.\n * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any\n *    length.\n * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n *    does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n *    If the expression evaluates to a RegExp object, then this is used directly.\n *    If the expression evaluates to a string, then it will be converted to a RegExp\n *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n *    `new RegExp('^abc$')`.<br />\n *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n *    start at the index of the last search's match, thus not taking the whole input value into\n *    account.\n * @param {string=} ngChange Angular expression to be executed when input changes due to user\n *    interaction with the input element.\n * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.\n *\n * @knownIssue\n *\n * When specifying the `placeholder` attribute of `<textarea>`, Internet Explorer will temporarily\n * insert the placeholder value as the textarea's content. If the placeholder value contains\n * interpolation (`{{ ... }}`), an error will be logged in the console when Angular tries to update\n * the value of the by-then-removed text node. This doesn't affect the functionality of the\n * textarea, but can be undesirable.\n *\n * You can work around this Internet Explorer issue by using `ng-attr-placeholder` instead of\n * `placeholder` on textareas, whenever you need interpolation in the placeholder value. You can\n * find more details on `ngAttr` in the\n * [Interpolation](guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes) section of the\n * Developer Guide.\n */\n\n\n/**\n * @ngdoc directive\n * @name input\n * @restrict E\n *\n * @description\n * HTML input element control. When used together with {@link ngModel `ngModel`}, it provides data-binding,\n * input state control, and validation.\n * Input control follows HTML5 input types and polyfills the HTML5 validation behavior for older browsers.\n *\n * <div class=\"alert alert-warning\">\n * **Note:** Not every feature offered is available for all input types.\n * Specifically, data binding and event handling via `ng-model` is unsupported for `input[file]`.\n * </div>\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} name Property name of the form under which the control is published.\n * @param {string=} required Sets `required` validation error key if the value is not entered.\n * @param {boolean=} ngRequired Sets `required` attribute if set to true\n * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than\n *    minlength.\n * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than\n *    maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any\n *    length.\n * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}\n *    value does not match a RegExp found by evaluating the Angular expression given in the attribute value.\n *    If the expression evaluates to a RegExp object, then this is used directly.\n *    If the expression evaluates to a string, then it will be converted to a RegExp\n *    after wrapping it in `^` and `$` characters. For instance, `\"abc\"` will be converted to\n *    `new RegExp('^abc$')`.<br />\n *    **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n *    start at the index of the last search's match, thus not taking the whole input value into\n *    account.\n * @param {string=} ngChange Angular expression to be executed when input changes due to user\n *    interaction with the input element.\n * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.\n *    This parameter is ignored for input[type=password] controls, which will never trim the\n *    input.\n *\n * @example\n    <example name=\"input-directive\" module=\"inputExample\">\n      <file name=\"index.html\">\n       <script>\n          angular.module('inputExample', [])\n            .controller('ExampleController', ['$scope', function($scope) {\n              $scope.user = {name: 'guest', last: 'visitor'};\n            }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <form name=\"myForm\">\n           <label>\n              User name:\n              <input type=\"text\" name=\"userName\" ng-model=\"user.name\" required>\n           </label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.userName.$error.required\">\n              Required!</span>\n           </div>\n           <label>\n              Last name:\n              <input type=\"text\" name=\"lastName\" ng-model=\"user.last\"\n              ng-minlength=\"3\" ng-maxlength=\"10\">\n           </label>\n           <div role=\"alert\">\n             <span class=\"error\" ng-show=\"myForm.lastName.$error.minlength\">\n               Too short!</span>\n             <span class=\"error\" ng-show=\"myForm.lastName.$error.maxlength\">\n               Too long!</span>\n           </div>\n         </form>\n         <hr>\n         <tt>user = {{user}}</tt><br/>\n         <tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br/>\n         <tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br/>\n         <tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br/>\n         <tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br/>\n         <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n         <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n         <tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br/>\n         <tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br/>\n       </div>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        var user = element(by.exactBinding('user'));\n        var userNameValid = element(by.binding('myForm.userName.$valid'));\n        var lastNameValid = element(by.binding('myForm.lastName.$valid'));\n        var lastNameError = element(by.binding('myForm.lastName.$error'));\n        var formValid = element(by.binding('myForm.$valid'));\n        var userNameInput = element(by.model('user.name'));\n        var userLastInput = element(by.model('user.last'));\n\n        it('should initialize to model', function() {\n          expect(user.getText()).toContain('{\"name\":\"guest\",\"last\":\"visitor\"}');\n          expect(userNameValid.getText()).toContain('true');\n          expect(formValid.getText()).toContain('true');\n        });\n\n        it('should be invalid if empty when required', function() {\n          userNameInput.clear();\n          userNameInput.sendKeys('');\n\n          expect(user.getText()).toContain('{\"last\":\"visitor\"}');\n          expect(userNameValid.getText()).toContain('false');\n          expect(formValid.getText()).toContain('false');\n        });\n\n        it('should be valid if empty when min length is set', function() {\n          userLastInput.clear();\n          userLastInput.sendKeys('');\n\n          expect(user.getText()).toContain('{\"name\":\"guest\",\"last\":\"\"}');\n          expect(lastNameValid.getText()).toContain('true');\n          expect(formValid.getText()).toContain('true');\n        });\n\n        it('should be invalid if less than required min length', function() {\n          userLastInput.clear();\n          userLastInput.sendKeys('xx');\n\n          expect(user.getText()).toContain('{\"name\":\"guest\"}');\n          expect(lastNameValid.getText()).toContain('false');\n          expect(lastNameError.getText()).toContain('minlength');\n          expect(formValid.getText()).toContain('false');\n        });\n\n        it('should be invalid if longer than max length', function() {\n          userLastInput.clear();\n          userLastInput.sendKeys('some ridiculously long name');\n\n          expect(user.getText()).toContain('{\"name\":\"guest\"}');\n          expect(lastNameValid.getText()).toContain('false');\n          expect(lastNameError.getText()).toContain('maxlength');\n          expect(formValid.getText()).toContain('false');\n        });\n      </file>\n    </example>\n */\nvar inputDirective = ['$browser', '$sniffer', '$filter', '$parse',\n    function($browser, $sniffer, $filter, $parse) {\n  return {\n    restrict: 'E',\n    require: ['?ngModel'],\n    link: {\n      pre: function(scope, element, attr, ctrls) {\n        if (ctrls[0]) {\n          (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer,\n                                                              $browser, $filter, $parse);\n        }\n      }\n    }\n  };\n}];\n\n\n\nvar CONSTANT_VALUE_REGEXP = /^(true|false|\\d+)$/;\n/**\n * @ngdoc directive\n * @name ngValue\n *\n * @description\n * Binds the given expression to the value of the element.\n *\n * It is mainly used on {@link input[radio] `input[radio]`} and option elements,\n * so that when the element is selected, the {@link ngModel `ngModel`} of that element (or its\n * {@link select `select`} parent element) is set to the bound value. It is especially useful\n * for dynamically generated lists using {@link ngRepeat `ngRepeat`}, as shown below.\n *\n * It can also be used to achieve one-way binding of a given expression to an input element\n * such as an `input[text]` or a `textarea`, when that element does not use ngModel.\n *\n * @element input\n * @param {string=} ngValue angular expression, whose value will be bound to the `value` attribute\n * and `value` property of the element.\n *\n * @example\n    <example name=\"ngValue-directive\" module=\"valueExample\">\n      <file name=\"index.html\">\n       <script>\n          angular.module('valueExample', [])\n            .controller('ExampleController', ['$scope', function($scope) {\n              $scope.names = ['pizza', 'unicorns', 'robots'];\n              $scope.my = { favorite: 'unicorns' };\n            }]);\n       </script>\n        <form ng-controller=\"ExampleController\">\n          <h2>Which is your favorite?</h2>\n            <label ng-repeat=\"name in names\" for=\"{{name}}\">\n              {{name}}\n              <input type=\"radio\"\n                     ng-model=\"my.favorite\"\n                     ng-value=\"name\"\n                     id=\"{{name}}\"\n                     name=\"favorite\">\n            </label>\n          <div>You chose {{my.favorite}}</div>\n        </form>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        var favorite = element(by.binding('my.favorite'));\n\n        it('should initialize to model', function() {\n          expect(favorite.getText()).toContain('unicorns');\n        });\n        it('should bind the values to the inputs', function() {\n          element.all(by.model('my.favorite')).get(0).click();\n          expect(favorite.getText()).toContain('pizza');\n        });\n      </file>\n    </example>\n */\nvar ngValueDirective = function() {\n  /**\n   *  inputs use the value attribute as their default value if the value property is not set.\n   *  Once the value property has been set (by adding input), it will not react to changes to\n   *  the value attribute anymore. Setting both attribute and property fixes this behavior, and\n   *  makes it possible to use ngValue as a sort of one-way bind.\n   */\n  function updateElementValue(element, attr, value) {\n    // Support: IE9 only\n    // In IE9 values are converted to string (e.g. `input.value = null` results in `input.value === 'null'`).\n    var propValue = isDefined(value) ? value : (msie === 9) ? '' : null;\n    element.prop('value', propValue);\n    attr.$set('value', value);\n  }\n\n  return {\n    restrict: 'A',\n    priority: 100,\n    compile: function(tpl, tplAttr) {\n      if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {\n        return function ngValueConstantLink(scope, elm, attr) {\n          var value = scope.$eval(attr.ngValue);\n          updateElementValue(elm, attr, value);\n        };\n      } else {\n        return function ngValueLink(scope, elm, attr) {\n          scope.$watch(attr.ngValue, function valueWatchAction(value) {\n            updateElementValue(elm, attr, value);\n          });\n        };\n      }\n    }\n  };\n};\n\n/**\n * @ngdoc directive\n * @name ngBind\n * @restrict AC\n *\n * @description\n * The `ngBind` attribute tells Angular to replace the text content of the specified HTML element\n * with the value of a given expression, and to update the text content when the value of that\n * expression changes.\n *\n * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like\n * `{{ expression }}` which is similar but less verbose.\n *\n * It is preferable to use `ngBind` instead of `{{ expression }}` if a template is momentarily\n * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an\n * element attribute, it makes the bindings invisible to the user while the page is loading.\n *\n * An alternative solution to this problem would be using the\n * {@link ng.directive:ngCloak ngCloak} directive.\n *\n *\n * @element ANY\n * @param {expression} ngBind {@link guide/expression Expression} to evaluate.\n *\n * @example\n * Enter a name in the Live Preview text box; the greeting below the text box changes instantly.\n   <example module=\"bindExample\" name=\"ng-bind\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('bindExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.name = 'Whirled';\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n         <label>Enter name: <input type=\"text\" ng-model=\"name\"></label><br>\n         Hello <span ng-bind=\"name\"></span>!\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-bind', function() {\n         var nameInput = element(by.model('name'));\n\n         expect(element(by.binding('name')).getText()).toBe('Whirled');\n         nameInput.clear();\n         nameInput.sendKeys('world');\n         expect(element(by.binding('name')).getText()).toBe('world');\n       });\n     </file>\n   </example>\n */\nvar ngBindDirective = ['$compile', function($compile) {\n  return {\n    restrict: 'AC',\n    compile: function ngBindCompile(templateElement) {\n      $compile.$$addBindingClass(templateElement);\n      return function ngBindLink(scope, element, attr) {\n        $compile.$$addBindingInfo(element, attr.ngBind);\n        element = element[0];\n        scope.$watch(attr.ngBind, function ngBindWatchAction(value) {\n          element.textContent = stringify(value);\n        });\n      };\n    }\n  };\n}];\n\n\n/**\n * @ngdoc directive\n * @name ngBindTemplate\n *\n * @description\n * The `ngBindTemplate` directive specifies that the element\n * text content should be replaced with the interpolation of the template\n * in the `ngBindTemplate` attribute.\n * Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}`\n * expressions. This directive is needed since some HTML elements\n * (such as TITLE and OPTION) cannot contain SPAN elements.\n *\n * @element ANY\n * @param {string} ngBindTemplate template of form\n *   <tt>{{</tt> <tt>expression</tt> <tt>}}</tt> to eval.\n *\n * @example\n * Try it here: enter text in text box and watch the greeting change.\n   <example module=\"bindExample\" name=\"ng-bind-template\">\n     <file name=\"index.html\">\n       <script>\n         angular.module('bindExample', [])\n           .controller('ExampleController', ['$scope', function($scope) {\n             $scope.salutation = 'Hello';\n             $scope.name = 'World';\n           }]);\n       </script>\n       <div ng-controller=\"ExampleController\">\n        <label>Salutation: <input type=\"text\" ng-model=\"salutation\"></label><br>\n        <label>Name: <input type=\"text\" ng-model=\"name\"></label><br>\n        <pre ng-bind-template=\"{{salutation}} {{name}}!\"></pre>\n       </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-bind', function() {\n         var salutationElem = element(by.binding('salutation'));\n         var salutationInput = element(by.model('salutation'));\n         var nameInput = element(by.model('name'));\n\n         expect(salutationElem.getText()).toBe('Hello World!');\n\n         salutationInput.clear();\n         salutationInput.sendKeys('Greetings');\n         nameInput.clear();\n         nameInput.sendKeys('user');\n\n         expect(salutationElem.getText()).toBe('Greetings user!');\n       });\n     </file>\n   </example>\n */\nvar ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate, $compile) {\n  return {\n    compile: function ngBindTemplateCompile(templateElement) {\n      $compile.$$addBindingClass(templateElement);\n      return function ngBindTemplateLink(scope, element, attr) {\n        var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate));\n        $compile.$$addBindingInfo(element, interpolateFn.expressions);\n        element = element[0];\n        attr.$observe('ngBindTemplate', function(value) {\n          element.textContent = isUndefined(value) ? '' : value;\n        });\n      };\n    }\n  };\n}];\n\n\n/**\n * @ngdoc directive\n * @name ngBindHtml\n *\n * @description\n * Evaluates the expression and inserts the resulting HTML into the element in a secure way. By default,\n * the resulting HTML content will be sanitized using the {@link ngSanitize.$sanitize $sanitize} service.\n * To utilize this functionality, ensure that `$sanitize` is available, for example, by including {@link\n * ngSanitize} in your module's dependencies (not in core Angular). In order to use {@link ngSanitize}\n * in your module's dependencies, you need to include \"angular-sanitize.js\" in your application.\n *\n * You may also bypass sanitization for values you know are safe. To do so, bind to\n * an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}.  See the example\n * under {@link ng.$sce#show-me-an-example-using-sce- Strict Contextual Escaping (SCE)}.\n *\n * Note: If a `$sanitize` service is unavailable and the bound value isn't explicitly trusted, you\n * will have an exception (instead of an exploit.)\n *\n * @element ANY\n * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.\n *\n * @example\n\n   <example module=\"bindHtmlExample\" deps=\"angular-sanitize.js\" name=\"ng-bind-html\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n        <p ng-bind-html=\"myHTML\"></p>\n       </div>\n     </file>\n\n     <file name=\"script.js\">\n       angular.module('bindHtmlExample', ['ngSanitize'])\n         .controller('ExampleController', ['$scope', function($scope) {\n           $scope.myHTML =\n              'I am an <code>HTML</code>string with ' +\n              '<a href=\"#\">links!</a> and other <em>stuff</em>';\n         }]);\n     </file>\n\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-bind-html', function() {\n         expect(element(by.binding('myHTML')).getText()).toBe(\n             'I am an HTMLstring with links! and other stuff');\n       });\n     </file>\n   </example>\n */\nvar ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) {\n  return {\n    restrict: 'A',\n    compile: function ngBindHtmlCompile(tElement, tAttrs) {\n      var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml);\n      var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function sceValueOf(val) {\n        // Unwrap the value to compare the actual inner safe value, not the wrapper object.\n        return $sce.valueOf(val);\n      });\n      $compile.$$addBindingClass(tElement);\n\n      return function ngBindHtmlLink(scope, element, attr) {\n        $compile.$$addBindingInfo(element, attr.ngBindHtml);\n\n        scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {\n          // The watched value is the unwrapped value. To avoid re-escaping, use the direct getter.\n          var value = ngBindHtmlGetter(scope);\n          element.html($sce.getTrustedHtml(value) || '');\n        });\n      };\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngChange\n *\n * @description\n * Evaluate the given expression when the user changes the input.\n * The expression is evaluated immediately, unlike the JavaScript onchange event\n * which only triggers at the end of a change (usually, when the user leaves the\n * form element or presses the return key).\n *\n * The `ngChange` expression is only evaluated when a change in the input value causes\n * a new value to be committed to the model.\n *\n * It will not be evaluated:\n * * if the value returned from the `$parsers` transformation pipeline has not changed\n * * if the input has continued to be invalid since the model will stay `null`\n * * if the model is changed programmatically and not by a change to the input value\n *\n *\n * Note, this directive requires `ngModel` to be present.\n *\n * @element input\n * @param {expression} ngChange {@link guide/expression Expression} to evaluate upon change\n * in input value.\n *\n * @example\n * <example name=\"ngChange-directive\" module=\"changeExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('changeExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.counter = 0;\n *           $scope.change = function() {\n *             $scope.counter++;\n *           };\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <input type=\"checkbox\" ng-model=\"confirmed\" ng-change=\"change()\" id=\"ng-change-example1\" />\n *       <input type=\"checkbox\" ng-model=\"confirmed\" id=\"ng-change-example2\" />\n *       <label for=\"ng-change-example2\">Confirmed</label><br />\n *       <tt>debug = {{confirmed}}</tt><br/>\n *       <tt>counter = {{counter}}</tt><br/>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     var counter = element(by.binding('counter'));\n *     var debug = element(by.binding('confirmed'));\n *\n *     it('should evaluate the expression if changing from view', function() {\n *       expect(counter.getText()).toContain('0');\n *\n *       element(by.id('ng-change-example1')).click();\n *\n *       expect(counter.getText()).toContain('1');\n *       expect(debug.getText()).toContain('true');\n *     });\n *\n *     it('should not evaluate the expression if changing from model', function() {\n *       element(by.id('ng-change-example2')).click();\n\n *       expect(counter.getText()).toContain('0');\n *       expect(debug.getText()).toContain('true');\n *     });\n *   </file>\n * </example>\n */\nvar ngChangeDirective = valueFn({\n  restrict: 'A',\n  require: 'ngModel',\n  link: function(scope, element, attr, ctrl) {\n    ctrl.$viewChangeListeners.push(function() {\n      scope.$eval(attr.ngChange);\n    });\n  }\n});\n\n/* exported\n  ngClassDirective,\n  ngClassEvenDirective,\n  ngClassOddDirective\n*/\n\nfunction classDirective(name, selector) {\n  name = 'ngClass' + name;\n  var indexWatchExpression;\n\n  return ['$parse', function($parse) {\n    return {\n      restrict: 'AC',\n      link: function(scope, element, attr) {\n        var expression = attr[name].trim();\n        var isOneTime = (expression.charAt(0) === ':') && (expression.charAt(1) === ':');\n\n        var watchInterceptor = isOneTime ? toFlatValue : toClassString;\n        var watchExpression = $parse(expression, watchInterceptor);\n        var watchAction = isOneTime ? ngClassOneTimeWatchAction : ngClassWatchAction;\n\n        var classCounts = element.data('$classCounts');\n        var oldModulo = true;\n        var oldClassString;\n\n        if (!classCounts) {\n          // Use createMap() to prevent class assumptions involving property\n          // names in Object.prototype\n          classCounts = createMap();\n          element.data('$classCounts', classCounts);\n        }\n\n        if (name !== 'ngClass') {\n          if (!indexWatchExpression) {\n            indexWatchExpression = $parse('$index', function moduloTwo($index) {\n              // eslint-disable-next-line no-bitwise\n              return $index & 1;\n            });\n          }\n\n          scope.$watch(indexWatchExpression, ngClassIndexWatchAction);\n        }\n\n        scope.$watch(watchExpression, watchAction, isOneTime);\n\n        function addClasses(classString) {\n          classString = digestClassCounts(split(classString), 1);\n          attr.$addClass(classString);\n        }\n\n        function removeClasses(classString) {\n          classString = digestClassCounts(split(classString), -1);\n          attr.$removeClass(classString);\n        }\n\n        function updateClasses(oldClassString, newClassString) {\n          var oldClassArray = split(oldClassString);\n          var newClassArray = split(newClassString);\n\n          var toRemoveArray = arrayDifference(oldClassArray, newClassArray);\n          var toAddArray = arrayDifference(newClassArray, oldClassArray);\n\n          var toRemoveString = digestClassCounts(toRemoveArray, -1);\n          var toAddString = digestClassCounts(toAddArray, 1);\n\n          attr.$addClass(toAddString);\n          attr.$removeClass(toRemoveString);\n        }\n\n        function digestClassCounts(classArray, count) {\n          var classesToUpdate = [];\n\n          forEach(classArray, function(className) {\n            if (count > 0 || classCounts[className]) {\n              classCounts[className] = (classCounts[className] || 0) + count;\n              if (classCounts[className] === +(count > 0)) {\n                classesToUpdate.push(className);\n              }\n            }\n          });\n\n          return classesToUpdate.join(' ');\n        }\n\n        function ngClassIndexWatchAction(newModulo) {\n          // This watch-action should run before the `ngClass[OneTime]WatchAction()`, thus it\n          // adds/removes `oldClassString`. If the `ngClass` expression has changed as well, the\n          // `ngClass[OneTime]WatchAction()` will update the classes.\n          if (newModulo === selector) {\n            addClasses(oldClassString);\n          } else {\n            removeClasses(oldClassString);\n          }\n\n          oldModulo = newModulo;\n        }\n\n        function ngClassOneTimeWatchAction(newClassValue) {\n          var newClassString = toClassString(newClassValue);\n\n          if (newClassString !== oldClassString) {\n            ngClassWatchAction(newClassString);\n          }\n        }\n\n        function ngClassWatchAction(newClassString) {\n          if (oldModulo === selector) {\n            updateClasses(oldClassString, newClassString);\n          }\n\n          oldClassString = newClassString;\n        }\n      }\n    };\n  }];\n\n  // Helpers\n  function arrayDifference(tokens1, tokens2) {\n    if (!tokens1 || !tokens1.length) return [];\n    if (!tokens2 || !tokens2.length) return tokens1;\n\n    var values = [];\n\n    outer:\n    for (var i = 0; i < tokens1.length; i++) {\n      var token = tokens1[i];\n      for (var j = 0; j < tokens2.length; j++) {\n        if (token === tokens2[j]) continue outer;\n      }\n      values.push(token);\n    }\n\n    return values;\n  }\n\n  function split(classString) {\n    return classString && classString.split(' ');\n  }\n\n  function toClassString(classValue) {\n    var classString = classValue;\n\n    if (isArray(classValue)) {\n      classString = classValue.map(toClassString).join(' ');\n    } else if (isObject(classValue)) {\n      classString = Object.keys(classValue).\n        filter(function(key) { return classValue[key]; }).\n        join(' ');\n    }\n\n    return classString;\n  }\n\n  function toFlatValue(classValue) {\n    var flatValue = classValue;\n\n    if (isArray(classValue)) {\n      flatValue = classValue.map(toFlatValue);\n    } else if (isObject(classValue)) {\n      var hasUndefined = false;\n\n      flatValue = Object.keys(classValue).filter(function(key) {\n        var value = classValue[key];\n\n        if (!hasUndefined && isUndefined(value)) {\n          hasUndefined = true;\n        }\n\n        return value;\n      });\n\n      if (hasUndefined) {\n        // Prevent the `oneTimeLiteralWatchInterceptor` from unregistering\n        // the watcher, by including at least one `undefined` value.\n        flatValue.push(undefined);\n      }\n    }\n\n    return flatValue;\n  }\n}\n\n/**\n * @ngdoc directive\n * @name ngClass\n * @restrict AC\n *\n * @description\n * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding\n * an expression that represents all classes to be added.\n *\n * The directive operates in three different ways, depending on which of three types the expression\n * evaluates to:\n *\n * 1. If the expression evaluates to a string, the string should be one or more space-delimited class\n * names.\n *\n * 2. If the expression evaluates to an object, then for each key-value pair of the\n * object with a truthy value the corresponding key is used as a class name.\n *\n * 3. If the expression evaluates to an array, each element of the array should either be a string as in\n * type 1 or an object as in type 2. This means that you can mix strings and objects together in an array\n * to give you more control over what CSS classes appear. See the code below for an example of this.\n *\n *\n * The directive won't add duplicate classes if a particular class was already set.\n *\n * When the expression changes, the previously added classes are removed and only then are the\n * new classes added.\n *\n * @knownIssue\n * You should not use {@link guide/interpolation interpolation} in the value of the `class`\n * attribute, when using the `ngClass` directive on the same element.\n * See {@link guide/interpolation#known-issues here} for more info.\n *\n * @animations\n * | Animation                        | Occurs                              |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#addClass addClass}       | just before the class is applied to the element   |\n * | {@link ng.$animate#removeClass removeClass} | just before the class is removed from the element |\n *\n * @element ANY\n * @param {expression} ngClass {@link guide/expression Expression} to eval. The result\n *   of the evaluation can be a string representing space delimited class\n *   names, an array, or a map of class names to boolean values. In the case of a map, the\n *   names of the properties whose values are truthy will be added as css classes to the\n *   element.\n *\n * @example Example that demonstrates basic bindings via ngClass directive.\n   <example name=\"ng-class\">\n     <file name=\"index.html\">\n       <p ng-class=\"{strike: deleted, bold: important, 'has-error': error}\">Map Syntax Example</p>\n       <label>\n          <input type=\"checkbox\" ng-model=\"deleted\">\n          deleted (apply \"strike\" class)\n       </label><br>\n       <label>\n          <input type=\"checkbox\" ng-model=\"important\">\n          important (apply \"bold\" class)\n       </label><br>\n       <label>\n          <input type=\"checkbox\" ng-model=\"error\">\n          error (apply \"has-error\" class)\n       </label>\n       <hr>\n       <p ng-class=\"style\">Using String Syntax</p>\n       <input type=\"text\" ng-model=\"style\"\n              placeholder=\"Type: bold strike red\" aria-label=\"Type: bold strike red\">\n       <hr>\n       <p ng-class=\"[style1, style2, style3]\">Using Array Syntax</p>\n       <input ng-model=\"style1\"\n              placeholder=\"Type: bold, strike or red\" aria-label=\"Type: bold, strike or red\"><br>\n       <input ng-model=\"style2\"\n              placeholder=\"Type: bold, strike or red\" aria-label=\"Type: bold, strike or red 2\"><br>\n       <input ng-model=\"style3\"\n              placeholder=\"Type: bold, strike or red\" aria-label=\"Type: bold, strike or red 3\"><br>\n       <hr>\n       <p ng-class=\"[style4, {orange: warning}]\">Using Array and Map Syntax</p>\n       <input ng-model=\"style4\" placeholder=\"Type: bold, strike\" aria-label=\"Type: bold, strike\"><br>\n       <label><input type=\"checkbox\" ng-model=\"warning\"> warning (apply \"orange\" class)</label>\n     </file>\n     <file name=\"style.css\">\n       .strike {\n           text-decoration: line-through;\n       }\n       .bold {\n           font-weight: bold;\n       }\n       .red {\n           color: red;\n       }\n       .has-error {\n           color: red;\n           background-color: yellow;\n       }\n       .orange {\n           color: orange;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       var ps = element.all(by.css('p'));\n\n       it('should let you toggle the class', function() {\n\n         expect(ps.first().getAttribute('class')).not.toMatch(/bold/);\n         expect(ps.first().getAttribute('class')).not.toMatch(/has-error/);\n\n         element(by.model('important')).click();\n         expect(ps.first().getAttribute('class')).toMatch(/bold/);\n\n         element(by.model('error')).click();\n         expect(ps.first().getAttribute('class')).toMatch(/has-error/);\n       });\n\n       it('should let you toggle string example', function() {\n         expect(ps.get(1).getAttribute('class')).toBe('');\n         element(by.model('style')).clear();\n         element(by.model('style')).sendKeys('red');\n         expect(ps.get(1).getAttribute('class')).toBe('red');\n       });\n\n       it('array example should have 3 classes', function() {\n         expect(ps.get(2).getAttribute('class')).toBe('');\n         element(by.model('style1')).sendKeys('bold');\n         element(by.model('style2')).sendKeys('strike');\n         element(by.model('style3')).sendKeys('red');\n         expect(ps.get(2).getAttribute('class')).toBe('bold strike red');\n       });\n\n       it('array with map example should have 2 classes', function() {\n         expect(ps.last().getAttribute('class')).toBe('');\n         element(by.model('style4')).sendKeys('bold');\n         element(by.model('warning')).click();\n         expect(ps.last().getAttribute('class')).toBe('bold orange');\n       });\n     </file>\n   </example>\n\n   ## Animations\n\n   The example below demonstrates how to perform animations using ngClass.\n\n   <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-class\">\n     <file name=\"index.html\">\n      <input id=\"setbtn\" type=\"button\" value=\"set\" ng-click=\"myVar='my-class'\">\n      <input id=\"clearbtn\" type=\"button\" value=\"clear\" ng-click=\"myVar=''\">\n      <br>\n      <span class=\"base-class\" ng-class=\"myVar\">Sample Text</span>\n     </file>\n     <file name=\"style.css\">\n       .base-class {\n         transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;\n       }\n\n       .base-class.my-class {\n         color: red;\n         font-size:3em;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-class', function() {\n         expect(element(by.css('.base-class')).getAttribute('class')).not.\n           toMatch(/my-class/);\n\n         element(by.id('setbtn')).click();\n\n         expect(element(by.css('.base-class')).getAttribute('class')).\n           toMatch(/my-class/);\n\n         element(by.id('clearbtn')).click();\n\n         expect(element(by.css('.base-class')).getAttribute('class')).not.\n           toMatch(/my-class/);\n       });\n     </file>\n   </example>\n\n\n   ## ngClass and pre-existing CSS3 Transitions/Animations\n   The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.\n   Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder\n   any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure\n   to view the step by step details of {@link $animate#addClass $animate.addClass} and\n   {@link $animate#removeClass $animate.removeClass}.\n */\nvar ngClassDirective = classDirective('', true);\n\n/**\n * @ngdoc directive\n * @name ngClassOdd\n * @restrict AC\n *\n * @description\n * The `ngClassOdd` and `ngClassEven` directives work exactly as\n * {@link ng.directive:ngClass ngClass}, except they work in\n * conjunction with `ngRepeat` and take effect only on odd (even) rows.\n *\n * This directive can be applied only within the scope of an\n * {@link ng.directive:ngRepeat ngRepeat}.\n *\n * @element ANY\n * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result\n *   of the evaluation can be a string representing space delimited class names or an array.\n *\n * @example\n   <example name=\"ng-class-odd\">\n     <file name=\"index.html\">\n        <ol ng-init=\"names=['John', 'Mary', 'Cate', 'Suz']\">\n          <li ng-repeat=\"name in names\">\n           <span ng-class-odd=\"'odd'\" ng-class-even=\"'even'\">\n             {{name}}\n           </span>\n          </li>\n        </ol>\n     </file>\n     <file name=\"style.css\">\n       .odd {\n         color: red;\n       }\n       .even {\n         color: blue;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-class-odd and ng-class-even', function() {\n         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).\n           toMatch(/odd/);\n         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).\n           toMatch(/even/);\n       });\n     </file>\n   </example>\n */\nvar ngClassOddDirective = classDirective('Odd', 0);\n\n/**\n * @ngdoc directive\n * @name ngClassEven\n * @restrict AC\n *\n * @description\n * The `ngClassOdd` and `ngClassEven` directives work exactly as\n * {@link ng.directive:ngClass ngClass}, except they work in\n * conjunction with `ngRepeat` and take effect only on odd (even) rows.\n *\n * This directive can be applied only within the scope of an\n * {@link ng.directive:ngRepeat ngRepeat}.\n *\n * @element ANY\n * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The\n *   result of the evaluation can be a string representing space delimited class names or an array.\n *\n * @example\n   <example name=\"ng-class-even\">\n     <file name=\"index.html\">\n        <ol ng-init=\"names=['John', 'Mary', 'Cate', 'Suz']\">\n          <li ng-repeat=\"name in names\">\n           <span ng-class-odd=\"'odd'\" ng-class-even=\"'even'\">\n             {{name}} &nbsp; &nbsp; &nbsp;\n           </span>\n          </li>\n        </ol>\n     </file>\n     <file name=\"style.css\">\n       .odd {\n         color: red;\n       }\n       .even {\n         color: blue;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-class-odd and ng-class-even', function() {\n         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).\n           toMatch(/odd/);\n         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).\n           toMatch(/even/);\n       });\n     </file>\n   </example>\n */\nvar ngClassEvenDirective = classDirective('Even', 1);\n\n/**\n * @ngdoc directive\n * @name ngCloak\n * @restrict AC\n *\n * @description\n * The `ngCloak` directive is used to prevent the Angular html template from being briefly\n * displayed by the browser in its raw (uncompiled) form while your application is loading. Use this\n * directive to avoid the undesirable flicker effect caused by the html template display.\n *\n * The directive can be applied to the `<body>` element, but the preferred usage is to apply\n * multiple `ngCloak` directives to small portions of the page to permit progressive rendering\n * of the browser view.\n *\n * `ngCloak` works in cooperation with the following css rule embedded within `angular.js` and\n * `angular.min.js`.\n * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}).\n *\n * ```css\n * [ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {\n *   display: none !important;\n * }\n * ```\n *\n * When this css rule is loaded by the browser, all html elements (including their children) that\n * are tagged with the `ngCloak` directive are hidden. When Angular encounters this directive\n * during the compilation of the template it deletes the `ngCloak` element attribute, making\n * the compiled element visible.\n *\n * For the best result, the `angular.js` script must be loaded in the head section of the html\n * document; alternatively, the css rule above must be included in the external stylesheet of the\n * application.\n *\n * @element ANY\n *\n * @example\n   <example name=\"ng-cloak\">\n     <file name=\"index.html\">\n        <div id=\"template1\" ng-cloak>{{ 'hello' }}</div>\n        <div id=\"template2\" class=\"ng-cloak\">{{ 'world' }}</div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should remove the template directive and css class', function() {\n         expect($('#template1').getAttribute('ng-cloak')).\n           toBeNull();\n         expect($('#template2').getAttribute('ng-cloak')).\n           toBeNull();\n       });\n     </file>\n   </example>\n *\n */\nvar ngCloakDirective = ngDirective({\n  compile: function(element, attr) {\n    attr.$set('ngCloak', undefined);\n    element.removeClass('ng-cloak');\n  }\n});\n\n/**\n * @ngdoc directive\n * @name ngController\n *\n * @description\n * The `ngController` directive attaches a controller class to the view. This is a key aspect of how angular\n * supports the principles behind the Model-View-Controller design pattern.\n *\n * MVC components in angular:\n *\n * * Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties\n *   are accessed through bindings.\n * * View — The template (HTML with data bindings) that is rendered into the View.\n * * Controller — The `ngController` directive specifies a Controller class; the class contains business\n *   logic behind the application to decorate the scope with functions and values\n *\n * Note that you can also attach controllers to the DOM by declaring it in a route definition\n * via the {@link ngRoute.$route $route} service. A common mistake is to declare the controller\n * again using `ng-controller` in the template itself.  This will cause the controller to be attached\n * and executed twice.\n *\n * @element ANY\n * @scope\n * @priority 500\n * @param {expression} ngController Name of a constructor function registered with the current\n * {@link ng.$controllerProvider $controllerProvider} or an {@link guide/expression expression}\n * that on the current scope evaluates to a constructor function.\n *\n * The controller instance can be published into a scope property by specifying\n * `ng-controller=\"as propertyName\"`.\n *\n * If the current `$controllerProvider` is configured to use globals (via\n * {@link ng.$controllerProvider#allowGlobals `$controllerProvider.allowGlobals()` }), this may\n * also be the name of a globally accessible constructor function (deprecated, not recommended).\n *\n * @example\n * Here is a simple form for editing user contact information. Adding, removing, clearing, and\n * greeting are methods declared on the controller (see source tab). These methods can\n * easily be called from the angular markup. Any changes to the data are automatically reflected\n * in the View without the need for a manual update.\n *\n * Two different declaration styles are included below:\n *\n * * one binds methods and properties directly onto the controller using `this`:\n * `ng-controller=\"SettingsController1 as settings\"`\n * * one injects `$scope` into the controller:\n * `ng-controller=\"SettingsController2\"`\n *\n * The second option is more common in the Angular community, and is generally used in boilerplates\n * and in this guide. However, there are advantages to binding properties directly to the controller\n * and avoiding scope.\n *\n * * Using `controller as` makes it obvious which controller you are accessing in the template when\n * multiple controllers apply to an element.\n * * If you are writing your controllers as classes you have easier access to the properties and\n * methods, which will appear on the scope, from inside the controller code.\n * * Since there is always a `.` in the bindings, you don't have to worry about prototypal\n * inheritance masking primitives.\n *\n * This example demonstrates the `controller as` syntax.\n *\n * <example name=\"ngControllerAs\" module=\"controllerAsExample\">\n *   <file name=\"index.html\">\n *    <div id=\"ctrl-as-exmpl\" ng-controller=\"SettingsController1 as settings\">\n *      <label>Name: <input type=\"text\" ng-model=\"settings.name\"/></label>\n *      <button ng-click=\"settings.greet()\">greet</button><br/>\n *      Contact:\n *      <ul>\n *        <li ng-repeat=\"contact in settings.contacts\">\n *          <select ng-model=\"contact.type\" aria-label=\"Contact method\" id=\"select_{{$index}}\">\n *             <option>phone</option>\n *             <option>email</option>\n *          </select>\n *          <input type=\"text\" ng-model=\"contact.value\" aria-labelledby=\"select_{{$index}}\" />\n *          <button ng-click=\"settings.clearContact(contact)\">clear</button>\n *          <button ng-click=\"settings.removeContact(contact)\" aria-label=\"Remove\">X</button>\n *        </li>\n *        <li><button ng-click=\"settings.addContact()\">add</button></li>\n *     </ul>\n *    </div>\n *   </file>\n *   <file name=\"app.js\">\n *    angular.module('controllerAsExample', [])\n *      .controller('SettingsController1', SettingsController1);\n *\n *    function SettingsController1() {\n *      this.name = 'John Smith';\n *      this.contacts = [\n *        {type: 'phone', value: '408 555 1212'},\n *        {type: 'email', value: 'john.smith@example.org'}\n *      ];\n *    }\n *\n *    SettingsController1.prototype.greet = function() {\n *      alert(this.name);\n *    };\n *\n *    SettingsController1.prototype.addContact = function() {\n *      this.contacts.push({type: 'email', value: 'yourname@example.org'});\n *    };\n *\n *    SettingsController1.prototype.removeContact = function(contactToRemove) {\n *     var index = this.contacts.indexOf(contactToRemove);\n *      this.contacts.splice(index, 1);\n *    };\n *\n *    SettingsController1.prototype.clearContact = function(contact) {\n *      contact.type = 'phone';\n *      contact.value = '';\n *    };\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     it('should check controller as', function() {\n *       var container = element(by.id('ctrl-as-exmpl'));\n *         expect(container.element(by.model('settings.name'))\n *           .getAttribute('value')).toBe('John Smith');\n *\n *       var firstRepeat =\n *           container.element(by.repeater('contact in settings.contacts').row(0));\n *       var secondRepeat =\n *           container.element(by.repeater('contact in settings.contacts').row(1));\n *\n *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))\n *           .toBe('408 555 1212');\n *\n *       expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))\n *           .toBe('john.smith@example.org');\n *\n *       firstRepeat.element(by.buttonText('clear')).click();\n *\n *       expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))\n *           .toBe('');\n *\n *       container.element(by.buttonText('add')).click();\n *\n *       expect(container.element(by.repeater('contact in settings.contacts').row(2))\n *           .element(by.model('contact.value'))\n *           .getAttribute('value'))\n *           .toBe('yourname@example.org');\n *     });\n *   </file>\n * </example>\n *\n * This example demonstrates the \"attach to `$scope`\" style of controller.\n *\n * <example name=\"ngController\" module=\"controllerExample\">\n *  <file name=\"index.html\">\n *   <div id=\"ctrl-exmpl\" ng-controller=\"SettingsController2\">\n *     <label>Name: <input type=\"text\" ng-model=\"name\"/></label>\n *     <button ng-click=\"greet()\">greet</button><br/>\n *     Contact:\n *     <ul>\n *       <li ng-repeat=\"contact in contacts\">\n *         <select ng-model=\"contact.type\" id=\"select_{{$index}}\">\n *            <option>phone</option>\n *            <option>email</option>\n *         </select>\n *         <input type=\"text\" ng-model=\"contact.value\" aria-labelledby=\"select_{{$index}}\" />\n *         <button ng-click=\"clearContact(contact)\">clear</button>\n *         <button ng-click=\"removeContact(contact)\">X</button>\n *       </li>\n *       <li>[ <button ng-click=\"addContact()\">add</button> ]</li>\n *    </ul>\n *   </div>\n *  </file>\n *  <file name=\"app.js\">\n *   angular.module('controllerExample', [])\n *     .controller('SettingsController2', ['$scope', SettingsController2]);\n *\n *   function SettingsController2($scope) {\n *     $scope.name = 'John Smith';\n *     $scope.contacts = [\n *       {type:'phone', value:'408 555 1212'},\n *       {type:'email', value:'john.smith@example.org'}\n *     ];\n *\n *     $scope.greet = function() {\n *       alert($scope.name);\n *     };\n *\n *     $scope.addContact = function() {\n *       $scope.contacts.push({type:'email', value:'yourname@example.org'});\n *     };\n *\n *     $scope.removeContact = function(contactToRemove) {\n *       var index = $scope.contacts.indexOf(contactToRemove);\n *       $scope.contacts.splice(index, 1);\n *     };\n *\n *     $scope.clearContact = function(contact) {\n *       contact.type = 'phone';\n *       contact.value = '';\n *     };\n *   }\n *  </file>\n *  <file name=\"protractor.js\" type=\"protractor\">\n *    it('should check controller', function() {\n *      var container = element(by.id('ctrl-exmpl'));\n *\n *      expect(container.element(by.model('name'))\n *          .getAttribute('value')).toBe('John Smith');\n *\n *      var firstRepeat =\n *          container.element(by.repeater('contact in contacts').row(0));\n *      var secondRepeat =\n *          container.element(by.repeater('contact in contacts').row(1));\n *\n *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))\n *          .toBe('408 555 1212');\n *      expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))\n *          .toBe('john.smith@example.org');\n *\n *      firstRepeat.element(by.buttonText('clear')).click();\n *\n *      expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))\n *          .toBe('');\n *\n *      container.element(by.buttonText('add')).click();\n *\n *      expect(container.element(by.repeater('contact in contacts').row(2))\n *          .element(by.model('contact.value'))\n *          .getAttribute('value'))\n *          .toBe('yourname@example.org');\n *    });\n *  </file>\n *</example>\n\n */\nvar ngControllerDirective = [function() {\n  return {\n    restrict: 'A',\n    scope: true,\n    controller: '@',\n    priority: 500\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngCsp\n *\n * @restrict A\n * @element ANY\n * @description\n *\n * Angular has some features that can conflict with certain restrictions that are applied when using\n * [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) rules.\n *\n * If you intend to implement CSP with these rules then you must tell Angular not to use these\n * features.\n *\n * This is necessary when developing things like Google Chrome Extensions or Universal Windows Apps.\n *\n *\n * The following default rules in CSP affect Angular:\n *\n * * The use of `eval()`, `Function(string)` and similar functions to dynamically create and execute\n * code from strings is forbidden. Angular makes use of this in the {@link $parse} service to\n * provide a 30% increase in the speed of evaluating Angular expressions. (This CSP rule can be\n * disabled with the CSP keyword `unsafe-eval`, but it is generally not recommended as it would\n * weaken the protections offered by CSP.)\n *\n * * The use of inline resources, such as inline `<script>` and `<style>` elements, are forbidden.\n * This prevents apps from injecting custom styles directly into the document. Angular makes use of\n * this to include some CSS rules (e.g. {@link ngCloak} and {@link ngHide}). To make these\n * directives work when a CSP rule is blocking inline styles, you must link to the `angular-csp.css`\n * in your HTML manually. (This CSP rule can be disabled with the CSP keyword `unsafe-inline`, but\n * it is generally not recommended as it would weaken the protections offered by CSP.)\n *\n * If you do not provide `ngCsp` then Angular tries to autodetect if CSP is blocking dynamic code\n * creation from strings (e.g., `unsafe-eval` not specified in CSP header) and automatically\n * deactivates this feature in the {@link $parse} service. This autodetection, however, triggers a\n * CSP error to be logged in the console:\n *\n * ```\n * Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of\n * script in the following Content Security Policy directive: \"default-src 'self'\". Note that\n * 'script-src' was not explicitly set, so 'default-src' is used as a fallback.\n * ```\n *\n * This error is harmless but annoying. To prevent the error from showing up, put the `ngCsp`\n * directive on an element of the HTML document that appears before the `<script>` tag that loads\n * the `angular.js` file.\n *\n * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.*\n *\n * You can specify which of the CSP related Angular features should be deactivated by providing\n * a value for the `ng-csp` attribute. The options are as follows:\n *\n * * no-inline-style: this stops Angular from injecting CSS styles into the DOM\n *\n * * no-unsafe-eval: this stops Angular from optimizing $parse with unsafe eval of strings\n *\n * You can use these values in the following combinations:\n *\n *\n * * No declaration means that Angular will assume that you can do inline styles, but it will do\n * a runtime check for unsafe-eval. E.g. `<body>`. This is backwardly compatible with previous\n * versions of Angular.\n *\n * * A simple `ng-csp` (or `data-ng-csp`) attribute will tell Angular to deactivate both inline\n * styles and unsafe eval. E.g. `<body ng-csp>`. This is backwardly compatible with previous\n * versions of Angular.\n *\n * * Specifying only `no-unsafe-eval` tells Angular that we must not use eval, but that we can\n * inject inline styles. E.g. `<body ng-csp=\"no-unsafe-eval\">`.\n *\n * * Specifying only `no-inline-style` tells Angular that we must not inject styles, but that we can\n * run eval - no automatic check for unsafe eval will occur. E.g. `<body ng-csp=\"no-inline-style\">`\n *\n * * Specifying both `no-unsafe-eval` and `no-inline-style` tells Angular that we must not inject\n * styles nor use eval, which is the same as an empty: ng-csp.\n * E.g.`<body ng-csp=\"no-inline-style;no-unsafe-eval\">`\n *\n * @example\n * This example shows how to apply the `ngCsp` directive to the `html` tag.\n   ```html\n     <!doctype html>\n     <html ng-app ng-csp>\n     ...\n     ...\n     </html>\n   ```\n  * @example\n      <!-- Note: the `.csp` suffix in the example name triggers CSP mode in our http server! -->\n      <example name=\"example.csp\" module=\"cspExample\" ng-csp=\"true\">\n        <file name=\"index.html\">\n          <div ng-controller=\"MainController as ctrl\">\n            <div>\n              <button ng-click=\"ctrl.inc()\" id=\"inc\">Increment</button>\n              <span id=\"counter\">\n                {{ctrl.counter}}\n              </span>\n            </div>\n\n            <div>\n              <button ng-click=\"ctrl.evil()\" id=\"evil\">Evil</button>\n              <span id=\"evilError\">\n                {{ctrl.evilError}}\n              </span>\n            </div>\n          </div>\n        </file>\n        <file name=\"script.js\">\n           angular.module('cspExample', [])\n             .controller('MainController', function MainController() {\n                this.counter = 0;\n                this.inc = function() {\n                  this.counter++;\n                };\n                this.evil = function() {\n                  try {\n                    eval('1+2'); // eslint-disable-line no-eval\n                  } catch (e) {\n                    this.evilError = e.message;\n                  }\n                };\n              });\n        </file>\n        <file name=\"protractor.js\" type=\"protractor\">\n          var util, webdriver;\n\n          var incBtn = element(by.id('inc'));\n          var counter = element(by.id('counter'));\n          var evilBtn = element(by.id('evil'));\n          var evilError = element(by.id('evilError'));\n\n          function getAndClearSevereErrors() {\n            return browser.manage().logs().get('browser').then(function(browserLog) {\n              return browserLog.filter(function(logEntry) {\n                return logEntry.level.value > webdriver.logging.Level.WARNING.value;\n              });\n            });\n          }\n\n          function clearErrors() {\n            getAndClearSevereErrors();\n          }\n\n          function expectNoErrors() {\n            getAndClearSevereErrors().then(function(filteredLog) {\n              expect(filteredLog.length).toEqual(0);\n              if (filteredLog.length) {\n                console.log('browser console errors: ' + util.inspect(filteredLog));\n              }\n            });\n          }\n\n          function expectError(regex) {\n            getAndClearSevereErrors().then(function(filteredLog) {\n              var found = false;\n              filteredLog.forEach(function(log) {\n                if (log.message.match(regex)) {\n                  found = true;\n                }\n              });\n              if (!found) {\n                throw new Error('expected an error that matches ' + regex);\n              }\n            });\n          }\n\n          beforeEach(function() {\n            util = require('util');\n            webdriver = require('selenium-webdriver');\n          });\n\n          // For now, we only test on Chrome,\n          // as Safari does not load the page with Protractor's injected scripts,\n          // and Firefox webdriver always disables content security policy (#6358)\n          if (browser.params.browser !== 'chrome') {\n            return;\n          }\n\n          it('should not report errors when the page is loaded', function() {\n            // clear errors so we are not dependent on previous tests\n            clearErrors();\n            // Need to reload the page as the page is already loaded when\n            // we come here\n            browser.driver.getCurrentUrl().then(function(url) {\n              browser.get(url);\n            });\n            expectNoErrors();\n          });\n\n          it('should evaluate expressions', function() {\n            expect(counter.getText()).toEqual('0');\n            incBtn.click();\n            expect(counter.getText()).toEqual('1');\n            expectNoErrors();\n          });\n\n          it('should throw and report an error when using \"eval\"', function() {\n            evilBtn.click();\n            expect(evilError.getText()).toMatch(/Content Security Policy/);\n            expectError(/Content Security Policy/);\n          });\n        </file>\n      </example>\n  */\n\n// `ngCsp` is not implemented as a proper directive any more, because we need it be processed while\n// we bootstrap the app (before `$parse` is instantiated). For this reason, we just have the `csp()`\n// fn that looks for the `ng-csp` attribute anywhere in the current doc.\n\n/**\n * @ngdoc directive\n * @name ngClick\n *\n * @description\n * The ngClick directive allows you to specify custom behavior when\n * an element is clicked.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngClick {@link guide/expression Expression} to evaluate upon\n * click. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-click\">\n     <file name=\"index.html\">\n      <button ng-click=\"count = count + 1\" ng-init=\"count=0\">\n        Increment\n      </button>\n      <span>\n        count: {{count}}\n      </span>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-click', function() {\n         expect(element(by.binding('count')).getText()).toMatch('0');\n         element(by.css('button')).click();\n         expect(element(by.binding('count')).getText()).toMatch('1');\n       });\n     </file>\n   </example>\n */\n/*\n * A collection of directives that allows creation of custom event handlers that are defined as\n * angular expressions and are compiled and executed within the current scope.\n */\nvar ngEventDirectives = {};\n\n// For events that might fire synchronously during DOM manipulation\n// we need to execute their event handlers asynchronously using $evalAsync,\n// so that they are not executed in an inconsistent state.\nvar forceAsyncEvents = {\n  'blur': true,\n  'focus': true\n};\nforEach(\n  'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),\n  function(eventName) {\n    var directiveName = directiveNormalize('ng-' + eventName);\n    ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {\n      return {\n        restrict: 'A',\n        compile: function($element, attr) {\n          // NOTE:\n          // We expose the powerful `$event` object on the scope that provides access to the Window,\n          // etc. This is OK, because expressions are not sandboxed any more (and the expression\n          // sandbox was never meant to be a security feature anyway).\n          var fn = $parse(attr[directiveName]);\n          return function ngEventHandler(scope, element) {\n            element.on(eventName, function(event) {\n              var callback = function() {\n                fn(scope, {$event: event});\n              };\n              if (forceAsyncEvents[eventName] && $rootScope.$$phase) {\n                scope.$evalAsync(callback);\n              } else {\n                scope.$apply(callback);\n              }\n            });\n          };\n        }\n      };\n    }];\n  }\n);\n\n/**\n * @ngdoc directive\n * @name ngDblclick\n *\n * @description\n * The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon\n * a dblclick. (The Event object is available as `$event`)\n *\n * @example\n   <example name=\"ng-dblclick\">\n     <file name=\"index.html\">\n      <button ng-dblclick=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (on double click)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMousedown\n *\n * @description\n * The ngMousedown directive allows you to specify custom behavior on mousedown event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon\n * mousedown. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mousedown\">\n     <file name=\"index.html\">\n      <button ng-mousedown=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (on mouse down)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMouseup\n *\n * @description\n * Specify custom behavior on mouseup event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon\n * mouseup. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mouseup\">\n     <file name=\"index.html\">\n      <button ng-mouseup=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (on mouse up)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngMouseover\n *\n * @description\n * Specify custom behavior on mouseover event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon\n * mouseover. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mouseover\">\n     <file name=\"index.html\">\n      <button ng-mouseover=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (when mouse is over)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMouseenter\n *\n * @description\n * Specify custom behavior on mouseenter event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon\n * mouseenter. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mouseenter\">\n     <file name=\"index.html\">\n      <button ng-mouseenter=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (when mouse enters)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMouseleave\n *\n * @description\n * Specify custom behavior on mouseleave event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon\n * mouseleave. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mouseleave\">\n     <file name=\"index.html\">\n      <button ng-mouseleave=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (when mouse leaves)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngMousemove\n *\n * @description\n * Specify custom behavior on mousemove event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon\n * mousemove. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-mousemove\">\n     <file name=\"index.html\">\n      <button ng-mousemove=\"count = count + 1\" ng-init=\"count=0\">\n        Increment (when mouse moves)\n      </button>\n      count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngKeydown\n *\n * @description\n * Specify custom behavior on keydown event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon\n * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)\n *\n * @example\n   <example name=\"ng-keydown\">\n     <file name=\"index.html\">\n      <input ng-keydown=\"count = count + 1\" ng-init=\"count=0\">\n      key down count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngKeyup\n *\n * @description\n * Specify custom behavior on keyup event.\n *\n * @element ANY\n * @priority 0\n * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon\n * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)\n *\n * @example\n   <example name=\"ng-keyup\">\n     <file name=\"index.html\">\n       <p>Typing in the input box below updates the key count</p>\n       <input ng-keyup=\"count = count + 1\" ng-init=\"count=0\"> key up count: {{count}}\n\n       <p>Typing in the input box below updates the keycode</p>\n       <input ng-keyup=\"event=$event\">\n       <p>event keyCode: {{ event.keyCode }}</p>\n       <p>event altKey: {{ event.altKey }}</p>\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngKeypress\n *\n * @description\n * Specify custom behavior on keypress event.\n *\n * @element ANY\n * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon\n * keypress. ({@link guide/expression#-event- Event object is available as `$event`}\n * and can be interrogated for keyCode, altKey, etc.)\n *\n * @example\n   <example name=\"ng-keypress\">\n     <file name=\"index.html\">\n      <input ng-keypress=\"count = count + 1\" ng-init=\"count=0\">\n      key press count: {{count}}\n     </file>\n   </example>\n */\n\n\n/**\n * @ngdoc directive\n * @name ngSubmit\n *\n * @description\n * Enables binding angular expressions to onsubmit events.\n *\n * Additionally it prevents the default action (which for form means sending the request to the\n * server and reloading the current page), but only if the form does not contain `action`,\n * `data-action`, or `x-action` attributes.\n *\n * <div class=\"alert alert-warning\">\n * **Warning:** Be careful not to cause \"double-submission\" by using both the `ngClick` and\n * `ngSubmit` handlers together. See the\n * {@link form#submitting-a-form-and-preventing-the-default-action `form` directive documentation}\n * for a detailed discussion of when `ngSubmit` may be triggered.\n * </div>\n *\n * @element form\n * @priority 0\n * @param {expression} ngSubmit {@link guide/expression Expression} to eval.\n * ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example module=\"submitExample\" name=\"ng-submit\">\n     <file name=\"index.html\">\n      <script>\n        angular.module('submitExample', [])\n          .controller('ExampleController', ['$scope', function($scope) {\n            $scope.list = [];\n            $scope.text = 'hello';\n            $scope.submit = function() {\n              if ($scope.text) {\n                $scope.list.push(this.text);\n                $scope.text = '';\n              }\n            };\n          }]);\n      </script>\n      <form ng-submit=\"submit()\" ng-controller=\"ExampleController\">\n        Enter text and hit enter:\n        <input type=\"text\" ng-model=\"text\" name=\"text\" />\n        <input type=\"submit\" id=\"submit\" value=\"Submit\" />\n        <pre>list={{list}}</pre>\n      </form>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-submit', function() {\n         expect(element(by.binding('list')).getText()).toBe('list=[]');\n         element(by.css('#submit')).click();\n         expect(element(by.binding('list')).getText()).toContain('hello');\n         expect(element(by.model('text')).getAttribute('value')).toBe('');\n       });\n       it('should ignore empty strings', function() {\n         expect(element(by.binding('list')).getText()).toBe('list=[]');\n         element(by.css('#submit')).click();\n         element(by.css('#submit')).click();\n         expect(element(by.binding('list')).getText()).toContain('hello');\n        });\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngFocus\n *\n * @description\n * Specify custom behavior on focus event.\n *\n * Note: As the `focus` event is executed synchronously when calling `input.focus()`\n * AngularJS executes the expression using `scope.$evalAsync` if the event is fired\n * during an `$apply` to ensure a consistent state.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon\n * focus. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n * See {@link ng.directive:ngClick ngClick}\n */\n\n/**\n * @ngdoc directive\n * @name ngBlur\n *\n * @description\n * Specify custom behavior on blur event.\n *\n * A [blur event](https://developer.mozilla.org/en-US/docs/Web/Events/blur) fires when\n * an element has lost focus.\n *\n * Note: As the `blur` event is executed synchronously also during DOM manipulations\n * (e.g. removing a focussed input),\n * AngularJS executes the expression using `scope.$evalAsync` if the event is fired\n * during an `$apply` to ensure a consistent state.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon\n * blur. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n * See {@link ng.directive:ngClick ngClick}\n */\n\n/**\n * @ngdoc directive\n * @name ngCopy\n *\n * @description\n * Specify custom behavior on copy event.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon\n * copy. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-copy\">\n     <file name=\"index.html\">\n      <input ng-copy=\"copied=true\" ng-init=\"copied=false; value='copy me'\" ng-model=\"value\">\n      copied: {{copied}}\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngCut\n *\n * @description\n * Specify custom behavior on cut event.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngCut {@link guide/expression Expression} to evaluate upon\n * cut. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-cut\">\n     <file name=\"index.html\">\n      <input ng-cut=\"cut=true\" ng-init=\"cut=false; value='cut me'\" ng-model=\"value\">\n      cut: {{cut}}\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngPaste\n *\n * @description\n * Specify custom behavior on paste event.\n *\n * @element window, input, select, textarea, a\n * @priority 0\n * @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon\n * paste. ({@link guide/expression#-event- Event object is available as `$event`})\n *\n * @example\n   <example name=\"ng-paste\">\n     <file name=\"index.html\">\n      <input ng-paste=\"paste=true\" ng-init=\"paste=false\" placeholder='paste here'>\n      pasted: {{paste}}\n     </file>\n   </example>\n */\n\n/**\n * @ngdoc directive\n * @name ngIf\n * @restrict A\n * @multiElement\n *\n * @description\n * The `ngIf` directive removes or recreates a portion of the DOM tree based on an\n * {expression}. If the expression assigned to `ngIf` evaluates to a false\n * value then the element is removed from the DOM, otherwise a clone of the\n * element is reinserted into the DOM.\n *\n * `ngIf` differs from `ngShow` and `ngHide` in that `ngIf` completely removes and recreates the\n * element in the DOM rather than changing its visibility via the `display` css property.  A common\n * case when this difference is significant is when using css selectors that rely on an element's\n * position within the DOM, such as the `:first-child` or `:last-child` pseudo-classes.\n *\n * Note that when an element is removed using `ngIf` its scope is destroyed and a new scope\n * is created when the element is restored.  The scope created within `ngIf` inherits from\n * its parent scope using\n * [prototypal inheritance](https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance).\n * An important implication of this is if `ngModel` is used within `ngIf` to bind to\n * a javascript primitive defined in the parent scope. In this case any modifications made to the\n * variable within the child scope will override (hide) the value in the parent scope.\n *\n * Also, `ngIf` recreates elements using their compiled state. An example of this behavior\n * is if an element's class attribute is directly modified after it's compiled, using something like\n * jQuery's `.addClass()` method, and the element is later removed. When `ngIf` recreates the element\n * the added class will be lost because the original compiled state is used to regenerate the element.\n *\n * Additionally, you can provide animations via the `ngAnimate` module to animate the `enter`\n * and `leave` effects.\n *\n * @animations\n * | Animation                        | Occurs                               |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#enter enter}  | just after the `ngIf` contents change and a new DOM element is created and injected into the `ngIf` container |\n * | {@link ng.$animate#leave leave}  | just before the `ngIf` contents are removed from the DOM |\n *\n * @element ANY\n * @scope\n * @priority 600\n * @param {expression} ngIf If the {@link guide/expression expression} is falsy then\n *     the element is removed from the DOM tree. If it is truthy a copy of the compiled\n *     element is added to the DOM tree.\n *\n * @example\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-if\">\n    <file name=\"index.html\">\n      <label>Click me: <input type=\"checkbox\" ng-model=\"checked\" ng-init=\"checked=true\" /></label><br/>\n      Show when checked:\n      <span ng-if=\"checked\" class=\"animate-if\">\n        This is removed when the checkbox is unchecked.\n      </span>\n    </file>\n    <file name=\"animations.css\">\n      .animate-if {\n        background:white;\n        border:1px solid black;\n        padding:10px;\n      }\n\n      .animate-if.ng-enter, .animate-if.ng-leave {\n        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;\n      }\n\n      .animate-if.ng-enter,\n      .animate-if.ng-leave.ng-leave-active {\n        opacity:0;\n      }\n\n      .animate-if.ng-leave,\n      .animate-if.ng-enter.ng-enter-active {\n        opacity:1;\n      }\n    </file>\n  </example>\n */\nvar ngIfDirective = ['$animate', '$compile', function($animate, $compile) {\n  return {\n    multiElement: true,\n    transclude: 'element',\n    priority: 600,\n    terminal: true,\n    restrict: 'A',\n    $$tlb: true,\n    link: function($scope, $element, $attr, ctrl, $transclude) {\n        var block, childScope, previousElements;\n        $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {\n\n          if (value) {\n            if (!childScope) {\n              $transclude(function(clone, newScope) {\n                childScope = newScope;\n                clone[clone.length++] = $compile.$$createComment('end ngIf', $attr.ngIf);\n                // Note: We only need the first/last node of the cloned nodes.\n                // However, we need to keep the reference to the jqlite wrapper as it might be changed later\n                // by a directive with templateUrl when its template arrives.\n                block = {\n                  clone: clone\n                };\n                $animate.enter(clone, $element.parent(), $element);\n              });\n            }\n          } else {\n            if (previousElements) {\n              previousElements.remove();\n              previousElements = null;\n            }\n            if (childScope) {\n              childScope.$destroy();\n              childScope = null;\n            }\n            if (block) {\n              previousElements = getBlockNodes(block.clone);\n              $animate.leave(previousElements).done(function(response) {\n                if (response !== false) previousElements = null;\n              });\n              block = null;\n            }\n          }\n        });\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngInclude\n * @restrict ECA\n *\n * @description\n * Fetches, compiles and includes an external HTML fragment.\n *\n * By default, the template URL is restricted to the same domain and protocol as the\n * application document. This is done by calling {@link $sce#getTrustedResourceUrl\n * $sce.getTrustedResourceUrl} on it. To load templates from other domains or protocols\n * you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist them} or\n * {@link $sce#trustAsResourceUrl wrap them} as trusted values. Refer to Angular's {@link\n * ng.$sce Strict Contextual Escaping}.\n *\n * In addition, the browser's\n * [Same Origin Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest)\n * and [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/)\n * policy may further restrict whether the template is successfully loaded.\n * For example, `ngInclude` won't work for cross-domain requests on all browsers and for `file://`\n * access on some browsers.\n *\n * @animations\n * | Animation                        | Occurs                              |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#enter enter}  | when the expression changes, on the new include |\n * | {@link ng.$animate#leave leave}  | when the expression changes, on the old include |\n *\n * The enter and leave animation occur concurrently.\n *\n * @scope\n * @priority 400\n *\n * @param {string} ngInclude|src angular expression evaluating to URL. If the source is a string constant,\n *                 make sure you wrap it in **single** quotes, e.g. `src=\"'myPartialTemplate.html'\"`.\n * @param {string=} onload Expression to evaluate when a new partial is loaded.\n *                  <div class=\"alert alert-warning\">\n *                  **Note:** When using onload on SVG elements in IE11, the browser will try to call\n *                  a function with the name on the window element, which will usually throw a\n *                  \"function is undefined\" error. To fix this, you can instead use `data-onload` or a\n *                  different form that {@link guide/directive#normalization matches} `onload`.\n *                  </div>\n   *\n * @param {string=} autoscroll Whether `ngInclude` should call {@link ng.$anchorScroll\n *                  $anchorScroll} to scroll the viewport after the content is loaded.\n *\n *                  - If the attribute is not set, disable scrolling.\n *                  - If the attribute is set without value, enable scrolling.\n *                  - Otherwise enable scrolling only if the expression evaluates to truthy value.\n *\n * @example\n  <example module=\"includeExample\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-include\">\n    <file name=\"index.html\">\n     <div ng-controller=\"ExampleController\">\n       <select ng-model=\"template\" ng-options=\"t.name for t in templates\">\n        <option value=\"\">(blank)</option>\n       </select>\n       url of the template: <code>{{template.url}}</code>\n       <hr/>\n       <div class=\"slide-animate-container\">\n         <div class=\"slide-animate\" ng-include=\"template.url\"></div>\n       </div>\n     </div>\n    </file>\n    <file name=\"script.js\">\n      angular.module('includeExample', ['ngAnimate'])\n        .controller('ExampleController', ['$scope', function($scope) {\n          $scope.templates =\n            [{ name: 'template1.html', url: 'template1.html'},\n             { name: 'template2.html', url: 'template2.html'}];\n          $scope.template = $scope.templates[0];\n        }]);\n     </file>\n    <file name=\"template1.html\">\n      Content of template1.html\n    </file>\n    <file name=\"template2.html\">\n      Content of template2.html\n    </file>\n    <file name=\"animations.css\">\n      .slide-animate-container {\n        position:relative;\n        background:white;\n        border:1px solid black;\n        height:40px;\n        overflow:hidden;\n      }\n\n      .slide-animate {\n        padding:10px;\n      }\n\n      .slide-animate.ng-enter, .slide-animate.ng-leave {\n        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;\n\n        position:absolute;\n        top:0;\n        left:0;\n        right:0;\n        bottom:0;\n        display:block;\n        padding:10px;\n      }\n\n      .slide-animate.ng-enter {\n        top:-50px;\n      }\n      .slide-animate.ng-enter.ng-enter-active {\n        top:0;\n      }\n\n      .slide-animate.ng-leave {\n        top:0;\n      }\n      .slide-animate.ng-leave.ng-leave-active {\n        top:50px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var templateSelect = element(by.model('template'));\n      var includeElem = element(by.css('[ng-include]'));\n\n      it('should load template1.html', function() {\n        expect(includeElem.getText()).toMatch(/Content of template1.html/);\n      });\n\n      it('should load template2.html', function() {\n        if (browser.params.browser === 'firefox') {\n          // Firefox can't handle using selects\n          // See https://github.com/angular/protractor/issues/480\n          return;\n        }\n        templateSelect.click();\n        templateSelect.all(by.css('option')).get(2).click();\n        expect(includeElem.getText()).toMatch(/Content of template2.html/);\n      });\n\n      it('should change to blank', function() {\n        if (browser.params.browser === 'firefox') {\n          // Firefox can't handle using selects\n          return;\n        }\n        templateSelect.click();\n        templateSelect.all(by.css('option')).get(0).click();\n        expect(includeElem.isPresent()).toBe(false);\n      });\n    </file>\n  </example>\n */\n\n\n/**\n * @ngdoc event\n * @name ngInclude#$includeContentRequested\n * @eventType emit on the scope ngInclude was declared in\n * @description\n * Emitted every time the ngInclude content is requested.\n *\n * @param {Object} angularEvent Synthetic event object.\n * @param {String} src URL of content to load.\n */\n\n\n/**\n * @ngdoc event\n * @name ngInclude#$includeContentLoaded\n * @eventType emit on the current ngInclude scope\n * @description\n * Emitted every time the ngInclude content is reloaded.\n *\n * @param {Object} angularEvent Synthetic event object.\n * @param {String} src URL of content to load.\n */\n\n\n/**\n * @ngdoc event\n * @name ngInclude#$includeContentError\n * @eventType emit on the scope ngInclude was declared in\n * @description\n * Emitted when a template HTTP request yields an erroneous response (status < 200 || status > 299)\n *\n * @param {Object} angularEvent Synthetic event object.\n * @param {String} src URL of content to load.\n */\nvar ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate',\n                  function($templateRequest,   $anchorScroll,   $animate) {\n  return {\n    restrict: 'ECA',\n    priority: 400,\n    terminal: true,\n    transclude: 'element',\n    controller: angular.noop,\n    compile: function(element, attr) {\n      var srcExp = attr.ngInclude || attr.src,\n          onloadExp = attr.onload || '',\n          autoScrollExp = attr.autoscroll;\n\n      return function(scope, $element, $attr, ctrl, $transclude) {\n        var changeCounter = 0,\n            currentScope,\n            previousElement,\n            currentElement;\n\n        var cleanupLastIncludeContent = function() {\n          if (previousElement) {\n            previousElement.remove();\n            previousElement = null;\n          }\n          if (currentScope) {\n            currentScope.$destroy();\n            currentScope = null;\n          }\n          if (currentElement) {\n            $animate.leave(currentElement).done(function(response) {\n              if (response !== false) previousElement = null;\n            });\n            previousElement = currentElement;\n            currentElement = null;\n          }\n        };\n\n        scope.$watch(srcExp, function ngIncludeWatchAction(src) {\n          var afterAnimation = function(response) {\n            if (response !== false && isDefined(autoScrollExp) &&\n              (!autoScrollExp || scope.$eval(autoScrollExp))) {\n                $anchorScroll();\n            }\n          };\n          var thisChangeId = ++changeCounter;\n\n          if (src) {\n            //set the 2nd param to true to ignore the template request error so that the inner\n            //contents and scope can be cleaned up.\n            $templateRequest(src, true).then(function(response) {\n              if (scope.$$destroyed) return;\n\n              if (thisChangeId !== changeCounter) return;\n              var newScope = scope.$new();\n              ctrl.template = response;\n\n              // Note: This will also link all children of ng-include that were contained in the original\n              // html. If that content contains controllers, ... they could pollute/change the scope.\n              // However, using ng-include on an element with additional content does not make sense...\n              // Note: We can't remove them in the cloneAttchFn of $transclude as that\n              // function is called before linking the content, which would apply child\n              // directives to non existing elements.\n              var clone = $transclude(newScope, function(clone) {\n                cleanupLastIncludeContent();\n                $animate.enter(clone, null, $element).done(afterAnimation);\n              });\n\n              currentScope = newScope;\n              currentElement = clone;\n\n              currentScope.$emit('$includeContentLoaded', src);\n              scope.$eval(onloadExp);\n            }, function() {\n              if (scope.$$destroyed) return;\n\n              if (thisChangeId === changeCounter) {\n                cleanupLastIncludeContent();\n                scope.$emit('$includeContentError', src);\n              }\n            });\n            scope.$emit('$includeContentRequested', src);\n          } else {\n            cleanupLastIncludeContent();\n            ctrl.template = null;\n          }\n        });\n      };\n    }\n  };\n}];\n\n// This directive is called during the $transclude call of the first `ngInclude` directive.\n// It will replace and compile the content of the element with the loaded template.\n// We need this directive so that the element content is already filled when\n// the link function of another directive on the same element as ngInclude\n// is called.\nvar ngIncludeFillContentDirective = ['$compile',\n  function($compile) {\n    return {\n      restrict: 'ECA',\n      priority: -400,\n      require: 'ngInclude',\n      link: function(scope, $element, $attr, ctrl) {\n        if (toString.call($element[0]).match(/SVG/)) {\n          // WebKit: https://bugs.webkit.org/show_bug.cgi?id=135698 --- SVG elements do not\n          // support innerHTML, so detect this here and try to generate the contents\n          // specially.\n          $element.empty();\n          $compile(jqLiteBuildFragment(ctrl.template, window.document).childNodes)(scope,\n              function namespaceAdaptedClone(clone) {\n            $element.append(clone);\n          }, {futureParentElement: $element});\n          return;\n        }\n\n        $element.html(ctrl.template);\n        $compile($element.contents())(scope);\n      }\n    };\n  }];\n\n/**\n * @ngdoc directive\n * @name ngInit\n * @restrict AC\n *\n * @description\n * The `ngInit` directive allows you to evaluate an expression in the\n * current scope.\n *\n * <div class=\"alert alert-danger\">\n * This directive can be abused to add unnecessary amounts of logic into your templates.\n * There are only a few appropriate uses of `ngInit`, such as for aliasing special properties of\n * {@link ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below; and for injecting data via\n * server side scripting. Besides these few cases, you should use {@link guide/controller controllers}\n * rather than `ngInit` to initialize values on a scope.\n * </div>\n *\n * <div class=\"alert alert-warning\">\n * **Note**: If you have assignment in `ngInit` along with a {@link ng.$filter `filter`}, make\n * sure you have parentheses to ensure correct operator precedence:\n * <pre class=\"prettyprint\">\n * `<div ng-init=\"test1 = ($index | toString)\"></div>`\n * </pre>\n * </div>\n *\n * @priority 450\n *\n * @element ANY\n * @param {expression} ngInit {@link guide/expression Expression} to eval.\n *\n * @example\n   <example module=\"initExample\" name=\"ng-init\">\n     <file name=\"index.html\">\n   <script>\n     angular.module('initExample', [])\n       .controller('ExampleController', ['$scope', function($scope) {\n         $scope.list = [['a', 'b'], ['c', 'd']];\n       }]);\n   </script>\n   <div ng-controller=\"ExampleController\">\n     <div ng-repeat=\"innerList in list\" ng-init=\"outerIndex = $index\">\n       <div ng-repeat=\"value in innerList\" ng-init=\"innerIndex = $index\">\n          <span class=\"example-init\">list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}};</span>\n       </div>\n     </div>\n   </div>\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       it('should alias index positions', function() {\n         var elements = element.all(by.css('.example-init'));\n         expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;');\n         expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;');\n         expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;');\n         expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;');\n       });\n     </file>\n   </example>\n */\nvar ngInitDirective = ngDirective({\n  priority: 450,\n  compile: function() {\n    return {\n      pre: function(scope, element, attrs) {\n        scope.$eval(attrs.ngInit);\n      }\n    };\n  }\n});\n\n/**\n * @ngdoc directive\n * @name ngList\n *\n * @description\n * Text input that converts between a delimited string and an array of strings. The default\n * delimiter is a comma followed by a space - equivalent to `ng-list=\", \"`. You can specify a custom\n * delimiter as the value of the `ngList` attribute - for example, `ng-list=\" | \"`.\n *\n * The behaviour of the directive is affected by the use of the `ngTrim` attribute.\n * * If `ngTrim` is set to `\"false\"` then whitespace around both the separator and each\n *   list item is respected. This implies that the user of the directive is responsible for\n *   dealing with whitespace but also allows you to use whitespace as a delimiter, such as a\n *   tab or newline character.\n * * Otherwise whitespace around the delimiter is ignored when splitting (although it is respected\n *   when joining the list items back together) and whitespace around each list item is stripped\n *   before it is added to the model.\n *\n * ### Example with Validation\n *\n * <example name=\"ngList-directive\" module=\"listExample\">\n *   <file name=\"app.js\">\n *      angular.module('listExample', [])\n *        .controller('ExampleController', ['$scope', function($scope) {\n *          $scope.names = ['morpheus', 'neo', 'trinity'];\n *        }]);\n *   </file>\n *   <file name=\"index.html\">\n *    <form name=\"myForm\" ng-controller=\"ExampleController\">\n *      <label>List: <input name=\"namesInput\" ng-model=\"names\" ng-list required></label>\n *      <span role=\"alert\">\n *        <span class=\"error\" ng-show=\"myForm.namesInput.$error.required\">\n *        Required!</span>\n *      </span>\n *      <br>\n *      <tt>names = {{names}}</tt><br/>\n *      <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>\n *      <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>\n *      <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>\n *      <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>\n *     </form>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     var listInput = element(by.model('names'));\n *     var names = element(by.exactBinding('names'));\n *     var valid = element(by.binding('myForm.namesInput.$valid'));\n *     var error = element(by.css('span.error'));\n *\n *     it('should initialize to model', function() {\n *       expect(names.getText()).toContain('[\"morpheus\",\"neo\",\"trinity\"]');\n *       expect(valid.getText()).toContain('true');\n *       expect(error.getCssValue('display')).toBe('none');\n *     });\n *\n *     it('should be invalid if empty', function() {\n *       listInput.clear();\n *       listInput.sendKeys('');\n *\n *       expect(names.getText()).toContain('');\n *       expect(valid.getText()).toContain('false');\n *       expect(error.getCssValue('display')).not.toBe('none');\n *     });\n *   </file>\n * </example>\n *\n * ### Example - splitting on newline\n * <example name=\"ngList-directive-newlines\">\n *   <file name=\"index.html\">\n *    <textarea ng-model=\"list\" ng-list=\"&#10;\" ng-trim=\"false\"></textarea>\n *    <pre>{{ list | json }}</pre>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     it(\"should split the text by newlines\", function() {\n *       var listInput = element(by.model('list'));\n *       var output = element(by.binding('list | json'));\n *       listInput.sendKeys('abc\\ndef\\nghi');\n *       expect(output.getText()).toContain('[\\n  \"abc\",\\n  \"def\",\\n  \"ghi\"\\n]');\n *     });\n *   </file>\n * </example>\n *\n * @element input\n * @param {string=} ngList optional delimiter that should be used to split the value.\n */\nvar ngListDirective = function() {\n  return {\n    restrict: 'A',\n    priority: 100,\n    require: 'ngModel',\n    link: function(scope, element, attr, ctrl) {\n      var ngList = attr.ngList || ', ';\n      var trimValues = attr.ngTrim !== 'false';\n      var separator = trimValues ? trim(ngList) : ngList;\n\n      var parse = function(viewValue) {\n        // If the viewValue is invalid (say required but empty) it will be `undefined`\n        if (isUndefined(viewValue)) return;\n\n        var list = [];\n\n        if (viewValue) {\n          forEach(viewValue.split(separator), function(value) {\n            if (value) list.push(trimValues ? trim(value) : value);\n          });\n        }\n\n        return list;\n      };\n\n      ctrl.$parsers.push(parse);\n      ctrl.$formatters.push(function(value) {\n        if (isArray(value)) {\n          return value.join(ngList);\n        }\n\n        return undefined;\n      });\n\n      // Override the standard $isEmpty because an empty array means the input is empty.\n      ctrl.$isEmpty = function(value) {\n        return !value || !value.length;\n      };\n    }\n  };\n};\n\n/* global VALID_CLASS: true,\n  INVALID_CLASS: true,\n  PRISTINE_CLASS: true,\n  DIRTY_CLASS: true,\n  UNTOUCHED_CLASS: true,\n  TOUCHED_CLASS: true,\n  PENDING_CLASS: true,\n  addSetValidityMethod: true,\n  setupValidity: true,\n  defaultModelOptions: false\n*/\n\n\nvar VALID_CLASS = 'ng-valid',\n    INVALID_CLASS = 'ng-invalid',\n    PRISTINE_CLASS = 'ng-pristine',\n    DIRTY_CLASS = 'ng-dirty',\n    UNTOUCHED_CLASS = 'ng-untouched',\n    TOUCHED_CLASS = 'ng-touched',\n    EMPTY_CLASS = 'ng-empty',\n    NOT_EMPTY_CLASS = 'ng-not-empty';\n\nvar ngModelMinErr = minErr('ngModel');\n\n/**\n * @ngdoc type\n * @name ngModel.NgModelController\n *\n * @property {*} $viewValue The actual value from the control's view. For `input` elements, this is a\n * String. See {@link ngModel.NgModelController#$setViewValue} for information about when the $viewValue\n * is set.\n *\n * @property {*} $modelValue The value in the model that the control is bound to.\n *\n * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever\n *  the control updates the ngModelController with a new {@link ngModel.NgModelController#$viewValue\n    `$viewValue`} from the DOM, usually via user input.\n    See {@link ngModel.NgModelController#$setViewValue `$setViewValue()`} for a detailed lifecycle explanation.\n    Note that the `$parsers` are not called when the bound ngModel expression changes programmatically.\n\n  The functions are called in array order, each passing\n    its return value through to the next. The last return value is forwarded to the\n    {@link ngModel.NgModelController#$validators `$validators`} collection.\n\n  Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue\n    `$viewValue`}.\n\n  Returning `undefined` from a parser means a parse error occurred. In that case,\n    no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel`\n    will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`}\n    is set to `true`. The parse error is stored in `ngModel.$error.parse`.\n\n  This simple example shows a parser that would convert text input value to lowercase:\n * ```js\n * function parse(value) {\n *   if (value) {\n *     return value.toLowerCase();\n *   }\n * }\n * ngModelController.$parsers.push(parse);\n * ```\n\n *\n * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever\n    the bound ngModel expression changes programmatically. The `$formatters` are not called when the\n    value of the control is changed by user interaction.\n\n  Formatters are used to format / convert the {@link ngModel.NgModelController#$modelValue\n    `$modelValue`} for display in the control.\n\n  The functions are called in reverse array order, each passing the value through to the\n    next. The last return value is used as the actual DOM value.\n\n  This simple example shows a formatter that would convert the model value to uppercase:\n\n * ```js\n * function format(value) {\n *   if (value) {\n *     return value.toUpperCase();\n *   }\n * }\n * ngModel.$formatters.push(format);\n * ```\n *\n * @property {Object.<string, function>} $validators A collection of validators that are applied\n *      whenever the model value changes. The key value within the object refers to the name of the\n *      validator while the function refers to the validation operation. The validation operation is\n *      provided with the model value as an argument and must return a true or false value depending\n *      on the response of that validation.\n *\n * ```js\n * ngModel.$validators.validCharacters = function(modelValue, viewValue) {\n *   var value = modelValue || viewValue;\n *   return /[0-9]+/.test(value) &&\n *          /[a-z]+/.test(value) &&\n *          /[A-Z]+/.test(value) &&\n *          /\\W+/.test(value);\n * };\n * ```\n *\n * @property {Object.<string, function>} $asyncValidators A collection of validations that are expected to\n *      perform an asynchronous validation (e.g. a HTTP request). The validation function that is provided\n *      is expected to return a promise when it is run during the model validation process. Once the promise\n *      is delivered then the validation status will be set to true when fulfilled and false when rejected.\n *      When the asynchronous validators are triggered, each of the validators will run in parallel and the model\n *      value will only be updated once all validators have been fulfilled. As long as an asynchronous validator\n *      is unfulfilled, its key will be added to the controllers `$pending` property. Also, all asynchronous validators\n *      will only run once all synchronous validators have passed.\n *\n * Please note that if $http is used then it is important that the server returns a success HTTP response code\n * in order to fulfill the validation and a status level of `4xx` in order to reject the validation.\n *\n * ```js\n * ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {\n *   var value = modelValue || viewValue;\n *\n *   // Lookup user by username\n *   return $http.get('/api/users/' + value).\n *      then(function resolved() {\n *        //username exists, this means validation fails\n *        return $q.reject('exists');\n *      }, function rejected() {\n *        //username does not exist, therefore this validation passes\n *        return true;\n *      });\n * };\n * ```\n *\n * @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever the\n *     view value has changed. It is called with no arguments, and its return value is ignored.\n *     This can be used in place of additional $watches against the model value.\n *\n * @property {Object} $error An object hash with all failing validator ids as keys.\n * @property {Object} $pending An object hash with all pending validator ids as keys.\n *\n * @property {boolean} $untouched True if control has not lost focus yet.\n * @property {boolean} $touched True if control has lost focus.\n * @property {boolean} $pristine True if user has not interacted with the control yet.\n * @property {boolean} $dirty True if user has already interacted with the control.\n * @property {boolean} $valid True if there is no error.\n * @property {boolean} $invalid True if at least one error on the control.\n * @property {string} $name The name attribute of the control.\n *\n * @description\n *\n * `NgModelController` provides API for the {@link ngModel `ngModel`} directive.\n * The controller contains services for data-binding, validation, CSS updates, and value formatting\n * and parsing. It purposefully does not contain any logic which deals with DOM rendering or\n * listening to DOM events.\n * Such DOM related logic should be provided by other directives which make use of\n * `NgModelController` for data-binding to control elements.\n * Angular provides this DOM logic for most {@link input `input`} elements.\n * At the end of this page you can find a {@link ngModel.NgModelController#custom-control-example\n * custom control example} that uses `ngModelController` to bind to `contenteditable` elements.\n *\n * @example\n * ### Custom Control Example\n * This example shows how to use `NgModelController` with a custom control to achieve\n * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)\n * collaborate together to achieve the desired result.\n *\n * `contenteditable` is an HTML5 attribute, which tells the browser to let the element\n * contents be edited in place by the user.\n *\n * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize}\n * module to automatically remove \"bad\" content like inline event listener (e.g. `<span onclick=\"...\">`).\n * However, as we are using `$sce` the model can still decide to provide unsafe content if it marks\n * that content using the `$sce` service.\n *\n * <example name=\"NgModelController\" module=\"customControl\" deps=\"angular-sanitize.js\">\n    <file name=\"style.css\">\n      [contenteditable] {\n        border: 1px solid black;\n        background-color: white;\n        min-height: 20px;\n      }\n\n      .ng-invalid {\n        border: 1px solid red;\n      }\n\n    </file>\n    <file name=\"script.js\">\n      angular.module('customControl', ['ngSanitize']).\n        directive('contenteditable', ['$sce', function($sce) {\n          return {\n            restrict: 'A', // only activate on element attribute\n            require: '?ngModel', // get a hold of NgModelController\n            link: function(scope, element, attrs, ngModel) {\n              if (!ngModel) return; // do nothing if no ng-model\n\n              // Specify how UI should be updated\n              ngModel.$render = function() {\n                element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));\n              };\n\n              // Listen for change events to enable binding\n              element.on('blur keyup change', function() {\n                scope.$evalAsync(read);\n              });\n              read(); // initialize\n\n              // Write data to the model\n              function read() {\n                var html = element.html();\n                // When we clear the content editable the browser leaves a <br> behind\n                // If strip-br attribute is provided then we strip this out\n                if (attrs.stripBr && html === '<br>') {\n                  html = '';\n                }\n                ngModel.$setViewValue(html);\n              }\n            }\n          };\n        }]);\n    </file>\n    <file name=\"index.html\">\n      <form name=\"myForm\">\n       <div contenteditable\n            name=\"myWidget\" ng-model=\"userContent\"\n            strip-br=\"true\"\n            required>Change me!</div>\n        <span ng-show=\"myForm.myWidget.$error.required\">Required!</span>\n       <hr>\n       <textarea ng-model=\"userContent\" aria-label=\"Dynamic textarea\"></textarea>\n      </form>\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n    it('should data-bind and become invalid', function() {\n      if (browser.params.browser === 'safari' || browser.params.browser === 'firefox') {\n        // SafariDriver can't handle contenteditable\n        // and Firefox driver can't clear contenteditables very well\n        return;\n      }\n      var contentEditable = element(by.css('[contenteditable]'));\n      var content = 'Change me!';\n\n      expect(contentEditable.getText()).toEqual(content);\n\n      contentEditable.clear();\n      contentEditable.sendKeys(protractor.Key.BACK_SPACE);\n      expect(contentEditable.getText()).toEqual('');\n      expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/);\n    });\n    </file>\n * </example>\n *\n *\n */\nNgModelController.$inject = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$q', '$interpolate'];\nfunction NgModelController($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $q, $interpolate) {\n  this.$viewValue = Number.NaN;\n  this.$modelValue = Number.NaN;\n  this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.\n  this.$validators = {};\n  this.$asyncValidators = {};\n  this.$parsers = [];\n  this.$formatters = [];\n  this.$viewChangeListeners = [];\n  this.$untouched = true;\n  this.$touched = false;\n  this.$pristine = true;\n  this.$dirty = false;\n  this.$valid = true;\n  this.$invalid = false;\n  this.$error = {}; // keep invalid keys here\n  this.$$success = {}; // keep valid keys here\n  this.$pending = undefined; // keep pending keys here\n  this.$name = $interpolate($attr.name || '', false)($scope);\n  this.$$parentForm = nullFormCtrl;\n  this.$options = defaultModelOptions;\n\n  this.$$parsedNgModel = $parse($attr.ngModel);\n  this.$$parsedNgModelAssign = this.$$parsedNgModel.assign;\n  this.$$ngModelGet = this.$$parsedNgModel;\n  this.$$ngModelSet = this.$$parsedNgModelAssign;\n  this.$$pendingDebounce = null;\n  this.$$parserValid = undefined;\n\n  this.$$currentValidationRunId = 0;\n\n  this.$$scope = $scope;\n  this.$$attr = $attr;\n  this.$$element = $element;\n  this.$$animate = $animate;\n  this.$$timeout = $timeout;\n  this.$$parse = $parse;\n  this.$$q = $q;\n  this.$$exceptionHandler = $exceptionHandler;\n\n  setupValidity(this);\n  setupModelWatcher(this);\n}\n\nNgModelController.prototype = {\n  $$initGetterSetters: function() {\n    if (this.$options.getOption('getterSetter')) {\n      var invokeModelGetter = this.$$parse(this.$$attr.ngModel + '()'),\n          invokeModelSetter = this.$$parse(this.$$attr.ngModel + '($$$p)');\n\n      this.$$ngModelGet = function($scope) {\n        var modelValue = this.$$parsedNgModel($scope);\n        if (isFunction(modelValue)) {\n          modelValue = invokeModelGetter($scope);\n        }\n        return modelValue;\n      };\n      this.$$ngModelSet = function($scope, newValue) {\n        if (isFunction(this.$$parsedNgModel($scope))) {\n          invokeModelSetter($scope, {$$$p: newValue});\n        } else {\n          this.$$parsedNgModelAssign($scope, newValue);\n        }\n      };\n    } else if (!this.$$parsedNgModel.assign) {\n      throw ngModelMinErr('nonassign', 'Expression \\'{0}\\' is non-assignable. Element: {1}',\n          this.$$attr.ngModel, startingTag(this.$$element));\n    }\n  },\n\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$render\n   *\n   * @description\n   * Called when the view needs to be updated. It is expected that the user of the ng-model\n   * directive will implement this method.\n   *\n   * The `$render()` method is invoked in the following situations:\n   *\n   * * `$rollbackViewValue()` is called.  If we are rolling back the view value to the last\n   *   committed value then `$render()` is called to update the input control.\n   * * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and\n   *   the `$viewValue` are different from last time.\n   *\n   * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of\n   * `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue`\n   * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be\n   * invoked if you only change a property on the objects.\n   */\n  $render: noop,\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$isEmpty\n   *\n   * @description\n   * This is called when we need to determine if the value of an input is empty.\n   *\n   * For instance, the required directive does this to work out if the input has data or not.\n   *\n   * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`.\n   *\n   * You can override this for input directives whose concept of being empty is different from the\n   * default. The `checkboxInputType` directive does this because in its case a value of `false`\n   * implies empty.\n   *\n   * @param {*} value The value of the input to check for emptiness.\n   * @returns {boolean} True if `value` is \"empty\".\n   */\n  $isEmpty: function(value) {\n    // eslint-disable-next-line no-self-compare\n    return isUndefined(value) || value === '' || value === null || value !== value;\n  },\n\n  $$updateEmptyClasses: function(value) {\n    if (this.$isEmpty(value)) {\n      this.$$animate.removeClass(this.$$element, NOT_EMPTY_CLASS);\n      this.$$animate.addClass(this.$$element, EMPTY_CLASS);\n    } else {\n      this.$$animate.removeClass(this.$$element, EMPTY_CLASS);\n      this.$$animate.addClass(this.$$element, NOT_EMPTY_CLASS);\n    }\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setPristine\n   *\n   * @description\n   * Sets the control to its pristine state.\n   *\n   * This method can be called to remove the `ng-dirty` class and set the control to its pristine\n   * state (`ng-pristine` class). A model is considered to be pristine when the control\n   * has not been changed from when first compiled.\n   */\n  $setPristine: function() {\n    this.$dirty = false;\n    this.$pristine = true;\n    this.$$animate.removeClass(this.$$element, DIRTY_CLASS);\n    this.$$animate.addClass(this.$$element, PRISTINE_CLASS);\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setDirty\n   *\n   * @description\n   * Sets the control to its dirty state.\n   *\n   * This method can be called to remove the `ng-pristine` class and set the control to its dirty\n   * state (`ng-dirty` class). A model is considered to be dirty when the control has been changed\n   * from when first compiled.\n   */\n  $setDirty: function() {\n    this.$dirty = true;\n    this.$pristine = false;\n    this.$$animate.removeClass(this.$$element, PRISTINE_CLASS);\n    this.$$animate.addClass(this.$$element, DIRTY_CLASS);\n    this.$$parentForm.$setDirty();\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setUntouched\n   *\n   * @description\n   * Sets the control to its untouched state.\n   *\n   * This method can be called to remove the `ng-touched` class and set the control to its\n   * untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched\n   * by default, however this function can be used to restore that state if the model has\n   * already been touched by the user.\n   */\n  $setUntouched: function() {\n    this.$touched = false;\n    this.$untouched = true;\n    this.$$animate.setClass(this.$$element, UNTOUCHED_CLASS, TOUCHED_CLASS);\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setTouched\n   *\n   * @description\n   * Sets the control to its touched state.\n   *\n   * This method can be called to remove the `ng-untouched` class and set the control to its\n   * touched state (`ng-touched` class). A model is considered to be touched when the user has\n   * first focused the control element and then shifted focus away from the control (blur event).\n   */\n  $setTouched: function() {\n    this.$touched = true;\n    this.$untouched = false;\n    this.$$animate.setClass(this.$$element, TOUCHED_CLASS, UNTOUCHED_CLASS);\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$rollbackViewValue\n   *\n   * @description\n   * Cancel an update and reset the input element's value to prevent an update to the `$modelValue`,\n   * which may be caused by a pending debounced event or because the input is waiting for some\n   * future event.\n   *\n   * If you have an input that uses `ng-model-options` to set up debounced updates or updates that\n   * depend on special events such as `blur`, there can be a period when the `$viewValue` is out of\n   * sync with the ngModel's `$modelValue`.\n   *\n   * In this case, you can use `$rollbackViewValue()` to manually cancel the debounced / future update\n   * and reset the input to the last committed view value.\n   *\n   * It is also possible that you run into difficulties if you try to update the ngModel's `$modelValue`\n   * programmatically before these debounced/future events have resolved/occurred, because Angular's\n   * dirty checking mechanism is not able to tell whether the model has actually changed or not.\n   *\n   * The `$rollbackViewValue()` method should be called before programmatically changing the model of an\n   * input which may have such events pending. This is important in order to make sure that the\n   * input field will be updated with the new model value and any pending operations are cancelled.\n   *\n   * <example name=\"ng-model-cancel-update\" module=\"cancel-update-example\">\n   *   <file name=\"app.js\">\n   *     angular.module('cancel-update-example', [])\n   *\n   *     .controller('CancelUpdateController', ['$scope', function($scope) {\n   *       $scope.model = {value1: '', value2: ''};\n   *\n   *       $scope.setEmpty = function(e, value, rollback) {\n   *         if (e.keyCode === 27) {\n   *           e.preventDefault();\n   *           if (rollback) {\n   *             $scope.myForm[value].$rollbackViewValue();\n   *           }\n   *           $scope.model[value] = '';\n   *         }\n   *       };\n   *     }]);\n   *   </file>\n   *   <file name=\"index.html\">\n   *     <div ng-controller=\"CancelUpdateController\">\n   *       <p>Both of these inputs are only updated if they are blurred. Hitting escape should\n   *       empty them. Follow these steps and observe the difference:</p>\n   *       <ol>\n   *         <li>Type something in the input. You will see that the model is not yet updated</li>\n   *         <li>Press the Escape key.\n   *           <ol>\n   *             <li> In the first example, nothing happens, because the model is already '', and no\n   *             update is detected. If you blur the input, the model will be set to the current view.\n   *             </li>\n   *             <li> In the second example, the pending update is cancelled, and the input is set back\n   *             to the last committed view value (''). Blurring the input does nothing.\n   *             </li>\n   *           </ol>\n   *         </li>\n   *       </ol>\n   *\n   *       <form name=\"myForm\" ng-model-options=\"{ updateOn: 'blur' }\">\n   *         <div>\n   *           <p id=\"inputDescription1\">Without $rollbackViewValue():</p>\n   *           <input name=\"value1\" aria-describedby=\"inputDescription1\" ng-model=\"model.value1\"\n   *                  ng-keydown=\"setEmpty($event, 'value1')\">\n   *           value1: \"{{ model.value1 }}\"\n   *         </div>\n   *\n   *         <div>\n   *           <p id=\"inputDescription2\">With $rollbackViewValue():</p>\n   *           <input name=\"value2\" aria-describedby=\"inputDescription2\" ng-model=\"model.value2\"\n   *                  ng-keydown=\"setEmpty($event, 'value2', true)\">\n   *           value2: \"{{ model.value2 }}\"\n   *         </div>\n   *       </form>\n   *     </div>\n   *   </file>\n       <file name=\"style.css\">\n          div {\n            display: table-cell;\n          }\n          div:nth-child(1) {\n            padding-right: 30px;\n          }\n\n        </file>\n   * </example>\n   */\n  $rollbackViewValue: function() {\n    this.$$timeout.cancel(this.$$pendingDebounce);\n    this.$viewValue = this.$$lastCommittedViewValue;\n    this.$render();\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$validate\n   *\n   * @description\n   * Runs each of the registered validators (first synchronous validators and then\n   * asynchronous validators).\n   * If the validity changes to invalid, the model will be set to `undefined`,\n   * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`.\n   * If the validity changes to valid, it will set the model to the last available valid\n   * `$modelValue`, i.e. either the last parsed value or the last value set from the scope.\n   */\n  $validate: function() {\n    // ignore $validate before model is initialized\n    if (isNumberNaN(this.$modelValue)) {\n      return;\n    }\n\n    var viewValue = this.$$lastCommittedViewValue;\n    // Note: we use the $$rawModelValue as $modelValue might have been\n    // set to undefined during a view -> model update that found validation\n    // errors. We can't parse the view here, since that could change\n    // the model although neither viewValue nor the model on the scope changed\n    var modelValue = this.$$rawModelValue;\n\n    var prevValid = this.$valid;\n    var prevModelValue = this.$modelValue;\n\n    var allowInvalid = this.$options.getOption('allowInvalid');\n\n    var that = this;\n    this.$$runValidators(modelValue, viewValue, function(allValid) {\n      // If there was no change in validity, don't update the model\n      // This prevents changing an invalid modelValue to undefined\n      if (!allowInvalid && prevValid !== allValid) {\n        // Note: Don't check this.$valid here, as we could have\n        // external validators (e.g. calculated on the server),\n        // that just call $setValidity and need the model value\n        // to calculate their validity.\n        that.$modelValue = allValid ? modelValue : undefined;\n\n        if (that.$modelValue !== prevModelValue) {\n          that.$$writeModelToScope();\n        }\n      }\n    });\n  },\n\n  $$runValidators: function(modelValue, viewValue, doneCallback) {\n    this.$$currentValidationRunId++;\n    var localValidationRunId = this.$$currentValidationRunId;\n    var that = this;\n\n    // check parser error\n    if (!processParseErrors()) {\n      validationDone(false);\n      return;\n    }\n    if (!processSyncValidators()) {\n      validationDone(false);\n      return;\n    }\n    processAsyncValidators();\n\n    function processParseErrors() {\n      var errorKey = that.$$parserName || 'parse';\n      if (isUndefined(that.$$parserValid)) {\n        setValidity(errorKey, null);\n      } else {\n        if (!that.$$parserValid) {\n          forEach(that.$validators, function(v, name) {\n            setValidity(name, null);\n          });\n          forEach(that.$asyncValidators, function(v, name) {\n            setValidity(name, null);\n          });\n        }\n        // Set the parse error last, to prevent unsetting it, should a $validators key == parserName\n        setValidity(errorKey, that.$$parserValid);\n        return that.$$parserValid;\n      }\n      return true;\n    }\n\n    function processSyncValidators() {\n      var syncValidatorsValid = true;\n      forEach(that.$validators, function(validator, name) {\n        var result = Boolean(validator(modelValue, viewValue));\n        syncValidatorsValid = syncValidatorsValid && result;\n        setValidity(name, result);\n      });\n      if (!syncValidatorsValid) {\n        forEach(that.$asyncValidators, function(v, name) {\n          setValidity(name, null);\n        });\n        return false;\n      }\n      return true;\n    }\n\n    function processAsyncValidators() {\n      var validatorPromises = [];\n      var allValid = true;\n      forEach(that.$asyncValidators, function(validator, name) {\n        var promise = validator(modelValue, viewValue);\n        if (!isPromiseLike(promise)) {\n          throw ngModelMinErr('nopromise',\n            'Expected asynchronous validator to return a promise but got \\'{0}\\' instead.', promise);\n        }\n        setValidity(name, undefined);\n        validatorPromises.push(promise.then(function() {\n          setValidity(name, true);\n        }, function() {\n          allValid = false;\n          setValidity(name, false);\n        }));\n      });\n      if (!validatorPromises.length) {\n        validationDone(true);\n      } else {\n        that.$$q.all(validatorPromises).then(function() {\n          validationDone(allValid);\n        }, noop);\n      }\n    }\n\n    function setValidity(name, isValid) {\n      if (localValidationRunId === that.$$currentValidationRunId) {\n        that.$setValidity(name, isValid);\n      }\n    }\n\n    function validationDone(allValid) {\n      if (localValidationRunId === that.$$currentValidationRunId) {\n\n        doneCallback(allValid);\n      }\n    }\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$commitViewValue\n   *\n   * @description\n   * Commit a pending update to the `$modelValue`.\n   *\n   * Updates may be pending by a debounced event or because the input is waiting for a some future\n   * event defined in `ng-model-options`. this method is rarely needed as `NgModelController`\n   * usually handles calling this in response to input events.\n   */\n  $commitViewValue: function() {\n    var viewValue = this.$viewValue;\n\n    this.$$timeout.cancel(this.$$pendingDebounce);\n\n    // If the view value has not changed then we should just exit, except in the case where there is\n    // a native validator on the element. In this case the validation state may have changed even though\n    // the viewValue has stayed empty.\n    if (this.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !this.$$hasNativeValidators)) {\n      return;\n    }\n    this.$$updateEmptyClasses(viewValue);\n    this.$$lastCommittedViewValue = viewValue;\n\n    // change to dirty\n    if (this.$pristine) {\n      this.$setDirty();\n    }\n    this.$$parseAndValidate();\n  },\n\n  $$parseAndValidate: function() {\n    var viewValue = this.$$lastCommittedViewValue;\n    var modelValue = viewValue;\n    var that = this;\n\n    this.$$parserValid = isUndefined(modelValue) ? undefined : true;\n\n    if (this.$$parserValid) {\n      for (var i = 0; i < this.$parsers.length; i++) {\n        modelValue = this.$parsers[i](modelValue);\n        if (isUndefined(modelValue)) {\n          this.$$parserValid = false;\n          break;\n        }\n      }\n    }\n    if (isNumberNaN(this.$modelValue)) {\n      // this.$modelValue has not been touched yet...\n      this.$modelValue = this.$$ngModelGet(this.$$scope);\n    }\n    var prevModelValue = this.$modelValue;\n    var allowInvalid = this.$options.getOption('allowInvalid');\n    this.$$rawModelValue = modelValue;\n\n    if (allowInvalid) {\n      this.$modelValue = modelValue;\n      writeToModelIfNeeded();\n    }\n\n    // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.\n    // This can happen if e.g. $setViewValue is called from inside a parser\n    this.$$runValidators(modelValue, this.$$lastCommittedViewValue, function(allValid) {\n      if (!allowInvalid) {\n        // Note: Don't check this.$valid here, as we could have\n        // external validators (e.g. calculated on the server),\n        // that just call $setValidity and need the model value\n        // to calculate their validity.\n        that.$modelValue = allValid ? modelValue : undefined;\n        writeToModelIfNeeded();\n      }\n    });\n\n    function writeToModelIfNeeded() {\n      if (that.$modelValue !== prevModelValue) {\n        that.$$writeModelToScope();\n      }\n    }\n  },\n\n  $$writeModelToScope: function() {\n    this.$$ngModelSet(this.$$scope, this.$modelValue);\n    forEach(this.$viewChangeListeners, function(listener) {\n      try {\n        listener();\n      } catch (e) {\n        // eslint-disable-next-line no-invalid-this\n        this.$$exceptionHandler(e);\n      }\n    }, this);\n  },\n\n  /**\n   * @ngdoc method\n   * @name ngModel.NgModelController#$setViewValue\n   *\n   * @description\n   * Update the view value.\n   *\n   * This method should be called when a control wants to change the view value; typically,\n   * this is done from within a DOM event handler. For example, the {@link ng.directive:input input}\n   * directive calls it when the value of the input changes and {@link ng.directive:select select}\n   * calls it when an option is selected.\n   *\n   * When `$setViewValue` is called, the new `value` will be staged for committing through the `$parsers`\n   * and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged\n   * value is sent directly for processing through the `$parsers` pipeline. After this, the `$validators` and\n   * `$asyncValidators` are called and the value is applied to `$modelValue`.\n   * Finally, the value is set to the **expression** specified in the `ng-model` attribute and\n   * all the registered change listeners, in the `$viewChangeListeners` list are called.\n   *\n   * In case the {@link ng.directive:ngModelOptions ngModelOptions} directive is used with `updateOn`\n   * and the `default` trigger is not listed, all those actions will remain pending until one of the\n   * `updateOn` events is triggered on the DOM element.\n   * All these actions will be debounced if the {@link ng.directive:ngModelOptions ngModelOptions}\n   * directive is used with a custom debounce for this particular event.\n   * Note that a `$digest` is only triggered once the `updateOn` events are fired, or if `debounce`\n   * is specified, once the timer runs out.\n   *\n   * When used with standard inputs, the view value will always be a string (which is in some cases\n   * parsed into another type, such as a `Date` object for `input[date]`.)\n   * However, custom controls might also pass objects to this method. In this case, we should make\n   * a copy of the object before passing it to `$setViewValue`. This is because `ngModel` does not\n   * perform a deep watch of objects, it only looks for a change of identity. If you only change\n   * the property of the object then ngModel will not realize that the object has changed and\n   * will not invoke the `$parsers` and `$validators` pipelines. For this reason, you should\n   * not change properties of the copy once it has been passed to `$setViewValue`.\n   * Otherwise you may cause the model value on the scope to change incorrectly.\n   *\n   * <div class=\"alert alert-info\">\n   * In any case, the value passed to the method should always reflect the current value\n   * of the control. For example, if you are calling `$setViewValue` for an input element,\n   * you should pass the input DOM value. Otherwise, the control and the scope model become\n   * out of sync. It's also important to note that `$setViewValue` does not call `$render` or change\n   * the control's DOM value in any way. If we want to change the control's DOM value\n   * programmatically, we should update the `ngModel` scope expression. Its new value will be\n   * picked up by the model controller, which will run it through the `$formatters`, `$render` it\n   * to update the DOM, and finally call `$validate` on it.\n   * </div>\n   *\n   * @param {*} value value from the view.\n   * @param {string} trigger Event that triggered the update.\n   */\n  $setViewValue: function(value, trigger) {\n    this.$viewValue = value;\n    if (this.$options.getOption('updateOnDefault')) {\n      this.$$debounceViewValueCommit(trigger);\n    }\n  },\n\n  $$debounceViewValueCommit: function(trigger) {\n    var debounceDelay = this.$options.getOption('debounce');\n\n    if (isNumber(debounceDelay[trigger])) {\n      debounceDelay = debounceDelay[trigger];\n    } else if (isNumber(debounceDelay['default'])) {\n      debounceDelay = debounceDelay['default'];\n    }\n\n    this.$$timeout.cancel(this.$$pendingDebounce);\n    var that = this;\n    if (debounceDelay > 0) { // this fails if debounceDelay is an object\n      this.$$pendingDebounce = this.$$timeout(function() {\n        that.$commitViewValue();\n      }, debounceDelay);\n    } else if (this.$$scope.$root.$$phase) {\n      this.$commitViewValue();\n    } else {\n      this.$$scope.$apply(function() {\n        that.$commitViewValue();\n      });\n    }\n  },\n\n  /**\n   * @ngdoc method\n   *\n   * @name ngModel.NgModelController#$overrideModelOptions\n   *\n   * @description\n   *\n   * Override the current model options settings programmatically.\n   *\n   * The previous `ModelOptions` value will not be modified. Instead, a\n   * new `ModelOptions` object will inherit from the previous one overriding\n   * or inheriting settings that are defined in the given parameter.\n   *\n   * See {@link ngModelOptions} for information about what options can be specified\n   * and how model option inheritance works.\n   *\n   * @param {Object} options a hash of settings to override the previous options\n   *\n   */\n  $overrideModelOptions: function(options) {\n    this.$options = this.$options.createChild(options);\n  }\n};\n\nfunction setupModelWatcher(ctrl) {\n  // model -> value\n  // Note: we cannot use a normal scope.$watch as we want to detect the following:\n  // 1. scope value is 'a'\n  // 2. user enters 'b'\n  // 3. ng-change kicks in and reverts scope value to 'a'\n  //    -> scope value did not change since the last digest as\n  //       ng-change executes in apply phase\n  // 4. view should be changed back to 'a'\n  ctrl.$$scope.$watch(function ngModelWatch() {\n    var modelValue = ctrl.$$ngModelGet(ctrl.$$scope);\n\n    // if scope model value and ngModel value are out of sync\n    // TODO(perf): why not move this to the action fn?\n    if (modelValue !== ctrl.$modelValue &&\n       // checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator\n        // eslint-disable-next-line no-self-compare\n       (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue)\n    ) {\n      ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;\n      ctrl.$$parserValid = undefined;\n\n      var formatters = ctrl.$formatters,\n          idx = formatters.length;\n\n      var viewValue = modelValue;\n      while (idx--) {\n        viewValue = formatters[idx](viewValue);\n      }\n      if (ctrl.$viewValue !== viewValue) {\n        ctrl.$$updateEmptyClasses(viewValue);\n        ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;\n        ctrl.$render();\n\n        // It is possible that model and view value have been updated during render\n        ctrl.$$runValidators(ctrl.$modelValue, ctrl.$viewValue, noop);\n      }\n    }\n\n    return modelValue;\n  });\n}\n\n/**\n * @ngdoc method\n * @name ngModel.NgModelController#$setValidity\n *\n * @description\n * Change the validity state, and notify the form.\n *\n * This method can be called within $parsers/$formatters or a custom validation implementation.\n * However, in most cases it should be sufficient to use the `ngModel.$validators` and\n * `ngModel.$asyncValidators` collections which will call `$setValidity` automatically.\n *\n * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be assigned\n *        to either `$error[validationErrorKey]` or `$pending[validationErrorKey]`\n *        (for unfulfilled `$asyncValidators`), so that it is available for data-binding.\n *        The `validationErrorKey` should be in camelCase and will get converted into dash-case\n *        for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error`\n *        class and can be bound to as  `{{someForm.someControl.$error.myError}}` .\n * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending (undefined),\n *                          or skipped (null). Pending is used for unfulfilled `$asyncValidators`.\n *                          Skipped is used by Angular when validators do not run because of parse errors and\n *                          when `$asyncValidators` do not run because any of the `$validators` failed.\n */\naddSetValidityMethod({\n  clazz: NgModelController,\n  set: function(object, property) {\n    object[property] = true;\n  },\n  unset: function(object, property) {\n    delete object[property];\n  }\n});\n\n\n/**\n * @ngdoc directive\n * @name ngModel\n *\n * @element input\n * @priority 1\n *\n * @description\n * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a\n * property on the scope using {@link ngModel.NgModelController NgModelController},\n * which is created and exposed by this directive.\n *\n * `ngModel` is responsible for:\n *\n * - Binding the view into the model, which other directives such as `input`, `textarea` or `select`\n *   require.\n * - Providing validation behavior (i.e. required, number, email, url).\n * - Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors).\n * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`, `ng-touched`,\n *   `ng-untouched`, `ng-empty`, `ng-not-empty`) including animations.\n * - Registering the control with its parent {@link ng.directive:form form}.\n *\n * Note: `ngModel` will try to bind to the property given by evaluating the expression on the\n * current scope. If the property doesn't already exist on this scope, it will be created\n * implicitly and added to the scope.\n *\n * For best practices on using `ngModel`, see:\n *\n *  - [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes)\n *\n * For basic examples, how to use `ngModel`, see:\n *\n *  - {@link ng.directive:input input}\n *    - {@link input[text] text}\n *    - {@link input[checkbox] checkbox}\n *    - {@link input[radio] radio}\n *    - {@link input[number] number}\n *    - {@link input[email] email}\n *    - {@link input[url] url}\n *    - {@link input[date] date}\n *    - {@link input[datetime-local] datetime-local}\n *    - {@link input[time] time}\n *    - {@link input[month] month}\n *    - {@link input[week] week}\n *  - {@link ng.directive:select select}\n *  - {@link ng.directive:textarea textarea}\n *\n * # Complex Models (objects or collections)\n *\n * By default, `ngModel` watches the model by reference, not value. This is important to know when\n * binding inputs to models that are objects (e.g. `Date`) or collections (e.g. arrays). If only properties of the\n * object or collection change, `ngModel` will not be notified and so the input will not be  re-rendered.\n *\n * The model must be assigned an entirely new object or collection before a re-rendering will occur.\n *\n * Some directives have options that will cause them to use a custom `$watchCollection` on the model expression\n * - for example, `ngOptions` will do so when a `track by` clause is included in the comprehension expression or\n * if the select is given the `multiple` attribute.\n *\n * The `$watchCollection()` method only does a shallow comparison, meaning that changing properties deeper than the\n * first level of the object (or only changing the properties of an item in the collection if it's an array) will still\n * not trigger a re-rendering of the model.\n *\n * # CSS classes\n * The following CSS classes are added and removed on the associated input/select/textarea element\n * depending on the validity of the model.\n *\n *  - `ng-valid`: the model is valid\n *  - `ng-invalid`: the model is invalid\n *  - `ng-valid-[key]`: for each valid key added by `$setValidity`\n *  - `ng-invalid-[key]`: for each invalid key added by `$setValidity`\n *  - `ng-pristine`: the control hasn't been interacted with yet\n *  - `ng-dirty`: the control has been interacted with\n *  - `ng-touched`: the control has been blurred\n *  - `ng-untouched`: the control hasn't been blurred\n *  - `ng-pending`: any `$asyncValidators` are unfulfilled\n *  - `ng-empty`: the view does not contain a value or the value is deemed \"empty\", as defined\n *     by the {@link ngModel.NgModelController#$isEmpty} method\n *  - `ng-not-empty`: the view contains a non-empty value\n *\n * Keep in mind that ngAnimate can detect each of these classes when added and removed.\n *\n * ## Animation Hooks\n *\n * Animations within models are triggered when any of the associated CSS classes are added and removed\n * on the input element which is attached to the model. These classes include: `.ng-pristine`, `.ng-dirty`,\n * `.ng-invalid` and `.ng-valid` as well as any other validations that are performed on the model itself.\n * The animations that are triggered within ngModel are similar to how they work in ngClass and\n * animations can be hooked into using CSS transitions, keyframes as well as JS animations.\n *\n * The following example shows a simple way to utilize CSS transitions to style an input element\n * that has been rendered as invalid after it has been validated:\n *\n * <pre>\n * //be sure to include ngAnimate as a module to hook into more\n * //advanced animations\n * .my-input {\n *   transition:0.5s linear all;\n *   background: white;\n * }\n * .my-input.ng-invalid {\n *   background: red;\n *   color:white;\n * }\n * </pre>\n *\n * @example\n * <example deps=\"angular-animate.js\" animations=\"true\" fixBase=\"true\" module=\"inputExample\" name=\"ng-model\">\n     <file name=\"index.html\">\n       <script>\n        angular.module('inputExample', [])\n          .controller('ExampleController', ['$scope', function($scope) {\n            $scope.val = '1';\n          }]);\n       </script>\n       <style>\n         .my-input {\n           transition:all linear 0.5s;\n           background: transparent;\n         }\n         .my-input.ng-invalid {\n           color:white;\n           background: red;\n         }\n       </style>\n       <p id=\"inputDescription\">\n        Update input to see transitions when valid/invalid.\n        Integer is a valid value.\n       </p>\n       <form name=\"testForm\" ng-controller=\"ExampleController\">\n         <input ng-model=\"val\" ng-pattern=\"/^\\d+$/\" name=\"anim\" class=\"my-input\"\n                aria-describedby=\"inputDescription\" />\n       </form>\n     </file>\n * </example>\n *\n * ## Binding to a getter/setter\n *\n * Sometimes it's helpful to bind `ngModel` to a getter/setter function.  A getter/setter is a\n * function that returns a representation of the model when called with zero arguments, and sets\n * the internal state of a model when called with an argument. It's sometimes useful to use this\n * for models that have an internal representation that's different from what the model exposes\n * to the view.\n *\n * <div class=\"alert alert-success\">\n * **Best Practice:** It's best to keep getters fast because Angular is likely to call them more\n * frequently than other parts of your code.\n * </div>\n *\n * You use this behavior by adding `ng-model-options=\"{ getterSetter: true }\"` to an element that\n * has `ng-model` attached to it. You can also add `ng-model-options=\"{ getterSetter: true }\"` to\n * a `<form>`, which will enable this behavior for all `<input>`s within it. See\n * {@link ng.directive:ngModelOptions `ngModelOptions`} for more.\n *\n * The following example shows how to use `ngModel` with a getter/setter:\n *\n * @example\n * <example name=\"ngModel-getter-setter\" module=\"getterSetterExample\">\n     <file name=\"index.html\">\n       <div ng-controller=\"ExampleController\">\n         <form name=\"userForm\">\n           <label>Name:\n             <input type=\"text\" name=\"userName\"\n                    ng-model=\"user.name\"\n                    ng-model-options=\"{ getterSetter: true }\" />\n           </label>\n         </form>\n         <pre>user.name = <span ng-bind=\"user.name()\"></span></pre>\n       </div>\n     </file>\n     <file name=\"app.js\">\n       angular.module('getterSetterExample', [])\n         .controller('ExampleController', ['$scope', function($scope) {\n           var _name = 'Brian';\n           $scope.user = {\n             name: function(newName) {\n              // Note that newName can be undefined for two reasons:\n              // 1. Because it is called as a getter and thus called with no arguments\n              // 2. Because the property should actually be set to undefined. This happens e.g. if the\n              //    input is invalid\n              return arguments.length ? (_name = newName) : _name;\n             }\n           };\n         }]);\n     </file>\n * </example>\n */\nvar ngModelDirective = ['$rootScope', function($rootScope) {\n  return {\n    restrict: 'A',\n    require: ['ngModel', '^?form', '^?ngModelOptions'],\n    controller: NgModelController,\n    // Prelink needs to run before any input directive\n    // so that we can set the NgModelOptions in NgModelController\n    // before anyone else uses it.\n    priority: 1,\n    compile: function ngModelCompile(element) {\n      // Setup initial state of the control\n      element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS);\n\n      return {\n        pre: function ngModelPreLink(scope, element, attr, ctrls) {\n          var modelCtrl = ctrls[0],\n              formCtrl = ctrls[1] || modelCtrl.$$parentForm,\n              optionsCtrl = ctrls[2];\n\n          if (optionsCtrl) {\n            modelCtrl.$options = optionsCtrl.$options;\n          }\n\n          modelCtrl.$$initGetterSetters();\n\n          // notify others, especially parent forms\n          formCtrl.$addControl(modelCtrl);\n\n          attr.$observe('name', function(newValue) {\n            if (modelCtrl.$name !== newValue) {\n              modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue);\n            }\n          });\n\n          scope.$on('$destroy', function() {\n            modelCtrl.$$parentForm.$removeControl(modelCtrl);\n          });\n        },\n        post: function ngModelPostLink(scope, element, attr, ctrls) {\n          var modelCtrl = ctrls[0];\n          if (modelCtrl.$options.getOption('updateOn')) {\n            element.on(modelCtrl.$options.getOption('updateOn'), function(ev) {\n              modelCtrl.$$debounceViewValueCommit(ev && ev.type);\n            });\n          }\n\n          function setTouched() {\n            modelCtrl.$setTouched();\n          }\n\n          element.on('blur', function() {\n            if (modelCtrl.$touched) return;\n\n            if ($rootScope.$$phase) {\n              scope.$evalAsync(setTouched);\n            } else {\n              scope.$apply(setTouched);\n            }\n          });\n        }\n      };\n    }\n  };\n}];\n\n/* exported defaultModelOptions */\nvar defaultModelOptions;\nvar DEFAULT_REGEXP = /(\\s+|^)default(\\s+|$)/;\n\n/**\n * @ngdoc type\n * @name ModelOptions\n * @description\n * A container for the options set by the {@link ngModelOptions} directive\n */\nfunction ModelOptions(options) {\n  this.$$options = options;\n}\n\nModelOptions.prototype = {\n\n  /**\n   * @ngdoc method\n   * @name ModelOptions#getOption\n   * @param {string} name the name of the option to retrieve\n   * @returns {*} the value of the option\n   * @description\n   * Returns the value of the given option\n   */\n  getOption: function(name) {\n    return this.$$options[name];\n  },\n\n  /**\n   * @ngdoc method\n   * @name ModelOptions#createChild\n   * @param {Object} options a hash of options for the new child that will override the parent's options\n   * @return {ModelOptions} a new `ModelOptions` object initialized with the given options.\n   */\n  createChild: function(options) {\n    var inheritAll = false;\n\n    // make a shallow copy\n    options = extend({}, options);\n\n    // Inherit options from the parent if specified by the value `\"$inherit\"`\n    forEach(options, /* @this */ function(option, key) {\n      if (option === '$inherit') {\n        if (key === '*') {\n          inheritAll = true;\n        } else {\n          options[key] = this.$$options[key];\n          // `updateOn` is special so we must also inherit the `updateOnDefault` option\n          if (key === 'updateOn') {\n            options.updateOnDefault = this.$$options.updateOnDefault;\n          }\n        }\n      } else {\n        if (key === 'updateOn') {\n          // If the `updateOn` property contains the `default` event then we have to remove\n          // it from the event list and set the `updateOnDefault` flag.\n          options.updateOnDefault = false;\n          options[key] = trim(option.replace(DEFAULT_REGEXP, function() {\n            options.updateOnDefault = true;\n            return ' ';\n          }));\n        }\n      }\n    }, this);\n\n    if (inheritAll) {\n      // We have a property of the form: `\"*\": \"$inherit\"`\n      delete options['*'];\n      defaults(options, this.$$options);\n    }\n\n    // Finally add in any missing defaults\n    defaults(options, defaultModelOptions.$$options);\n\n    return new ModelOptions(options);\n  }\n};\n\n\ndefaultModelOptions = new ModelOptions({\n  updateOn: '',\n  updateOnDefault: true,\n  debounce: 0,\n  getterSetter: false,\n  allowInvalid: false,\n  timezone: null\n});\n\n\n/**\n * @ngdoc directive\n * @name ngModelOptions\n *\n * @description\n * This directive allows you to modify the behaviour of {@link ngModel} directives within your\n * application. You can specify an `ngModelOptions` directive on any element. All {@link ngModel}\n * directives will use the options of their nearest `ngModelOptions` ancestor.\n *\n * The `ngModelOptions` settings are found by evaluating the value of the attribute directive as\n * an Angular expression. This expression should evaluate to an object, whose properties contain\n * the settings. For example: `<div \"ng-model-options\"=\"{ debounce: 100 }\"`.\n *\n * ## Inheriting Options\n *\n * You can specify that an `ngModelOptions` setting should be inherited from a parent `ngModelOptions`\n * directive by giving it the value of `\"$inherit\"`.\n * Then it will inherit that setting from the first `ngModelOptions` directive found by traversing up the\n * DOM tree. If there is no ancestor element containing an `ngModelOptions` directive then default settings\n * will be used.\n *\n * For example given the following fragment of HTML\n *\n *\n * ```html\n * <div ng-model-options=\"{ allowInvalid: true, debounce: 200 }\">\n *   <form ng-model-options=\"{ updateOn: 'blur', allowInvalid: '$inherit' }\">\n *     <input ng-model-options=\"{ updateOn: 'default', allowInvalid: '$inherit' }\" />\n *   </form>\n * </div>\n * ```\n *\n * the `input` element will have the following settings\n *\n * ```js\n * { allowInvalid: true, updateOn: 'default', debounce: 0 }\n * ```\n *\n * Notice that the `debounce` setting was not inherited and used the default value instead.\n *\n * You can specify that all undefined settings are automatically inherited from an ancestor by\n * including a property with key of `\"*\"` and value of `\"$inherit\"`.\n *\n * For example given the following fragment of HTML\n *\n *\n * ```html\n * <div ng-model-options=\"{ allowInvalid: true, debounce: 200 }\">\n *   <form ng-model-options=\"{ updateOn: 'blur', \"*\": '$inherit' }\">\n *     <input ng-model-options=\"{ updateOn: 'default', \"*\": '$inherit' }\" />\n *   </form>\n * </div>\n * ```\n *\n * the `input` element will have the following settings\n *\n * ```js\n * { allowInvalid: true, updateOn: 'default', debounce: 200 }\n * ```\n *\n * Notice that the `debounce` setting now inherits the value from the outer `<div>` element.\n *\n * If you are creating a reusable component then you should be careful when using `\"*\": \"$inherit\"`\n * since you may inadvertently inherit a setting in the future that changes the behavior of your component.\n *\n *\n * ## Triggering and debouncing model updates\n *\n * The `updateOn` and `debounce` properties allow you to specify a custom list of events that will\n * trigger a model update and/or a debouncing delay so that the actual update only takes place when\n * a timer expires; this timer will be reset after another change takes place.\n *\n * Given the nature of `ngModelOptions`, the value displayed inside input fields in the view might\n * be different from the value in the actual model. This means that if you update the model you\n * should also invoke {@link ngModel.NgModelController#$rollbackViewValue} on the relevant input field in\n * order to make sure it is synchronized with the model and that any debounced action is canceled.\n *\n * The easiest way to reference the control's {@link ngModel.NgModelController#$rollbackViewValue}\n * method is by making sure the input is placed inside a form that has a `name` attribute. This is\n * important because `form` controllers are published to the related scope under the name in their\n * `name` attribute.\n *\n * Any pending changes will take place immediately when an enclosing form is submitted via the\n * `submit` event. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`\n * to have access to the updated model.\n *\n * The following example shows how to override immediate updates. Changes on the inputs within the\n * form will update the model only when the control loses focus (blur event). If `escape` key is\n * pressed while the input field is focused, the value is reset to the value in the current model.\n *\n * <example name=\"ngModelOptions-directive-blur\" module=\"optionsExample\">\n *   <file name=\"index.html\">\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"userForm\">\n *         <label>\n *           Name:\n *           <input type=\"text\" name=\"userName\"\n *                  ng-model=\"user.name\"\n *                  ng-model-options=\"{ updateOn: 'blur' }\"\n *                  ng-keyup=\"cancel($event)\" />\n *         </label><br />\n *         <label>\n *           Other data:\n *           <input type=\"text\" ng-model=\"user.data\" />\n *         </label><br />\n *       </form>\n *       <pre>user.name = <span ng-bind=\"user.name\"></span></pre>\n *     </div>\n *   </file>\n *   <file name=\"app.js\">\n *     angular.module('optionsExample', [])\n *       .controller('ExampleController', ['$scope', function($scope) {\n *         $scope.user = { name: 'say', data: '' };\n *\n *         $scope.cancel = function(e) {\n *           if (e.keyCode === 27) {\n *             $scope.userForm.userName.$rollbackViewValue();\n *           }\n *         };\n *       }]);\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     var model = element(by.binding('user.name'));\n *     var input = element(by.model('user.name'));\n *     var other = element(by.model('user.data'));\n *\n *     it('should allow custom events', function() {\n *       input.sendKeys(' hello');\n *       input.click();\n *       expect(model.getText()).toEqual('say');\n *       other.click();\n *       expect(model.getText()).toEqual('say hello');\n *     });\n *\n *     it('should $rollbackViewValue when model changes', function() {\n *       input.sendKeys(' hello');\n *       expect(input.getAttribute('value')).toEqual('say hello');\n *       input.sendKeys(protractor.Key.ESCAPE);\n *       expect(input.getAttribute('value')).toEqual('say');\n *       other.click();\n *       expect(model.getText()).toEqual('say');\n *     });\n *   </file>\n * </example>\n *\n * The next example shows how to debounce model changes. Model will be updated only 1 sec after last change.\n * If the `Clear` button is pressed, any debounced action is canceled and the value becomes empty.\n *\n * <example name=\"ngModelOptions-directive-debounce\" module=\"optionsExample\">\n *   <file name=\"index.html\">\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"userForm\">\n *         Name:\n *         <input type=\"text\" name=\"userName\"\n *                ng-model=\"user.name\"\n *                ng-model-options=\"{ debounce: 1000 }\" />\n *         <button ng-click=\"userForm.userName.$rollbackViewValue(); user.name=''\">Clear</button><br />\n *       </form>\n *       <pre>user.name = <span ng-bind=\"user.name\"></span></pre>\n *     </div>\n *   </file>\n *   <file name=\"app.js\">\n *     angular.module('optionsExample', [])\n *       .controller('ExampleController', ['$scope', function($scope) {\n *         $scope.user = { name: 'say' };\n *       }]);\n *   </file>\n * </example>\n *\n * ## Model updates and validation\n *\n * The default behaviour in `ngModel` is that the model value is set to `undefined` when the\n * validation determines that the value is invalid. By setting the `allowInvalid` property to true,\n * the model will still be updated even if the value is invalid.\n *\n *\n * ## Connecting to the scope\n *\n * By setting the `getterSetter` property to true you are telling ngModel that the `ngModel` expression\n * on the scope refers to a \"getter/setter\" function rather than the value itself.\n *\n * The following example shows how to bind to getter/setters:\n *\n * <example name=\"ngModelOptions-directive-getter-setter\" module=\"getterSetterExample\">\n *   <file name=\"index.html\">\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"userForm\">\n *         <label>\n *           Name:\n *           <input type=\"text\" name=\"userName\"\n *                  ng-model=\"user.name\"\n *                  ng-model-options=\"{ getterSetter: true }\" />\n *         </label>\n *       </form>\n *       <pre>user.name = <span ng-bind=\"user.name()\"></span></pre>\n *     </div>\n *   </file>\n *   <file name=\"app.js\">\n *     angular.module('getterSetterExample', [])\n *       .controller('ExampleController', ['$scope', function($scope) {\n *         var _name = 'Brian';\n *         $scope.user = {\n *           name: function(newName) {\n *             return angular.isDefined(newName) ? (_name = newName) : _name;\n *           }\n *         };\n *       }]);\n *   </file>\n * </example>\n *\n *\n * ## Specifying timezones\n *\n * You can specify the timezone that date/time input directives expect by providing its name in the\n * `timezone` property.\n *\n * @param {Object} ngModelOptions options to apply to {@link ngModel} directives on this element and\n *   and its descendents. Valid keys are:\n *   - `updateOn`: string specifying which event should the input be bound to. You can set several\n *     events using an space delimited list. There is a special event called `default` that\n *     matches the default events belonging to the control.\n *   - `debounce`: integer value which contains the debounce model update value in milliseconds. A\n *     value of 0 triggers an immediate update. If an object is supplied instead, you can specify a\n *     custom value for each event. For example:\n *     ```\n *     ng-model-options=\"{\n *       updateOn: 'default blur',\n *       debounce: { 'default': 500, 'blur': 0 }\n *     }\"\n *     ```\n *   - `allowInvalid`: boolean value which indicates that the model can be set with values that did\n *     not validate correctly instead of the default behavior of setting the model to undefined.\n *   - `getterSetter`: boolean value which determines whether or not to treat functions bound to\n *     `ngModel` as getters/setters.\n *   - `timezone`: Defines the timezone to be used to read/write the `Date` instance in the model for\n *     `<input type=\"date\" />`, `<input type=\"time\" />`, ... . It understands UTC/GMT and the\n *     continental US time zone abbreviations, but for general use, use a time zone offset, for\n *     example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)\n *     If not specified, the timezone of the browser will be used.\n *\n */\nvar ngModelOptionsDirective = function() {\n  NgModelOptionsController.$inject = ['$attrs', '$scope'];\n  function NgModelOptionsController($attrs, $scope) {\n    this.$$attrs = $attrs;\n    this.$$scope = $scope;\n  }\n  NgModelOptionsController.prototype = {\n    $onInit: function() {\n      var parentOptions = this.parentCtrl ? this.parentCtrl.$options : defaultModelOptions;\n      var modelOptionsDefinition = this.$$scope.$eval(this.$$attrs.ngModelOptions);\n\n      this.$options = parentOptions.createChild(modelOptionsDefinition);\n    }\n  };\n\n  return {\n    restrict: 'A',\n    // ngModelOptions needs to run before ngModel and input directives\n    priority: 10,\n    require: {parentCtrl: '?^^ngModelOptions'},\n    bindToController: true,\n    controller: NgModelOptionsController\n  };\n};\n\n\n// shallow copy over values from `src` that are not already specified on `dst`\nfunction defaults(dst, src) {\n  forEach(src, function(value, key) {\n    if (!isDefined(dst[key])) {\n      dst[key] = value;\n    }\n  });\n}\n\n/**\n * @ngdoc directive\n * @name ngNonBindable\n * @restrict AC\n * @priority 1000\n *\n * @description\n * The `ngNonBindable` directive tells Angular not to compile or bind the contents of the current\n * DOM element. This is useful if the element contains what appears to be Angular directives and\n * bindings but which should be ignored by Angular. This could be the case if you have a site that\n * displays snippets of code, for instance.\n *\n * @element ANY\n *\n * @example\n * In this example there are two locations where a simple interpolation binding (`{{}}`) is present,\n * but the one wrapped in `ngNonBindable` is left alone.\n *\n * @example\n    <example name=\"ng-non-bindable\">\n      <file name=\"index.html\">\n        <div>Normal: {{1 + 2}}</div>\n        <div ng-non-bindable>Ignored: {{1 + 2}}</div>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n       it('should check ng-non-bindable', function() {\n         expect(element(by.binding('1 + 2')).getText()).toContain('3');\n         expect(element.all(by.css('div')).last().getText()).toMatch(/1 \\+ 2/);\n       });\n      </file>\n    </example>\n */\nvar ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });\n\n/* exported ngOptionsDirective */\n\n/* global jqLiteRemove */\n\nvar ngOptionsMinErr = minErr('ngOptions');\n\n/**\n * @ngdoc directive\n * @name ngOptions\n * @restrict A\n *\n * @description\n *\n * The `ngOptions` attribute can be used to dynamically generate a list of `<option>`\n * elements for the `<select>` element using the array or object obtained by evaluating the\n * `ngOptions` comprehension expression.\n *\n * In many cases, {@link ng.directive:ngRepeat ngRepeat} can be used on `<option>` elements instead of\n * `ngOptions` to achieve a similar result. However, `ngOptions` provides some benefits:\n * - more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the\n * comprehension expression\n * - reduced memory consumption by not creating a new scope for each repeated instance\n * - increased render speed by creating the options in a documentFragment instead of individually\n *\n * When an item in the `<select>` menu is selected, the array element or object property\n * represented by the selected option will be bound to the model identified by the `ngModel`\n * directive.\n *\n * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can\n * be nested into the `<select>` element. This element will then represent the `null` or \"not selected\"\n * option. See example below for demonstration.\n *\n * ## Complex Models (objects or collections)\n *\n * By default, `ngModel` watches the model by reference, not value. This is important to know when\n * binding the select to a model that is an object or a collection.\n *\n * One issue occurs if you want to preselect an option. For example, if you set\n * the model to an object that is equal to an object in your collection, `ngOptions` won't be able to set the selection,\n * because the objects are not identical. So by default, you should always reference the item in your collection\n * for preselections, e.g.: `$scope.selected = $scope.collection[3]`.\n *\n * Another solution is to use a `track by` clause, because then `ngOptions` will track the identity\n * of the item not by reference, but by the result of the `track by` expression. For example, if your\n * collection items have an id property, you would `track by item.id`.\n *\n * A different issue with objects or collections is that ngModel won't detect if an object property or\n * a collection item changes. For that reason, `ngOptions` additionally watches the model using\n * `$watchCollection`, when the expression contains a `track by` clause or the the select has the `multiple` attribute.\n * This allows ngOptions to trigger a re-rendering of the options even if the actual object/collection\n * has not changed identity, but only a property on the object or an item in the collection changes.\n *\n * Note that `$watchCollection` does a shallow comparison of the properties of the object (or the items in the collection\n * if the model is an array). This means that changing a property deeper than the first level inside the\n * object/collection will not trigger a re-rendering.\n *\n * ## `select` **`as`**\n *\n * Using `select` **`as`** will bind the result of the `select` expression to the model, but\n * the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)\n * or property name (for object data sources) of the value within the collection. If a **`track by`** expression\n * is used, the result of that expression will be set as the value of the `option` and `select` elements.\n *\n *\n * ### `select` **`as`** and **`track by`**\n *\n * <div class=\"alert alert-warning\">\n * Be careful when using `select` **`as`** and **`track by`** in the same expression.\n * </div>\n *\n * Given this array of items on the $scope:\n *\n * ```js\n * $scope.items = [{\n *   id: 1,\n *   label: 'aLabel',\n *   subItem: { name: 'aSubItem' }\n * }, {\n *   id: 2,\n *   label: 'bLabel',\n *   subItem: { name: 'bSubItem' }\n * }];\n * ```\n *\n * This will work:\n *\n * ```html\n * <select ng-options=\"item as item.label for item in items track by item.id\" ng-model=\"selected\"></select>\n * ```\n * ```js\n * $scope.selected = $scope.items[0];\n * ```\n *\n * but this will not work:\n *\n * ```html\n * <select ng-options=\"item.subItem as item.label for item in items track by item.id\" ng-model=\"selected\"></select>\n * ```\n * ```js\n * $scope.selected = $scope.items[0].subItem;\n * ```\n *\n * In both examples, the **`track by`** expression is applied successfully to each `item` in the\n * `items` array. Because the selected option has been set programmatically in the controller, the\n * **`track by`** expression is also applied to the `ngModel` value. In the first example, the\n * `ngModel` value is `items[0]` and the **`track by`** expression evaluates to `items[0].id` with\n * no issue. In the second example, the `ngModel` value is `items[0].subItem` and the **`track by`**\n * expression evaluates to `items[0].subItem.id` (which is undefined). As a result, the model value\n * is not matched against any `<option>` and the `<select>` appears as having no selected value.\n *\n *\n * @param {string} ngModel Assignable AngularJS expression to data-bind to.\n * @param {comprehension_expression} ngOptions in one of the following forms:\n *\n *   * for array data sources:\n *     * `label` **`for`** `value` **`in`** `array`\n *     * `select` **`as`** `label` **`for`** `value` **`in`** `array`\n *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array`\n *     * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array`\n *     * `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`\n *     * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`\n *     * `label` **`for`** `value` **`in`** `array` | orderBy:`orderexpr` **`track by`** `trackexpr`\n *        (for including a filter with `track by`)\n *   * for object data sources:\n *     * `label` **`for (`**`key` **`,`** `value`**`) in`** `object`\n *     * `select` **`as`** `label` **`for (`**`key` **`,`** `value`**`) in`** `object`\n *     * `label` **`group by`** `group` **`for (`**`key`**`,`** `value`**`) in`** `object`\n *     * `label` **`disable when`** `disable` **`for (`**`key`**`,`** `value`**`) in`** `object`\n *     * `select` **`as`** `label` **`group by`** `group`\n *         **`for` `(`**`key`**`,`** `value`**`) in`** `object`\n *     * `select` **`as`** `label` **`disable when`** `disable`\n *         **`for` `(`**`key`**`,`** `value`**`) in`** `object`\n *\n * Where:\n *\n *   * `array` / `object`: an expression which evaluates to an array / object to iterate over.\n *   * `value`: local variable which will refer to each item in the `array` or each property value\n *      of `object` during iteration.\n *   * `key`: local variable which will refer to a property name in `object` during iteration.\n *   * `label`: The result of this expression will be the label for `<option>` element. The\n *     `expression` will most likely refer to the `value` variable (e.g. `value.propertyName`).\n *   * `select`: The result of this expression will be bound to the model of the parent `<select>`\n *      element. If not specified, `select` expression will default to `value`.\n *   * `group`: The result of this expression will be used to group options using the `<optgroup>`\n *      DOM element.\n *   * `disable`: The result of this expression will be used to disable the rendered `<option>`\n *      element. Return `true` to disable.\n *   * `trackexpr`: Used when working with an array of objects. The result of this expression will be\n *      used to identify the objects in the array. The `trackexpr` will most likely refer to the\n *     `value` variable (e.g. `value.propertyName`). With this the selection is preserved\n *      even when the options are recreated (e.g. reloaded from the server).\n * @param {string=} name Property name of the form under which the control is published.\n * @param {string=} required The control is considered valid only if value is entered.\n * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to\n *    the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of\n *    `required` when you want to data-bind to the `required` attribute.\n * @param {string=} ngAttrSize sets the size of the select element dynamically. Uses the\n * {@link guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes ngAttr} directive.\n *\n * @example\n    <example module=\"selectExample\" name=\"select\">\n      <file name=\"index.html\">\n        <script>\n        angular.module('selectExample', [])\n          .controller('ExampleController', ['$scope', function($scope) {\n            $scope.colors = [\n              {name:'black', shade:'dark'},\n              {name:'white', shade:'light', notAnOption: true},\n              {name:'red', shade:'dark'},\n              {name:'blue', shade:'dark', notAnOption: true},\n              {name:'yellow', shade:'light', notAnOption: false}\n            ];\n            $scope.myColor = $scope.colors[2]; // red\n          }]);\n        </script>\n        <div ng-controller=\"ExampleController\">\n          <ul>\n            <li ng-repeat=\"color in colors\">\n              <label>Name: <input ng-model=\"color.name\"></label>\n              <label><input type=\"checkbox\" ng-model=\"color.notAnOption\"> Disabled?</label>\n              <button ng-click=\"colors.splice($index, 1)\" aria-label=\"Remove\">X</button>\n            </li>\n            <li>\n              <button ng-click=\"colors.push({})\">add</button>\n            </li>\n          </ul>\n          <hr/>\n          <label>Color (null not allowed):\n            <select ng-model=\"myColor\" ng-options=\"color.name for color in colors\"></select>\n          </label><br/>\n          <label>Color (null allowed):\n          <span  class=\"nullable\">\n            <select ng-model=\"myColor\" ng-options=\"color.name for color in colors\">\n              <option value=\"\">-- choose color --</option>\n            </select>\n          </span></label><br/>\n\n          <label>Color grouped by shade:\n            <select ng-model=\"myColor\" ng-options=\"color.name group by color.shade for color in colors\">\n            </select>\n          </label><br/>\n\n          <label>Color grouped by shade, with some disabled:\n            <select ng-model=\"myColor\"\n                  ng-options=\"color.name group by color.shade disable when color.notAnOption for color in colors\">\n            </select>\n          </label><br/>\n\n\n\n          Select <button ng-click=\"myColor = { name:'not in list', shade: 'other' }\">bogus</button>.\n          <br/>\n          <hr/>\n          Currently selected: {{ {selected_color:myColor} }}\n          <div style=\"border:solid 1px black; height:20px\"\n               ng-style=\"{'background-color':myColor.name}\">\n          </div>\n        </div>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n         it('should check ng-options', function() {\n           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red');\n           element.all(by.model('myColor')).first().click();\n           element.all(by.css('select[ng-model=\"myColor\"] option')).first().click();\n           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black');\n           element(by.css('.nullable select[ng-model=\"myColor\"]')).click();\n           element.all(by.css('.nullable select[ng-model=\"myColor\"] option')).first().click();\n           expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('null');\n         });\n      </file>\n    </example>\n */\n\n/* eslint-disable max-len */\n//                     //00001111111111000000000002222222222000000000000000000000333333333300000000000000000000000004444444444400000000000005555555555555000000000666666666666600000007777777777777000000000000000888888888800000000000000000009999999999\nvar NG_OPTIONS_REGEXP = /^\\s*([\\s\\S]+?)(?:\\s+as\\s+([\\s\\S]+?))?(?:\\s+group\\s+by\\s+([\\s\\S]+?))?(?:\\s+disable\\s+when\\s+([\\s\\S]+?))?\\s+for\\s+(?:([$\\w][$\\w]*)|(?:\\(\\s*([$\\w][$\\w]*)\\s*,\\s*([$\\w][$\\w]*)\\s*\\)))\\s+in\\s+([\\s\\S]+?)(?:\\s+track\\s+by\\s+([\\s\\S]+?))?$/;\n                        // 1: value expression (valueFn)\n                        // 2: label expression (displayFn)\n                        // 3: group by expression (groupByFn)\n                        // 4: disable when expression (disableWhenFn)\n                        // 5: array item variable name\n                        // 6: object item key variable name\n                        // 7: object item value variable name\n                        // 8: collection expression\n                        // 9: track by expression\n/* eslint-enable */\n\n\nvar ngOptionsDirective = ['$compile', '$document', '$parse', function($compile, $document, $parse) {\n\n  function parseOptionsExpression(optionsExp, selectElement, scope) {\n\n    var match = optionsExp.match(NG_OPTIONS_REGEXP);\n    if (!(match)) {\n      throw ngOptionsMinErr('iexp',\n        'Expected expression in form of ' +\n        '\\'_select_ (as _label_)? for (_key_,)?_value_ in _collection_\\'' +\n        ' but got \\'{0}\\'. Element: {1}',\n        optionsExp, startingTag(selectElement));\n    }\n\n    // Extract the parts from the ngOptions expression\n\n    // The variable name for the value of the item in the collection\n    var valueName = match[5] || match[7];\n    // The variable name for the key of the item in the collection\n    var keyName = match[6];\n\n    // An expression that generates the viewValue for an option if there is a label expression\n    var selectAs = / as /.test(match[0]) && match[1];\n    // An expression that is used to track the id of each object in the options collection\n    var trackBy = match[9];\n    // An expression that generates the viewValue for an option if there is no label expression\n    var valueFn = $parse(match[2] ? match[1] : valueName);\n    var selectAsFn = selectAs && $parse(selectAs);\n    var viewValueFn = selectAsFn || valueFn;\n    var trackByFn = trackBy && $parse(trackBy);\n\n    // Get the value by which we are going to track the option\n    // if we have a trackFn then use that (passing scope and locals)\n    // otherwise just hash the given viewValue\n    var getTrackByValueFn = trackBy ?\n                              function(value, locals) { return trackByFn(scope, locals); } :\n                              function getHashOfValue(value) { return hashKey(value); };\n    var getTrackByValue = function(value, key) {\n      return getTrackByValueFn(value, getLocals(value, key));\n    };\n\n    var displayFn = $parse(match[2] || match[1]);\n    var groupByFn = $parse(match[3] || '');\n    var disableWhenFn = $parse(match[4] || '');\n    var valuesFn = $parse(match[8]);\n\n    var locals = {};\n    var getLocals = keyName ? function(value, key) {\n      locals[keyName] = key;\n      locals[valueName] = value;\n      return locals;\n    } : function(value) {\n      locals[valueName] = value;\n      return locals;\n    };\n\n\n    function Option(selectValue, viewValue, label, group, disabled) {\n      this.selectValue = selectValue;\n      this.viewValue = viewValue;\n      this.label = label;\n      this.group = group;\n      this.disabled = disabled;\n    }\n\n    function getOptionValuesKeys(optionValues) {\n      var optionValuesKeys;\n\n      if (!keyName && isArrayLike(optionValues)) {\n        optionValuesKeys = optionValues;\n      } else {\n        // if object, extract keys, in enumeration order, unsorted\n        optionValuesKeys = [];\n        for (var itemKey in optionValues) {\n          if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') {\n            optionValuesKeys.push(itemKey);\n          }\n        }\n      }\n      return optionValuesKeys;\n    }\n\n    return {\n      trackBy: trackBy,\n      getTrackByValue: getTrackByValue,\n      getWatchables: $parse(valuesFn, function(optionValues) {\n        // Create a collection of things that we would like to watch (watchedArray)\n        // so that they can all be watched using a single $watchCollection\n        // that only runs the handler once if anything changes\n        var watchedArray = [];\n        optionValues = optionValues || [];\n\n        var optionValuesKeys = getOptionValuesKeys(optionValues);\n        var optionValuesLength = optionValuesKeys.length;\n        for (var index = 0; index < optionValuesLength; index++) {\n          var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];\n          var value = optionValues[key];\n\n          var locals = getLocals(value, key);\n          var selectValue = getTrackByValueFn(value, locals);\n          watchedArray.push(selectValue);\n\n          // Only need to watch the displayFn if there is a specific label expression\n          if (match[2] || match[1]) {\n            var label = displayFn(scope, locals);\n            watchedArray.push(label);\n          }\n\n          // Only need to watch the disableWhenFn if there is a specific disable expression\n          if (match[4]) {\n            var disableWhen = disableWhenFn(scope, locals);\n            watchedArray.push(disableWhen);\n          }\n        }\n        return watchedArray;\n      }),\n\n      getOptions: function() {\n\n        var optionItems = [];\n        var selectValueMap = {};\n\n        // The option values were already computed in the `getWatchables` fn,\n        // which must have been called to trigger `getOptions`\n        var optionValues = valuesFn(scope) || [];\n        var optionValuesKeys = getOptionValuesKeys(optionValues);\n        var optionValuesLength = optionValuesKeys.length;\n\n        for (var index = 0; index < optionValuesLength; index++) {\n          var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];\n          var value = optionValues[key];\n          var locals = getLocals(value, key);\n          var viewValue = viewValueFn(scope, locals);\n          var selectValue = getTrackByValueFn(viewValue, locals);\n          var label = displayFn(scope, locals);\n          var group = groupByFn(scope, locals);\n          var disabled = disableWhenFn(scope, locals);\n          var optionItem = new Option(selectValue, viewValue, label, group, disabled);\n\n          optionItems.push(optionItem);\n          selectValueMap[selectValue] = optionItem;\n        }\n\n        return {\n          items: optionItems,\n          selectValueMap: selectValueMap,\n          getOptionFromViewValue: function(value) {\n            return selectValueMap[getTrackByValue(value)];\n          },\n          getViewValueFromOption: function(option) {\n            // If the viewValue could be an object that may be mutated by the application,\n            // we need to make a copy and not return the reference to the value on the option.\n            return trackBy ? copy(option.viewValue) : option.viewValue;\n          }\n        };\n      }\n    };\n  }\n\n\n  // we can't just jqLite('<option>') since jqLite is not smart enough\n  // to create it in <select> and IE barfs otherwise.\n  var optionTemplate = window.document.createElement('option'),\n      optGroupTemplate = window.document.createElement('optgroup');\n\n    function ngOptionsPostLink(scope, selectElement, attr, ctrls) {\n\n      var selectCtrl = ctrls[0];\n      var ngModelCtrl = ctrls[1];\n      var multiple = attr.multiple;\n\n      // The emptyOption allows the application developer to provide their own custom \"empty\"\n      // option when the viewValue does not match any of the option values.\n      for (var i = 0, children = selectElement.children(), ii = children.length; i < ii; i++) {\n        if (children[i].value === '') {\n          selectCtrl.hasEmptyOption = true;\n          selectCtrl.emptyOption = children.eq(i);\n          break;\n        }\n      }\n\n      var providedEmptyOption = !!selectCtrl.emptyOption;\n\n      var unknownOption = jqLite(optionTemplate.cloneNode(false));\n      unknownOption.val('?');\n\n      var options;\n      var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope);\n      // This stores the newly created options before they are appended to the select.\n      // Since the contents are removed from the fragment when it is appended,\n      // we only need to create it once.\n      var listFragment = $document[0].createDocumentFragment();\n\n      // Overwrite the implementation. ngOptions doesn't use hashes\n      selectCtrl.generateUnknownOptionValue = function(val) {\n        return '?';\n      };\n\n      // Update the controller methods for multiple selectable options\n      if (!multiple) {\n\n        selectCtrl.writeValue = function writeNgOptionsValue(value) {\n          var selectedOption = options.selectValueMap[selectElement.val()];\n          var option = options.getOptionFromViewValue(value);\n\n          // Make sure to remove the selected attribute from the previously selected option\n          // Otherwise, screen readers might get confused\n          if (selectedOption) selectedOption.element.removeAttribute('selected');\n\n          if (option) {\n            // Don't update the option when it is already selected.\n            // For example, the browser will select the first option by default. In that case,\n            // most properties are set automatically - except the `selected` attribute, which we\n            // set always\n\n            if (selectElement[0].value !== option.selectValue) {\n              selectCtrl.removeUnknownOption();\n              selectCtrl.unselectEmptyOption();\n\n              selectElement[0].value = option.selectValue;\n              option.element.selected = true;\n            }\n\n            option.element.setAttribute('selected', 'selected');\n          } else {\n\n            if (providedEmptyOption) {\n              selectCtrl.selectEmptyOption();\n            } else if (selectCtrl.unknownOption.parent().length) {\n              selectCtrl.updateUnknownOption(value);\n            } else {\n              selectCtrl.renderUnknownOption(value);\n            }\n          }\n        };\n\n        selectCtrl.readValue = function readNgOptionsValue() {\n\n          var selectedOption = options.selectValueMap[selectElement.val()];\n\n          if (selectedOption && !selectedOption.disabled) {\n            selectCtrl.unselectEmptyOption();\n            selectCtrl.removeUnknownOption();\n            return options.getViewValueFromOption(selectedOption);\n          }\n          return null;\n        };\n\n        // If we are using `track by` then we must watch the tracked value on the model\n        // since ngModel only watches for object identity change\n        // FIXME: When a user selects an option, this watch will fire needlessly\n        if (ngOptions.trackBy) {\n          scope.$watch(\n            function() { return ngOptions.getTrackByValue(ngModelCtrl.$viewValue); },\n            function() { ngModelCtrl.$render(); }\n          );\n        }\n\n      } else {\n\n        selectCtrl.writeValue = function writeNgOptionsMultiple(values) {\n          // Only set `<option>.selected` if necessary, in order to prevent some browsers from\n          // scrolling to `<option>` elements that are outside the `<select>` element's viewport.\n\n          var selectedOptions = values && values.map(getAndUpdateSelectedOption) || [];\n\n          options.items.forEach(function(option) {\n            if (option.element.selected && !includes(selectedOptions, option)) {\n              option.element.selected = false;\n            }\n          });\n        };\n\n\n        selectCtrl.readValue = function readNgOptionsMultiple() {\n          var selectedValues = selectElement.val() || [],\n              selections = [];\n\n          forEach(selectedValues, function(value) {\n            var option = options.selectValueMap[value];\n            if (option && !option.disabled) selections.push(options.getViewValueFromOption(option));\n          });\n\n          return selections;\n        };\n\n        // If we are using `track by` then we must watch these tracked values on the model\n        // since ngModel only watches for object identity change\n        if (ngOptions.trackBy) {\n\n          scope.$watchCollection(function() {\n            if (isArray(ngModelCtrl.$viewValue)) {\n              return ngModelCtrl.$viewValue.map(function(value) {\n                return ngOptions.getTrackByValue(value);\n              });\n            }\n          }, function() {\n            ngModelCtrl.$render();\n          });\n\n        }\n      }\n\n      if (providedEmptyOption) {\n\n        // we need to remove it before calling selectElement.empty() because otherwise IE will\n        // remove the label from the element. wtf?\n        selectCtrl.emptyOption.remove();\n\n        // compile the element since there might be bindings in it\n        $compile(selectCtrl.emptyOption)(scope);\n\n        if (selectCtrl.emptyOption[0].nodeType === NODE_TYPE_COMMENT) {\n          // This means the empty option has currently no actual DOM node, probably because\n          // it has been modified by a transclusion directive.\n          selectCtrl.hasEmptyOption = false;\n\n          // Redefine the registerOption function, which will catch\n          // options that are added by ngIf etc. (rendering of the node is async because of\n          // lazy transclusion)\n          selectCtrl.registerOption = function(optionScope, optionEl) {\n            if (optionEl.val() === '') {\n              selectCtrl.hasEmptyOption = true;\n              selectCtrl.emptyOption = optionEl;\n              selectCtrl.emptyOption.removeClass('ng-scope');\n              // This ensures the new empty option is selected if previously no option was selected\n              ngModelCtrl.$render();\n\n              optionEl.on('$destroy', function() {\n                selectCtrl.hasEmptyOption = false;\n                selectCtrl.emptyOption = undefined;\n              });\n            }\n          };\n\n        } else {\n          // remove the class, which is added automatically because we recompile the element and it\n          // becomes the compilation root\n          selectCtrl.emptyOption.removeClass('ng-scope');\n        }\n\n      }\n\n      selectElement.empty();\n\n      // We need to do this here to ensure that the options object is defined\n      // when we first hit it in writeNgOptionsValue\n      updateOptions();\n\n      // We will re-render the option elements if the option values or labels change\n      scope.$watchCollection(ngOptions.getWatchables, updateOptions);\n\n      // ------------------------------------------------------------------ //\n\n      function addOptionElement(option, parent) {\n        var optionElement = optionTemplate.cloneNode(false);\n        parent.appendChild(optionElement);\n        updateOptionElement(option, optionElement);\n      }\n\n      function getAndUpdateSelectedOption(viewValue) {\n        var option = options.getOptionFromViewValue(viewValue);\n        var element = option && option.element;\n\n        if (element && !element.selected) element.selected = true;\n\n        return option;\n      }\n\n      function updateOptionElement(option, element) {\n        option.element = element;\n        element.disabled = option.disabled;\n        // NOTE: The label must be set before the value, otherwise IE10/11/EDGE create unresponsive\n        // selects in certain circumstances when multiple selects are next to each other and display\n        // the option list in listbox style, i.e. the select is [multiple], or specifies a [size].\n        // See https://github.com/angular/angular.js/issues/11314 for more info.\n        // This is unfortunately untestable with unit / e2e tests\n        if (option.label !== element.label) {\n          element.label = option.label;\n          element.textContent = option.label;\n        }\n        element.value = option.selectValue;\n      }\n\n      function updateOptions() {\n        var previousValue = options && selectCtrl.readValue();\n\n        // We must remove all current options, but cannot simply set innerHTML = null\n        // since the providedEmptyOption might have an ngIf on it that inserts comments which we\n        // must preserve.\n        // Instead, iterate over the current option elements and remove them or their optgroup\n        // parents\n        if (options) {\n\n          for (var i = options.items.length - 1; i >= 0; i--) {\n            var option = options.items[i];\n            if (isDefined(option.group)) {\n              jqLiteRemove(option.element.parentNode);\n            } else {\n              jqLiteRemove(option.element);\n            }\n          }\n        }\n\n        options = ngOptions.getOptions();\n\n        var groupElementMap = {};\n\n        // Ensure that the empty option is always there if it was explicitly provided\n        if (providedEmptyOption) {\n          selectElement.prepend(selectCtrl.emptyOption);\n        }\n\n        options.items.forEach(function addOption(option) {\n          var groupElement;\n\n          if (isDefined(option.group)) {\n\n            // This option is to live in a group\n            // See if we have already created this group\n            groupElement = groupElementMap[option.group];\n\n            if (!groupElement) {\n\n              groupElement = optGroupTemplate.cloneNode(false);\n              listFragment.appendChild(groupElement);\n\n              // Update the label on the group element\n              // \"null\" is special cased because of Safari\n              groupElement.label = option.group === null ? 'null' : option.group;\n\n              // Store it for use later\n              groupElementMap[option.group] = groupElement;\n            }\n\n            addOptionElement(option, groupElement);\n\n          } else {\n\n            // This option is not in a group\n            addOptionElement(option, listFragment);\n          }\n        });\n\n        selectElement[0].appendChild(listFragment);\n\n        ngModelCtrl.$render();\n\n        // Check to see if the value has changed due to the update to the options\n        if (!ngModelCtrl.$isEmpty(previousValue)) {\n          var nextValue = selectCtrl.readValue();\n          var isNotPrimitive = ngOptions.trackBy || multiple;\n          if (isNotPrimitive ? !equals(previousValue, nextValue) : previousValue !== nextValue) {\n            ngModelCtrl.$setViewValue(nextValue);\n            ngModelCtrl.$render();\n          }\n        }\n\n      }\n  }\n\n  return {\n    restrict: 'A',\n    terminal: true,\n    require: ['select', 'ngModel'],\n    link: {\n      pre: function ngOptionsPreLink(scope, selectElement, attr, ctrls) {\n        // Deactivate the SelectController.register method to prevent\n        // option directives from accidentally registering themselves\n        // (and unwanted $destroy handlers etc.)\n        ctrls[0].registerOption = noop;\n      },\n      post: ngOptionsPostLink\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngPluralize\n * @restrict EA\n *\n * @description\n * `ngPluralize` is a directive that displays messages according to en-US localization rules.\n * These rules are bundled with angular.js, but can be overridden\n * (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive\n * by specifying the mappings between\n * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)\n * and the strings to be displayed.\n *\n * # Plural categories and explicit number rules\n * There are two\n * [plural categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html)\n * in Angular's default en-US locale: \"one\" and \"other\".\n *\n * While a plural category may match many numbers (for example, in en-US locale, \"other\" can match\n * any number that is not 1), an explicit number rule can only match one number. For example, the\n * explicit number rule for \"3\" matches the number 3. There are examples of plural categories\n * and explicit number rules throughout the rest of this documentation.\n *\n * # Configuring ngPluralize\n * You configure ngPluralize by providing 2 attributes: `count` and `when`.\n * You can also provide an optional attribute, `offset`.\n *\n * The value of the `count` attribute can be either a string or an {@link guide/expression\n * Angular expression}; these are evaluated on the current scope for its bound value.\n *\n * The `when` attribute specifies the mappings between plural categories and the actual\n * string to be displayed. The value of the attribute should be a JSON object.\n *\n * The following example shows how to configure ngPluralize:\n *\n * ```html\n * <ng-pluralize count=\"personCount\"\n                 when=\"{'0': 'Nobody is viewing.',\n *                      'one': '1 person is viewing.',\n *                      'other': '{} people are viewing.'}\">\n * </ng-pluralize>\n *```\n *\n * In the example, `\"0: Nobody is viewing.\"` is an explicit number rule. If you did not\n * specify this rule, 0 would be matched to the \"other\" category and \"0 people are viewing\"\n * would be shown instead of \"Nobody is viewing\". You can specify an explicit number rule for\n * other numbers, for example 12, so that instead of showing \"12 people are viewing\", you can\n * show \"a dozen people are viewing\".\n *\n * You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted\n * into pluralized strings. In the previous example, Angular will replace `{}` with\n * <span ng-non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder\n * for <span ng-non-bindable>{{numberExpression}}</span>.\n *\n * If no rule is defined for a category, then an empty string is displayed and a warning is generated.\n * Note that some locales define more categories than `one` and `other`. For example, fr-fr defines `few` and `many`.\n *\n * # Configuring ngPluralize with offset\n * The `offset` attribute allows further customization of pluralized text, which can result in\n * a better user experience. For example, instead of the message \"4 people are viewing this document\",\n * you might display \"John, Kate and 2 others are viewing this document\".\n * The offset attribute allows you to offset a number by any desired value.\n * Let's take a look at an example:\n *\n * ```html\n * <ng-pluralize count=\"personCount\" offset=2\n *               when=\"{'0': 'Nobody is viewing.',\n *                      '1': '{{person1}} is viewing.',\n *                      '2': '{{person1}} and {{person2}} are viewing.',\n *                      'one': '{{person1}}, {{person2}} and one other person are viewing.',\n *                      'other': '{{person1}}, {{person2}} and {} other people are viewing.'}\">\n * </ng-pluralize>\n * ```\n *\n * Notice that we are still using two plural categories(one, other), but we added\n * three explicit number rules 0, 1 and 2.\n * When one person, perhaps John, views the document, \"John is viewing\" will be shown.\n * When three people view the document, no explicit number rule is found, so\n * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category.\n * In this case, plural category 'one' is matched and \"John, Mary and one other person are viewing\"\n * is shown.\n *\n * Note that when you specify offsets, you must provide explicit number rules for\n * numbers from 0 up to and including the offset. If you use an offset of 3, for example,\n * you must provide explicit number rules for 0, 1, 2 and 3. You must also provide plural strings for\n * plural categories \"one\" and \"other\".\n *\n * @param {string|expression} count The variable to be bound to.\n * @param {string} when The mapping between plural category to its corresponding strings.\n * @param {number=} offset Offset to deduct from the total number.\n *\n * @example\n    <example module=\"pluralizeExample\" name=\"ng-pluralize\">\n      <file name=\"index.html\">\n        <script>\n          angular.module('pluralizeExample', [])\n            .controller('ExampleController', ['$scope', function($scope) {\n              $scope.person1 = 'Igor';\n              $scope.person2 = 'Misko';\n              $scope.personCount = 1;\n            }]);\n        </script>\n        <div ng-controller=\"ExampleController\">\n          <label>Person 1:<input type=\"text\" ng-model=\"person1\" value=\"Igor\" /></label><br/>\n          <label>Person 2:<input type=\"text\" ng-model=\"person2\" value=\"Misko\" /></label><br/>\n          <label>Number of People:<input type=\"text\" ng-model=\"personCount\" value=\"1\" /></label><br/>\n\n          <!--- Example with simple pluralization rules for en locale --->\n          Without Offset:\n          <ng-pluralize count=\"personCount\"\n                        when=\"{'0': 'Nobody is viewing.',\n                               'one': '1 person is viewing.',\n                               'other': '{} people are viewing.'}\">\n          </ng-pluralize><br>\n\n          <!--- Example with offset --->\n          With Offset(2):\n          <ng-pluralize count=\"personCount\" offset=2\n                        when=\"{'0': 'Nobody is viewing.',\n                               '1': '{{person1}} is viewing.',\n                               '2': '{{person1}} and {{person2}} are viewing.',\n                               'one': '{{person1}}, {{person2}} and one other person are viewing.',\n                               'other': '{{person1}}, {{person2}} and {} other people are viewing.'}\">\n          </ng-pluralize>\n        </div>\n      </file>\n      <file name=\"protractor.js\" type=\"protractor\">\n        it('should show correct pluralized string', function() {\n          var withoutOffset = element.all(by.css('ng-pluralize')).get(0);\n          var withOffset = element.all(by.css('ng-pluralize')).get(1);\n          var countInput = element(by.model('personCount'));\n\n          expect(withoutOffset.getText()).toEqual('1 person is viewing.');\n          expect(withOffset.getText()).toEqual('Igor is viewing.');\n\n          countInput.clear();\n          countInput.sendKeys('0');\n\n          expect(withoutOffset.getText()).toEqual('Nobody is viewing.');\n          expect(withOffset.getText()).toEqual('Nobody is viewing.');\n\n          countInput.clear();\n          countInput.sendKeys('2');\n\n          expect(withoutOffset.getText()).toEqual('2 people are viewing.');\n          expect(withOffset.getText()).toEqual('Igor and Misko are viewing.');\n\n          countInput.clear();\n          countInput.sendKeys('3');\n\n          expect(withoutOffset.getText()).toEqual('3 people are viewing.');\n          expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.');\n\n          countInput.clear();\n          countInput.sendKeys('4');\n\n          expect(withoutOffset.getText()).toEqual('4 people are viewing.');\n          expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.');\n        });\n        it('should show data-bound names', function() {\n          var withOffset = element.all(by.css('ng-pluralize')).get(1);\n          var personCount = element(by.model('personCount'));\n          var person1 = element(by.model('person1'));\n          var person2 = element(by.model('person2'));\n          personCount.clear();\n          personCount.sendKeys('4');\n          person1.clear();\n          person1.sendKeys('Di');\n          person2.clear();\n          person2.sendKeys('Vojta');\n          expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.');\n        });\n      </file>\n    </example>\n */\nvar ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale, $interpolate, $log) {\n  var BRACE = /{}/g,\n      IS_WHEN = /^when(Minus)?(.+)$/;\n\n  return {\n    link: function(scope, element, attr) {\n      var numberExp = attr.count,\n          whenExp = attr.$attr.when && element.attr(attr.$attr.when), // we have {{}} in attrs\n          offset = attr.offset || 0,\n          whens = scope.$eval(whenExp) || {},\n          whensExpFns = {},\n          startSymbol = $interpolate.startSymbol(),\n          endSymbol = $interpolate.endSymbol(),\n          braceReplacement = startSymbol + numberExp + '-' + offset + endSymbol,\n          watchRemover = angular.noop,\n          lastCount;\n\n      forEach(attr, function(expression, attributeName) {\n        var tmpMatch = IS_WHEN.exec(attributeName);\n        if (tmpMatch) {\n          var whenKey = (tmpMatch[1] ? '-' : '') + lowercase(tmpMatch[2]);\n          whens[whenKey] = element.attr(attr.$attr[attributeName]);\n        }\n      });\n      forEach(whens, function(expression, key) {\n        whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement));\n\n      });\n\n      scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {\n        var count = parseFloat(newVal);\n        var countIsNaN = isNumberNaN(count);\n\n        if (!countIsNaN && !(count in whens)) {\n          // If an explicit number rule such as 1, 2, 3... is defined, just use it.\n          // Otherwise, check it against pluralization rules in $locale service.\n          count = $locale.pluralCat(count - offset);\n        }\n\n        // If both `count` and `lastCount` are NaN, we don't need to re-register a watch.\n        // In JS `NaN !== NaN`, so we have to explicitly check.\n        if ((count !== lastCount) && !(countIsNaN && isNumberNaN(lastCount))) {\n          watchRemover();\n          var whenExpFn = whensExpFns[count];\n          if (isUndefined(whenExpFn)) {\n            if (newVal != null) {\n              $log.debug('ngPluralize: no rule defined for \\'' + count + '\\' in ' + whenExp);\n            }\n            watchRemover = noop;\n            updateElementText();\n          } else {\n            watchRemover = scope.$watch(whenExpFn, updateElementText);\n          }\n          lastCount = count;\n        }\n      });\n\n      function updateElementText(newText) {\n        element.text(newText || '');\n      }\n    }\n  };\n}];\n\n/* exported ngRepeatDirective */\n\n/**\n * @ngdoc directive\n * @name ngRepeat\n * @multiElement\n * @restrict A\n *\n * @description\n * The `ngRepeat` directive instantiates a template once per item from a collection. Each template\n * instance gets its own scope, where the given loop variable is set to the current collection item,\n * and `$index` is set to the item index or key.\n *\n * Special properties are exposed on the local scope of each template instance, including:\n *\n * | Variable  | Type            | Details                                                                     |\n * |-----------|-----------------|-----------------------------------------------------------------------------|\n * | `$index`  | {@type number}  | iterator offset of the repeated element (0..length-1)                       |\n * | `$first`  | {@type boolean} | true if the repeated element is first in the iterator.                      |\n * | `$middle` | {@type boolean} | true if the repeated element is between the first and last in the iterator. |\n * | `$last`   | {@type boolean} | true if the repeated element is last in the iterator.                       |\n * | `$even`   | {@type boolean} | true if the iterator position `$index` is even (otherwise false).           |\n * | `$odd`    | {@type boolean} | true if the iterator position `$index` is odd (otherwise false).            |\n *\n * <div class=\"alert alert-info\">\n *   Creating aliases for these properties is possible with {@link ng.directive:ngInit `ngInit`}.\n *   This may be useful when, for instance, nesting ngRepeats.\n * </div>\n *\n *\n * # Iterating over object properties\n *\n * It is possible to get `ngRepeat` to iterate over the properties of an object using the following\n * syntax:\n *\n * ```js\n * <div ng-repeat=\"(key, value) in myObj\"> ... </div>\n * ```\n *\n * However, there are a few limitations compared to array iteration:\n *\n * - The JavaScript specification does not define the order of keys\n *   returned for an object, so Angular relies on the order returned by the browser\n *   when running `for key in myObj`. Browsers generally follow the strategy of providing\n *   keys in the order in which they were defined, although there are exceptions when keys are deleted\n *   and reinstated. See the\n *   [MDN page on `delete` for more info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_notes).\n *\n * - `ngRepeat` will silently *ignore* object keys starting with `$`, because\n *   it's a prefix used by Angular for public (`$`) and private (`$$`) properties.\n *\n * - The built-in filters {@link ng.orderBy orderBy} and {@link ng.filter filter} do not work with\n *   objects, and will throw an error if used with one.\n *\n * If you are hitting any of these limitations, the recommended workaround is to convert your object into an array\n * that is sorted into the order that you prefer before providing it to `ngRepeat`. You could\n * do this with a filter such as [toArrayFilter](http://ngmodules.org/modules/angular-toArrayFilter)\n * or implement a `$watch` on the object yourself.\n *\n *\n * # Tracking and Duplicates\n *\n * `ngRepeat` uses {@link $rootScope.Scope#$watchCollection $watchCollection} to detect changes in\n * the collection. When a change happens, `ngRepeat` then makes the corresponding changes to the DOM:\n *\n * * When an item is added, a new instance of the template is added to the DOM.\n * * When an item is removed, its template instance is removed from the DOM.\n * * When items are reordered, their respective templates are reordered in the DOM.\n *\n * To minimize creation of DOM elements, `ngRepeat` uses a function\n * to \"keep track\" of all items in the collection and their corresponding DOM elements.\n * For example, if an item is added to the collection, `ngRepeat` will know that all other items\n * already have DOM elements, and will not re-render them.\n *\n * The default tracking function (which tracks items by their identity) does not allow\n * duplicate items in arrays. This is because when there are duplicates, it is not possible\n * to maintain a one-to-one mapping between collection items and DOM elements.\n *\n * If you do need to repeat duplicate items, you can substitute the default tracking behavior\n * with your own using the `track by` expression.\n *\n * For example, you may track items by the index of each item in the collection, using the\n * special scope property `$index`:\n * ```html\n *    <div ng-repeat=\"n in [42, 42, 43, 43] track by $index\">\n *      {{n}}\n *    </div>\n * ```\n *\n * You may also use arbitrary expressions in `track by`, including references to custom functions\n * on the scope:\n * ```html\n *    <div ng-repeat=\"n in [42, 42, 43, 43] track by myTrackingFunction(n)\">\n *      {{n}}\n *    </div>\n * ```\n *\n * <div class=\"alert alert-success\">\n * If you are working with objects that have a unique identifier property, you should track\n * by this identifier instead of the object instance. Should you reload your data later, `ngRepeat`\n * will not have to rebuild the DOM elements for items it has already rendered, even if the\n * JavaScript objects in the collection have been substituted for new ones. For large collections,\n * this significantly improves rendering performance. If you don't have a unique identifier,\n * `track by $index` can also provide a performance boost.\n * </div>\n *\n * ```html\n *    <div ng-repeat=\"model in collection track by model.id\">\n *      {{model.name}}\n *    </div>\n * ```\n *\n * <br />\n * <div class=\"alert alert-warning\">\n * Avoid using `track by $index` when the repeated template contains\n * {@link guide/expression#one-time-binding one-time bindings}. In such cases, the `nth` DOM\n * element will always be matched with the `nth` item of the array, so the bindings on that element\n * will not be updated even when the corresponding item changes, essentially causing the view to get\n * out-of-sync with the underlying data.\n * </div>\n *\n * When no `track by` expression is provided, it is equivalent to tracking by the built-in\n * `$id` function, which tracks items by their identity:\n * ```html\n *    <div ng-repeat=\"obj in collection track by $id(obj)\">\n *      {{obj.prop}}\n *    </div>\n * ```\n *\n * <br />\n * <div class=\"alert alert-warning\">\n * **Note:** `track by` must always be the last expression:\n * </div>\n * ```\n *    <div ng-repeat=\"model in collection | orderBy: 'id' as filtered_result track by model.id\">\n *      {{model.name}}\n *    </div>\n * ```\n *\n *\n * # Special repeat start and end points\n * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending\n * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.\n * The **ng-repeat-start** directive works the same as **ng-repeat**, but will repeat all the HTML code (including the tag it's defined on)\n * up to and including the ending HTML tag where **ng-repeat-end** is placed.\n *\n * The example below makes use of this feature:\n * ```html\n *   <header ng-repeat-start=\"item in items\">\n *     Header {{ item }}\n *   </header>\n *   <div class=\"body\">\n *     Body {{ item }}\n *   </div>\n *   <footer ng-repeat-end>\n *     Footer {{ item }}\n *   </footer>\n * ```\n *\n * And with an input of {@type ['A','B']} for the items variable in the example above, the output will evaluate to:\n * ```html\n *   <header>\n *     Header A\n *   </header>\n *   <div class=\"body\">\n *     Body A\n *   </div>\n *   <footer>\n *     Footer A\n *   </footer>\n *   <header>\n *     Header B\n *   </header>\n *   <div class=\"body\">\n *     Body B\n *   </div>\n *   <footer>\n *     Footer B\n *   </footer>\n * ```\n *\n * The custom start and end points for ngRepeat also support all other HTML directive syntax flavors provided in AngularJS (such\n * as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**).\n *\n * @animations\n * | Animation                        | Occurs                              |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#enter enter} | when a new item is added to the list or when an item is revealed after a filter |\n * | {@link ng.$animate#leave leave} | when an item is removed from the list or when an item is filtered out |\n * | {@link ng.$animate#move move } | when an adjacent item is filtered out causing a reorder or when the item contents are reordered |\n *\n * See the example below for defining CSS animations with ngRepeat.\n *\n * @element ANY\n * @scope\n * @priority 1000\n * @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. These\n *   formats are currently supported:\n *\n *   * `variable in expression` – where variable is the user defined loop variable and `expression`\n *     is a scope expression giving the collection to enumerate.\n *\n *     For example: `album in artist.albums`.\n *\n *   * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,\n *     and `expression` is the scope expression giving the collection to enumerate.\n *\n *     For example: `(name, age) in {'adam':10, 'amalie':12}`.\n *\n *   * `variable in expression track by tracking_expression` – You can also provide an optional tracking expression\n *     which can be used to associate the objects in the collection with the DOM elements. If no tracking expression\n *     is specified, ng-repeat associates elements by identity. It is an error to have\n *     more than one tracking expression value resolve to the same key. (This would mean that two distinct objects are\n *     mapped to the same DOM element, which is not possible.)\n *\n *     Note that the tracking expression must come last, after any filters, and the alias expression.\n *\n *     For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements\n *     will be associated by item identity in the array.\n *\n *     For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique\n *     `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements\n *     with the corresponding item in the array by identity. Moving the same object in array would move the DOM\n *     element in the same way in the DOM.\n *\n *     For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this\n *     case the object identity does not matter. Two objects are considered equivalent as long as their `id`\n *     property is same.\n *\n *     For example: `item in items | filter:searchText track by item.id` is a pattern that might be used to apply a filter\n *     to items in conjunction with a tracking expression.\n *\n *   * `variable in expression as alias_expression` – You can also provide an optional alias expression which will then store the\n *     intermediate results of the repeater after the filters have been applied. Typically this is used to render a special message\n *     when a filter is active on the repeater, but the filtered result set is empty.\n *\n *     For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after\n *     the items have been processed through the filter.\n *\n *     Please note that `as [variable name] is not an operator but rather a part of ngRepeat micro-syntax so it can be used only at the end\n *     (and not as operator, inside an expression).\n *\n *     For example: `item in items | filter : x | orderBy : order | limitTo : limit as results` .\n *\n * @example\n * This example uses `ngRepeat` to display a list of people. A filter is used to restrict the displayed\n * results by name or by age. New (entering) and removed (leaving) items are animated.\n  <example module=\"ngRepeat\" name=\"ngRepeat\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-repeat\">\n    <file name=\"index.html\">\n      <div ng-controller=\"repeatController\">\n        I have {{friends.length}} friends. They are:\n        <input type=\"search\" ng-model=\"q\" placeholder=\"filter friends...\" aria-label=\"filter friends\" />\n        <ul class=\"example-animate-container\">\n          <li class=\"animate-repeat\" ng-repeat=\"friend in friends | filter:q as results\">\n            [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.\n          </li>\n          <li class=\"animate-repeat\" ng-if=\"results.length === 0\">\n            <strong>No results found...</strong>\n          </li>\n        </ul>\n      </div>\n    </file>\n    <file name=\"script.js\">\n      angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {\n        $scope.friends = [\n          {name:'John', age:25, gender:'boy'},\n          {name:'Jessie', age:30, gender:'girl'},\n          {name:'Johanna', age:28, gender:'girl'},\n          {name:'Joy', age:15, gender:'girl'},\n          {name:'Mary', age:28, gender:'girl'},\n          {name:'Peter', age:95, gender:'boy'},\n          {name:'Sebastian', age:50, gender:'boy'},\n          {name:'Erika', age:27, gender:'girl'},\n          {name:'Patrick', age:40, gender:'boy'},\n          {name:'Samantha', age:60, gender:'girl'}\n        ];\n      });\n    </file>\n    <file name=\"animations.css\">\n      .example-animate-container {\n        background:white;\n        border:1px solid black;\n        list-style:none;\n        margin:0;\n        padding:0 10px;\n      }\n\n      .animate-repeat {\n        line-height:30px;\n        list-style:none;\n        box-sizing:border-box;\n      }\n\n      .animate-repeat.ng-move,\n      .animate-repeat.ng-enter,\n      .animate-repeat.ng-leave {\n        transition:all linear 0.5s;\n      }\n\n      .animate-repeat.ng-leave.ng-leave-active,\n      .animate-repeat.ng-move,\n      .animate-repeat.ng-enter {\n        opacity:0;\n        max-height:0;\n      }\n\n      .animate-repeat.ng-leave,\n      .animate-repeat.ng-move.ng-move-active,\n      .animate-repeat.ng-enter.ng-enter-active {\n        opacity:1;\n        max-height:30px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var friends = element.all(by.repeater('friend in friends'));\n\n      it('should render initial data set', function() {\n        expect(friends.count()).toBe(10);\n        expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.');\n        expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.');\n        expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.');\n        expect(element(by.binding('friends.length')).getText())\n            .toMatch(\"I have 10 friends. They are:\");\n      });\n\n       it('should update repeater when filter predicate changes', function() {\n         expect(friends.count()).toBe(10);\n\n         element(by.model('q')).sendKeys('ma');\n\n         expect(friends.count()).toBe(2);\n         expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.');\n         expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.');\n       });\n      </file>\n    </example>\n */\nvar ngRepeatDirective = ['$parse', '$animate', '$compile', function($parse, $animate, $compile) {\n  var NG_REMOVED = '$$NG_REMOVED';\n  var ngRepeatMinErr = minErr('ngRepeat');\n\n  var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength) {\n    // TODO(perf): generate setters to shave off ~40ms or 1-1.5%\n    scope[valueIdentifier] = value;\n    if (keyIdentifier) scope[keyIdentifier] = key;\n    scope.$index = index;\n    scope.$first = (index === 0);\n    scope.$last = (index === (arrayLength - 1));\n    scope.$middle = !(scope.$first || scope.$last);\n    // eslint-disable-next-line no-bitwise\n    scope.$odd = !(scope.$even = (index & 1) === 0);\n  };\n\n  var getBlockStart = function(block) {\n    return block.clone[0];\n  };\n\n  var getBlockEnd = function(block) {\n    return block.clone[block.clone.length - 1];\n  };\n\n\n  return {\n    restrict: 'A',\n    multiElement: true,\n    transclude: 'element',\n    priority: 1000,\n    terminal: true,\n    $$tlb: true,\n    compile: function ngRepeatCompile($element, $attr) {\n      var expression = $attr.ngRepeat;\n      var ngRepeatEndComment = $compile.$$createComment('end ngRepeat', expression);\n\n      var match = expression.match(/^\\s*([\\s\\S]+?)\\s+in\\s+([\\s\\S]+?)(?:\\s+as\\s+([\\s\\S]+?))?(?:\\s+track\\s+by\\s+([\\s\\S]+?))?\\s*$/);\n\n      if (!match) {\n        throw ngRepeatMinErr('iexp', 'Expected expression in form of \\'_item_ in _collection_[ track by _id_]\\' but got \\'{0}\\'.',\n            expression);\n      }\n\n      var lhs = match[1];\n      var rhs = match[2];\n      var aliasAs = match[3];\n      var trackByExp = match[4];\n\n      match = lhs.match(/^(?:(\\s*[$\\w]+)|\\(\\s*([$\\w]+)\\s*,\\s*([$\\w]+)\\s*\\))$/);\n\n      if (!match) {\n        throw ngRepeatMinErr('iidexp', '\\'_item_\\' in \\'_item_ in _collection_\\' should be an identifier or \\'(_key_, _value_)\\' expression, but got \\'{0}\\'.',\n            lhs);\n      }\n      var valueIdentifier = match[3] || match[1];\n      var keyIdentifier = match[2];\n\n      if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) ||\n          /^(null|undefined|this|\\$index|\\$first|\\$middle|\\$last|\\$even|\\$odd|\\$parent|\\$root|\\$id)$/.test(aliasAs))) {\n        throw ngRepeatMinErr('badident', 'alias \\'{0}\\' is invalid --- must be a valid JS identifier which is not a reserved name.',\n          aliasAs);\n      }\n\n      var trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn;\n      var hashFnLocals = {$id: hashKey};\n\n      if (trackByExp) {\n        trackByExpGetter = $parse(trackByExp);\n      } else {\n        trackByIdArrayFn = function(key, value) {\n          return hashKey(value);\n        };\n        trackByIdObjFn = function(key) {\n          return key;\n        };\n      }\n\n      return function ngRepeatLink($scope, $element, $attr, ctrl, $transclude) {\n\n        if (trackByExpGetter) {\n          trackByIdExpFn = function(key, value, index) {\n            // assign key, value, and $index to the locals so that they can be used in hash functions\n            if (keyIdentifier) hashFnLocals[keyIdentifier] = key;\n            hashFnLocals[valueIdentifier] = value;\n            hashFnLocals.$index = index;\n            return trackByExpGetter($scope, hashFnLocals);\n          };\n        }\n\n        // Store a list of elements from previous run. This is a hash where key is the item from the\n        // iterator, and the value is objects with following properties.\n        //   - scope: bound scope\n        //   - element: previous element.\n        //   - index: position\n        //\n        // We are using no-proto object so that we don't need to guard against inherited props via\n        // hasOwnProperty.\n        var lastBlockMap = createMap();\n\n        //watch props\n        $scope.$watchCollection(rhs, function ngRepeatAction(collection) {\n          var index, length,\n              previousNode = $element[0],     // node that cloned nodes should be inserted after\n                                              // initialized to the comment node anchor\n              nextNode,\n              // Same as lastBlockMap but it has the current state. It will become the\n              // lastBlockMap on the next iteration.\n              nextBlockMap = createMap(),\n              collectionLength,\n              key, value, // key/value of iteration\n              trackById,\n              trackByIdFn,\n              collectionKeys,\n              block,       // last object information {scope, element, id}\n              nextBlockOrder,\n              elementsToRemove;\n\n          if (aliasAs) {\n            $scope[aliasAs] = collection;\n          }\n\n          if (isArrayLike(collection)) {\n            collectionKeys = collection;\n            trackByIdFn = trackByIdExpFn || trackByIdArrayFn;\n          } else {\n            trackByIdFn = trackByIdExpFn || trackByIdObjFn;\n            // if object, extract keys, in enumeration order, unsorted\n            collectionKeys = [];\n            for (var itemKey in collection) {\n              if (hasOwnProperty.call(collection, itemKey) && itemKey.charAt(0) !== '$') {\n                collectionKeys.push(itemKey);\n              }\n            }\n          }\n\n          collectionLength = collectionKeys.length;\n          nextBlockOrder = new Array(collectionLength);\n\n          // locate existing items\n          for (index = 0; index < collectionLength; index++) {\n            key = (collection === collectionKeys) ? index : collectionKeys[index];\n            value = collection[key];\n            trackById = trackByIdFn(key, value, index);\n            if (lastBlockMap[trackById]) {\n              // found previously seen block\n              block = lastBlockMap[trackById];\n              delete lastBlockMap[trackById];\n              nextBlockMap[trackById] = block;\n              nextBlockOrder[index] = block;\n            } else if (nextBlockMap[trackById]) {\n              // if collision detected. restore lastBlockMap and throw an error\n              forEach(nextBlockOrder, function(block) {\n                if (block && block.scope) lastBlockMap[block.id] = block;\n              });\n              throw ngRepeatMinErr('dupes',\n                  'Duplicates in a repeater are not allowed. Use \\'track by\\' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}',\n                  expression, trackById, value);\n            } else {\n              // new never before seen block\n              nextBlockOrder[index] = {id: trackById, scope: undefined, clone: undefined};\n              nextBlockMap[trackById] = true;\n            }\n          }\n\n          // remove leftover items\n          for (var blockKey in lastBlockMap) {\n            block = lastBlockMap[blockKey];\n            elementsToRemove = getBlockNodes(block.clone);\n            $animate.leave(elementsToRemove);\n            if (elementsToRemove[0].parentNode) {\n              // if the element was not removed yet because of pending animation, mark it as deleted\n              // so that we can ignore it later\n              for (index = 0, length = elementsToRemove.length; index < length; index++) {\n                elementsToRemove[index][NG_REMOVED] = true;\n              }\n            }\n            block.scope.$destroy();\n          }\n\n          // we are not using forEach for perf reasons (trying to avoid #call)\n          for (index = 0; index < collectionLength; index++) {\n            key = (collection === collectionKeys) ? index : collectionKeys[index];\n            value = collection[key];\n            block = nextBlockOrder[index];\n\n            if (block.scope) {\n              // if we have already seen this object, then we need to reuse the\n              // associated scope/element\n\n              nextNode = previousNode;\n\n              // skip nodes that are already pending removal via leave animation\n              do {\n                nextNode = nextNode.nextSibling;\n              } while (nextNode && nextNode[NG_REMOVED]);\n\n              if (getBlockStart(block) !== nextNode) {\n                // existing item which got moved\n                $animate.move(getBlockNodes(block.clone), null, previousNode);\n              }\n              previousNode = getBlockEnd(block);\n              updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);\n            } else {\n              // new item which we don't know about\n              $transclude(function ngRepeatTransclude(clone, scope) {\n                block.scope = scope;\n                // http://jsperf.com/clone-vs-createcomment\n                var endNode = ngRepeatEndComment.cloneNode(false);\n                clone[clone.length++] = endNode;\n\n                $animate.enter(clone, null, previousNode);\n                previousNode = endNode;\n                // Note: We only need the first/last node of the cloned nodes.\n                // However, we need to keep the reference to the jqlite wrapper as it might be changed later\n                // by a directive with templateUrl when its template arrives.\n                block.clone = clone;\n                nextBlockMap[block.id] = block;\n                updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);\n              });\n            }\n          }\n          lastBlockMap = nextBlockMap;\n        });\n      };\n    }\n  };\n}];\n\nvar NG_HIDE_CLASS = 'ng-hide';\nvar NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';\n/**\n * @ngdoc directive\n * @name ngShow\n * @multiElement\n *\n * @description\n * The `ngShow` directive shows or hides the given HTML element based on the expression provided to\n * the `ngShow` attribute.\n *\n * The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.\n * The `.ng-hide` CSS class is predefined in AngularJS and sets the display style to none (using an\n * `!important` flag). For CSP mode please add `angular-csp.css` to your HTML file (see\n * {@link ng.directive:ngCsp ngCsp}).\n *\n * ```html\n * <!-- when $scope.myValue is truthy (element is visible) -->\n * <div ng-show=\"myValue\"></div>\n *\n * <!-- when $scope.myValue is falsy (element is hidden) -->\n * <div ng-show=\"myValue\" class=\"ng-hide\"></div>\n * ```\n *\n * When the `ngShow` expression evaluates to a falsy value then the `.ng-hide` CSS class is added\n * to the class attribute on the element causing it to become hidden. When truthy, the `.ng-hide`\n * CSS class is removed from the element causing the element not to appear hidden.\n *\n * ## Why is `!important` used?\n *\n * You may be wondering why `!important` is used for the `.ng-hide` CSS class. This is because the\n * `.ng-hide` selector can be easily overridden by heavier selectors. For example, something as\n * simple as changing the display style on a HTML list item would make hidden elements appear\n * visible. This also becomes a bigger issue when dealing with CSS frameworks.\n *\n * By using `!important`, the show and hide behavior will work as expected despite any clash between\n * CSS selector specificity (when `!important` isn't used with any conflicting styles). If a\n * developer chooses to override the styling to change how to hide an element then it is just a\n * matter of using `!important` in their own CSS code.\n *\n * ### Overriding `.ng-hide`\n *\n * By default, the `.ng-hide` class will style the element with `display: none !important`. If you\n * wish to change the hide behavior with `ngShow`/`ngHide`, you can simply overwrite the styles for\n * the `.ng-hide` CSS class. Note that the selector that needs to be used is actually\n * `.ng-hide:not(.ng-hide-animate)` to cope with extra animation classes that can be added.\n *\n * ```css\n * .ng-hide:not(.ng-hide-animate) {\n *   /&#42; These are just alternative ways of hiding an element &#42;/\n *   display: block!important;\n *   position: absolute;\n *   top: -9999px;\n *   left: -9999px;\n * }\n * ```\n *\n * By default you don't need to override anything in CSS and the animations will work around the\n * display style.\n *\n * ## A note about animations with `ngShow`\n *\n * Animations in `ngShow`/`ngHide` work with the show and hide events that are triggered when the\n * directive expression is true and false. This system works like the animation system present with\n * `ngClass` except that you must also include the `!important` flag to override the display\n * property so that the elements are not actually hidden during the animation.\n *\n * ```css\n * /&#42; A working example can be found at the bottom of this page. &#42;/\n * .my-element.ng-hide-add, .my-element.ng-hide-remove {\n *   transition: all 0.5s linear;\n * }\n *\n * .my-element.ng-hide-add { ... }\n * .my-element.ng-hide-add.ng-hide-add-active { ... }\n * .my-element.ng-hide-remove { ... }\n * .my-element.ng-hide-remove.ng-hide-remove-active { ... }\n * ```\n *\n * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display property\n * to block during animation states - ngAnimate will automatically handle the style toggling for you.\n *\n * @animations\n * | Animation                                           | Occurs                                                                                                        |\n * |-----------------------------------------------------|---------------------------------------------------------------------------------------------------------------|\n * | {@link $animate#addClass addClass} `.ng-hide`       | After the `ngShow` expression evaluates to a non truthy value and just before the contents are set to hidden. |\n * | {@link $animate#removeClass removeClass} `.ng-hide` | After the `ngShow` expression evaluates to a truthy value and just before contents are set to visible.        |\n *\n * @element ANY\n * @param {expression} ngShow If the {@link guide/expression expression} is truthy/falsy then the\n *                            element is shown/hidden respectively.\n *\n * @example\n * A simple example, animating the element's opacity:\n *\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-show-simple\">\n    <file name=\"index.html\">\n      Show: <input type=\"checkbox\" ng-model=\"checked\" aria-label=\"Toggle ngShow\"><br />\n      <div class=\"check-element animate-show-hide\" ng-show=\"checked\">\n        I show up when your checkbox is checked.\n      </div>\n    </file>\n    <file name=\"animations.css\">\n      .animate-show-hide.ng-hide {\n        opacity: 0;\n      }\n\n      .animate-show-hide.ng-hide-add,\n      .animate-show-hide.ng-hide-remove {\n        transition: all linear 0.5s;\n      }\n\n      .check-element {\n        border: 1px solid black;\n        opacity: 1;\n        padding: 10px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should check ngShow', function() {\n        var checkbox = element(by.model('checked'));\n        var checkElem = element(by.css('.check-element'));\n\n        expect(checkElem.isDisplayed()).toBe(false);\n        checkbox.click();\n        expect(checkElem.isDisplayed()).toBe(true);\n      });\n    </file>\n  </example>\n *\n * <hr />\n * @example\n * A more complex example, featuring different show/hide animations:\n *\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-show-complex\">\n    <file name=\"index.html\">\n      Show: <input type=\"checkbox\" ng-model=\"checked\" aria-label=\"Toggle ngShow\"><br />\n      <div class=\"check-element funky-show-hide\" ng-show=\"checked\">\n        I show up when your checkbox is checked.\n      </div>\n    </file>\n    <file name=\"animations.css\">\n      body {\n        overflow: hidden;\n        perspective: 1000px;\n      }\n\n      .funky-show-hide.ng-hide-add {\n        transform: rotateZ(0);\n        transform-origin: right;\n        transition: all 0.5s ease-in-out;\n      }\n\n      .funky-show-hide.ng-hide-add.ng-hide-add-active {\n        transform: rotateZ(-135deg);\n      }\n\n      .funky-show-hide.ng-hide-remove {\n        transform: rotateY(90deg);\n        transform-origin: left;\n        transition: all 0.5s ease;\n      }\n\n      .funky-show-hide.ng-hide-remove.ng-hide-remove-active {\n        transform: rotateY(0);\n      }\n\n      .check-element {\n        border: 1px solid black;\n        opacity: 1;\n        padding: 10px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should check ngShow', function() {\n        var checkbox = element(by.model('checked'));\n        var checkElem = element(by.css('.check-element'));\n\n        expect(checkElem.isDisplayed()).toBe(false);\n        checkbox.click();\n        expect(checkElem.isDisplayed()).toBe(true);\n      });\n    </file>\n  </example>\n */\nvar ngShowDirective = ['$animate', function($animate) {\n  return {\n    restrict: 'A',\n    multiElement: true,\n    link: function(scope, element, attr) {\n      scope.$watch(attr.ngShow, function ngShowWatchAction(value) {\n        // we're adding a temporary, animation-specific class for ng-hide since this way\n        // we can control when the element is actually displayed on screen without having\n        // to have a global/greedy CSS selector that breaks when other animations are run.\n        // Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845\n        $animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {\n          tempClasses: NG_HIDE_IN_PROGRESS_CLASS\n        });\n      });\n    }\n  };\n}];\n\n\n/**\n * @ngdoc directive\n * @name ngHide\n * @multiElement\n *\n * @description\n * The `ngHide` directive shows or hides the given HTML element based on the expression provided to\n * the `ngHide` attribute.\n *\n * The element is shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.\n * The `.ng-hide` CSS class is predefined in AngularJS and sets the display style to none (using an\n * `!important` flag). For CSP mode please add `angular-csp.css` to your HTML file (see\n * {@link ng.directive:ngCsp ngCsp}).\n *\n * ```html\n * <!-- when $scope.myValue is truthy (element is hidden) -->\n * <div ng-hide=\"myValue\" class=\"ng-hide\"></div>\n *\n * <!-- when $scope.myValue is falsy (element is visible) -->\n * <div ng-hide=\"myValue\"></div>\n * ```\n *\n * When the `ngHide` expression evaluates to a truthy value then the `.ng-hide` CSS class is added\n * to the class attribute on the element causing it to become hidden. When falsy, the `.ng-hide`\n * CSS class is removed from the element causing the element not to appear hidden.\n *\n * ## Why is `!important` used?\n *\n * You may be wondering why `!important` is used for the `.ng-hide` CSS class. This is because the\n * `.ng-hide` selector can be easily overridden by heavier selectors. For example, something as\n * simple as changing the display style on a HTML list item would make hidden elements appear\n * visible. This also becomes a bigger issue when dealing with CSS frameworks.\n *\n * By using `!important`, the show and hide behavior will work as expected despite any clash between\n * CSS selector specificity (when `!important` isn't used with any conflicting styles). If a\n * developer chooses to override the styling to change how to hide an element then it is just a\n * matter of using `!important` in their own CSS code.\n *\n * ### Overriding `.ng-hide`\n *\n * By default, the `.ng-hide` class will style the element with `display: none !important`. If you\n * wish to change the hide behavior with `ngShow`/`ngHide`, you can simply overwrite the styles for\n * the `.ng-hide` CSS class. Note that the selector that needs to be used is actually\n * `.ng-hide:not(.ng-hide-animate)` to cope with extra animation classes that can be added.\n *\n * ```css\n * .ng-hide:not(.ng-hide-animate) {\n *   /&#42; These are just alternative ways of hiding an element &#42;/\n *   display: block!important;\n *   position: absolute;\n *   top: -9999px;\n *   left: -9999px;\n * }\n * ```\n *\n * By default you don't need to override in CSS anything and the animations will work around the\n * display style.\n *\n * ## A note about animations with `ngHide`\n *\n * Animations in `ngShow`/`ngHide` work with the show and hide events that are triggered when the\n * directive expression is true and false. This system works like the animation system present with\n * `ngClass` except that you must also include the `!important` flag to override the display\n * property so that the elements are not actually hidden during the animation.\n *\n * ```css\n * /&#42; A working example can be found at the bottom of this page. &#42;/\n * .my-element.ng-hide-add, .my-element.ng-hide-remove {\n *   transition: all 0.5s linear;\n * }\n *\n * .my-element.ng-hide-add { ... }\n * .my-element.ng-hide-add.ng-hide-add-active { ... }\n * .my-element.ng-hide-remove { ... }\n * .my-element.ng-hide-remove.ng-hide-remove-active { ... }\n * ```\n *\n * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display property\n * to block during animation states - ngAnimate will automatically handle the style toggling for you.\n *\n * @animations\n * | Animation                                           | Occurs                                                                                                     |\n * |-----------------------------------------------------|------------------------------------------------------------------------------------------------------------|\n * | {@link $animate#addClass addClass} `.ng-hide`       | After the `ngHide` expression evaluates to a truthy value and just before the contents are set to hidden.  |\n * | {@link $animate#removeClass removeClass} `.ng-hide` | After the `ngHide` expression evaluates to a non truthy value and just before contents are set to visible. |\n *\n *\n * @element ANY\n * @param {expression} ngHide If the {@link guide/expression expression} is truthy/falsy then the\n *                            element is hidden/shown respectively.\n *\n * @example\n * A simple example, animating the element's opacity:\n *\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-hide-simple\">\n    <file name=\"index.html\">\n      Hide: <input type=\"checkbox\" ng-model=\"checked\" aria-label=\"Toggle ngHide\"><br />\n      <div class=\"check-element animate-show-hide\" ng-hide=\"checked\">\n        I hide when your checkbox is checked.\n      </div>\n    </file>\n    <file name=\"animations.css\">\n      .animate-show-hide.ng-hide {\n        opacity: 0;\n      }\n\n      .animate-show-hide.ng-hide-add,\n      .animate-show-hide.ng-hide-remove {\n        transition: all linear 0.5s;\n      }\n\n      .check-element {\n        border: 1px solid black;\n        opacity: 1;\n        padding: 10px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should check ngHide', function() {\n        var checkbox = element(by.model('checked'));\n        var checkElem = element(by.css('.check-element'));\n\n        expect(checkElem.isDisplayed()).toBe(true);\n        checkbox.click();\n        expect(checkElem.isDisplayed()).toBe(false);\n      });\n    </file>\n  </example>\n *\n * <hr />\n * @example\n * A more complex example, featuring different show/hide animations:\n *\n  <example module=\"ngAnimate\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-hide-complex\">\n    <file name=\"index.html\">\n      Hide: <input type=\"checkbox\" ng-model=\"checked\" aria-label=\"Toggle ngHide\"><br />\n      <div class=\"check-element funky-show-hide\" ng-hide=\"checked\">\n        I hide when your checkbox is checked.\n      </div>\n    </file>\n    <file name=\"animations.css\">\n      body {\n        overflow: hidden;\n        perspective: 1000px;\n      }\n\n      .funky-show-hide.ng-hide-add {\n        transform: rotateZ(0);\n        transform-origin: right;\n        transition: all 0.5s ease-in-out;\n      }\n\n      .funky-show-hide.ng-hide-add.ng-hide-add-active {\n        transform: rotateZ(-135deg);\n      }\n\n      .funky-show-hide.ng-hide-remove {\n        transform: rotateY(90deg);\n        transform-origin: left;\n        transition: all 0.5s ease;\n      }\n\n      .funky-show-hide.ng-hide-remove.ng-hide-remove-active {\n        transform: rotateY(0);\n      }\n\n      .check-element {\n        border: 1px solid black;\n        opacity: 1;\n        padding: 10px;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should check ngHide', function() {\n        var checkbox = element(by.model('checked'));\n        var checkElem = element(by.css('.check-element'));\n\n        expect(checkElem.isDisplayed()).toBe(true);\n        checkbox.click();\n        expect(checkElem.isDisplayed()).toBe(false);\n      });\n    </file>\n  </example>\n */\nvar ngHideDirective = ['$animate', function($animate) {\n  return {\n    restrict: 'A',\n    multiElement: true,\n    link: function(scope, element, attr) {\n      scope.$watch(attr.ngHide, function ngHideWatchAction(value) {\n        // The comment inside of the ngShowDirective explains why we add and\n        // remove a temporary class for the show/hide animation\n        $animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, {\n          tempClasses: NG_HIDE_IN_PROGRESS_CLASS\n        });\n      });\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngStyle\n * @restrict AC\n *\n * @description\n * The `ngStyle` directive allows you to set CSS style on an HTML element conditionally.\n *\n * @knownIssue\n * You should not use {@link guide/interpolation interpolation} in the value of the `style`\n * attribute, when using the `ngStyle` directive on the same element.\n * See {@link guide/interpolation#known-issues here} for more info.\n *\n * @element ANY\n * @param {expression} ngStyle\n *\n * {@link guide/expression Expression} which evals to an\n * object whose keys are CSS style names and values are corresponding values for those CSS\n * keys.\n *\n * Since some CSS style names are not valid keys for an object, they must be quoted.\n * See the 'background-color' style in the example below.\n *\n * @example\n   <example name=\"ng-style\">\n     <file name=\"index.html\">\n        <input type=\"button\" value=\"set color\" ng-click=\"myStyle={color:'red'}\">\n        <input type=\"button\" value=\"set background\" ng-click=\"myStyle={'background-color':'blue'}\">\n        <input type=\"button\" value=\"clear\" ng-click=\"myStyle={}\">\n        <br/>\n        <span ng-style=\"myStyle\">Sample Text</span>\n        <pre>myStyle={{myStyle}}</pre>\n     </file>\n     <file name=\"style.css\">\n       span {\n         color: black;\n       }\n     </file>\n     <file name=\"protractor.js\" type=\"protractor\">\n       var colorSpan = element(by.css('span'));\n\n       it('should check ng-style', function() {\n         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');\n         element(by.css('input[value=\\'set color\\']')).click();\n         expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');\n         element(by.css('input[value=clear]')).click();\n         expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');\n       });\n     </file>\n   </example>\n */\nvar ngStyleDirective = ngDirective(function(scope, element, attr) {\n  scope.$watch(attr.ngStyle, function ngStyleWatchAction(newStyles, oldStyles) {\n    if (oldStyles && (newStyles !== oldStyles)) {\n      forEach(oldStyles, function(val, style) { element.css(style, '');});\n    }\n    if (newStyles) element.css(newStyles);\n  }, true);\n});\n\n/**\n * @ngdoc directive\n * @name ngSwitch\n * @restrict EA\n *\n * @description\n * The `ngSwitch` directive is used to conditionally swap DOM structure on your template based on a scope expression.\n * Elements within `ngSwitch` but without `ngSwitchWhen` or `ngSwitchDefault` directives will be preserved at the location\n * as specified in the template.\n *\n * The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it\n * from the template cache), `ngSwitch` simply chooses one of the nested elements and makes it visible based on which element\n * matches the value obtained from the evaluated expression. In other words, you define a container element\n * (where you place the directive), place an expression on the **`on=\"...\"` attribute**\n * (or the **`ng-switch=\"...\"` attribute**), define any inner elements inside of the directive and place\n * a when attribute per element. The when attribute is used to inform ngSwitch which element to display when the on\n * expression is evaluated. If a matching expression is not found via a when attribute then an element with the default\n * attribute is displayed.\n *\n * <div class=\"alert alert-info\">\n * Be aware that the attribute values to match against cannot be expressions. They are interpreted\n * as literal string values to match against.\n * For example, **`ng-switch-when=\"someVal\"`** will match against the string `\"someVal\"` not against the\n * value of the expression `$scope.someVal`.\n * </div>\n\n * @animations\n * | Animation                        | Occurs                              |\n * |----------------------------------|-------------------------------------|\n * | {@link ng.$animate#enter enter}  | after the ngSwitch contents change and the matched child element is placed inside the container |\n * | {@link ng.$animate#leave leave}  | after the ngSwitch contents change and just before the former contents are removed from the DOM |\n *\n * @usage\n *\n * ```\n * <ANY ng-switch=\"expression\">\n *   <ANY ng-switch-when=\"matchValue1\">...</ANY>\n *   <ANY ng-switch-when=\"matchValue2\">...</ANY>\n *   <ANY ng-switch-default>...</ANY>\n * </ANY>\n * ```\n *\n *\n * @scope\n * @priority 1200\n * @param {*} ngSwitch|on expression to match against <code>ng-switch-when</code>.\n * On child elements add:\n *\n * * `ngSwitchWhen`: the case statement to match against. If match then this\n *   case will be displayed. If the same match appears multiple times, all the\n *   elements will be displayed. It is possible to associate multiple values to\n *   the same `ngSwitchWhen` by defining the optional attribute\n *   `ngSwitchWhenSeparator`. The separator will be used to split the value of\n *   the `ngSwitchWhen` attribute into multiple tokens, and the element will show\n *   if any of the `ngSwitch` evaluates to any of these tokens.\n * * `ngSwitchDefault`: the default case when no other case match. If there\n *   are multiple default cases, all of them will be displayed when no other\n *   case match.\n *\n *\n * @example\n  <example module=\"switchExample\" deps=\"angular-animate.js\" animations=\"true\" name=\"ng-switch\">\n    <file name=\"index.html\">\n      <div ng-controller=\"ExampleController\">\n        <select ng-model=\"selection\" ng-options=\"item for item in items\">\n        </select>\n        <code>selection={{selection}}</code>\n        <hr/>\n        <div class=\"animate-switch-container\"\n          ng-switch on=\"selection\">\n            <div class=\"animate-switch\" ng-switch-when=\"settings|options\" ng-switch-when-separator=\"|\">Settings Div</div>\n            <div class=\"animate-switch\" ng-switch-when=\"home\">Home Span</div>\n            <div class=\"animate-switch\" ng-switch-default>default</div>\n        </div>\n      </div>\n    </file>\n    <file name=\"script.js\">\n      angular.module('switchExample', ['ngAnimate'])\n        .controller('ExampleController', ['$scope', function($scope) {\n          $scope.items = ['settings', 'home', 'options', 'other'];\n          $scope.selection = $scope.items[0];\n        }]);\n    </file>\n    <file name=\"animations.css\">\n      .animate-switch-container {\n        position:relative;\n        background:white;\n        border:1px solid black;\n        height:40px;\n        overflow:hidden;\n      }\n\n      .animate-switch {\n        padding:10px;\n      }\n\n      .animate-switch.ng-animate {\n        transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;\n\n        position:absolute;\n        top:0;\n        left:0;\n        right:0;\n        bottom:0;\n      }\n\n      .animate-switch.ng-leave.ng-leave-active,\n      .animate-switch.ng-enter {\n        top:-50px;\n      }\n      .animate-switch.ng-leave,\n      .animate-switch.ng-enter.ng-enter-active {\n        top:0;\n      }\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      var switchElem = element(by.css('[ng-switch]'));\n      var select = element(by.model('selection'));\n\n      it('should start in settings', function() {\n        expect(switchElem.getText()).toMatch(/Settings Div/);\n      });\n      it('should change to home', function() {\n        select.all(by.css('option')).get(1).click();\n        expect(switchElem.getText()).toMatch(/Home Span/);\n      });\n      it('should change to settings via \"options\"', function() {\n        select.all(by.css('option')).get(2).click();\n        expect(switchElem.getText()).toMatch(/Settings Div/);\n      });\n      it('should select default', function() {\n        select.all(by.css('option')).get(3).click();\n        expect(switchElem.getText()).toMatch(/default/);\n      });\n    </file>\n  </example>\n */\nvar ngSwitchDirective = ['$animate', '$compile', function($animate, $compile) {\n  return {\n    require: 'ngSwitch',\n\n    // asks for $scope to fool the BC controller module\n    controller: ['$scope', function NgSwitchController() {\n     this.cases = {};\n    }],\n    link: function(scope, element, attr, ngSwitchController) {\n      var watchExpr = attr.ngSwitch || attr.on,\n          selectedTranscludes = [],\n          selectedElements = [],\n          previousLeaveAnimations = [],\n          selectedScopes = [];\n\n      var spliceFactory = function(array, index) {\n          return function(response) {\n            if (response !== false) array.splice(index, 1);\n          };\n      };\n\n      scope.$watch(watchExpr, function ngSwitchWatchAction(value) {\n        var i, ii;\n\n        // Start with the last, in case the array is modified during the loop\n        while (previousLeaveAnimations.length) {\n          $animate.cancel(previousLeaveAnimations.pop());\n        }\n\n        for (i = 0, ii = selectedScopes.length; i < ii; ++i) {\n          var selected = getBlockNodes(selectedElements[i].clone);\n          selectedScopes[i].$destroy();\n          var runner = previousLeaveAnimations[i] = $animate.leave(selected);\n          runner.done(spliceFactory(previousLeaveAnimations, i));\n        }\n\n        selectedElements.length = 0;\n        selectedScopes.length = 0;\n\n        if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {\n          forEach(selectedTranscludes, function(selectedTransclude) {\n            selectedTransclude.transclude(function(caseElement, selectedScope) {\n              selectedScopes.push(selectedScope);\n              var anchor = selectedTransclude.element;\n              caseElement[caseElement.length++] = $compile.$$createComment('end ngSwitchWhen');\n              var block = { clone: caseElement };\n\n              selectedElements.push(block);\n              $animate.enter(caseElement, anchor.parent(), anchor);\n            });\n          });\n        }\n      });\n    }\n  };\n}];\n\nvar ngSwitchWhenDirective = ngDirective({\n  transclude: 'element',\n  priority: 1200,\n  require: '^ngSwitch',\n  multiElement: true,\n  link: function(scope, element, attrs, ctrl, $transclude) {\n\n    var cases = attrs.ngSwitchWhen.split(attrs.ngSwitchWhenSeparator).sort().filter(\n      // Filter duplicate cases\n      function(element, index, array) { return array[index - 1] !== element; }\n    );\n\n    forEach(cases, function(whenCase) {\n      ctrl.cases['!' + whenCase] = (ctrl.cases['!' + whenCase] || []);\n      ctrl.cases['!' + whenCase].push({ transclude: $transclude, element: element });\n    });\n  }\n});\n\nvar ngSwitchDefaultDirective = ngDirective({\n  transclude: 'element',\n  priority: 1200,\n  require: '^ngSwitch',\n  multiElement: true,\n  link: function(scope, element, attr, ctrl, $transclude) {\n    ctrl.cases['?'] = (ctrl.cases['?'] || []);\n    ctrl.cases['?'].push({ transclude: $transclude, element: element });\n   }\n});\n\n/**\n * @ngdoc directive\n * @name ngTransclude\n * @restrict EAC\n *\n * @description\n * Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.\n *\n * You can specify that you want to insert a named transclusion slot, instead of the default slot, by providing the slot name\n * as the value of the `ng-transclude` or `ng-transclude-slot` attribute.\n *\n * If the transcluded content is not empty (i.e. contains one or more DOM nodes, including whitespace text nodes), any existing\n * content of this element will be removed before the transcluded content is inserted.\n * If the transcluded content is empty (or only whitespace), the existing content is left intact. This lets you provide fallback\n * content in the case that no transcluded content is provided.\n *\n * @element ANY\n *\n * @param {string} ngTransclude|ngTranscludeSlot the name of the slot to insert at this point. If this is not provided, is empty\n *                                               or its value is the same as the name of the attribute then the default slot is used.\n *\n * @example\n * ### Basic transclusion\n * This example demonstrates basic transclusion of content into a component directive.\n * <example name=\"simpleTranscludeExample\" module=\"transcludeExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('transcludeExample', [])\n *        .directive('pane', function(){\n *           return {\n *             restrict: 'E',\n *             transclude: true,\n *             scope: { title:'@' },\n *             template: '<div style=\"border: 1px solid black;\">' +\n *                         '<div style=\"background-color: gray\">{{title}}</div>' +\n *                         '<ng-transclude></ng-transclude>' +\n *                       '</div>'\n *           };\n *       })\n *       .controller('ExampleController', ['$scope', function($scope) {\n *         $scope.title = 'Lorem Ipsum';\n *         $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';\n *       }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <input ng-model=\"title\" aria-label=\"title\"> <br/>\n *       <textarea ng-model=\"text\" aria-label=\"text\"></textarea> <br/>\n *       <pane title=\"{{title}}\"><span>{{text}}</span></pane>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *      it('should have transcluded', function() {\n *        var titleElement = element(by.model('title'));\n *        titleElement.clear();\n *        titleElement.sendKeys('TITLE');\n *        var textElement = element(by.model('text'));\n *        textElement.clear();\n *        textElement.sendKeys('TEXT');\n *        expect(element(by.binding('title')).getText()).toEqual('TITLE');\n *        expect(element(by.binding('text')).getText()).toEqual('TEXT');\n *      });\n *   </file>\n * </example>\n *\n * @example\n * ### Transclude fallback content\n * This example shows how to use `NgTransclude` with fallback content, that\n * is displayed if no transcluded content is provided.\n *\n * <example module=\"transcludeFallbackContentExample\" name=\"ng-transclude\">\n * <file name=\"index.html\">\n * <script>\n * angular.module('transcludeFallbackContentExample', [])\n * .directive('myButton', function(){\n *             return {\n *               restrict: 'E',\n *               transclude: true,\n *               scope: true,\n *               template: '<button style=\"cursor: pointer;\">' +\n *                           '<ng-transclude>' +\n *                             '<b style=\"color: red;\">Button1</b>' +\n *                           '</ng-transclude>' +\n *                         '</button>'\n *             };\n *         });\n * </script>\n * <!-- fallback button content -->\n * <my-button id=\"fallback\"></my-button>\n * <!-- modified button content -->\n * <my-button id=\"modified\">\n *   <i style=\"color: green;\">Button2</i>\n * </my-button>\n * </file>\n * <file name=\"protractor.js\" type=\"protractor\">\n * it('should have different transclude element content', function() {\n *          expect(element(by.id('fallback')).getText()).toBe('Button1');\n *          expect(element(by.id('modified')).getText()).toBe('Button2');\n *        });\n * </file>\n * </example>\n *\n * @example\n * ### Multi-slot transclusion\n * This example demonstrates using multi-slot transclusion in a component directive.\n * <example name=\"multiSlotTranscludeExample\" module=\"multiSlotTranscludeExample\">\n *   <file name=\"index.html\">\n *    <style>\n *      .title, .footer {\n *        background-color: gray\n *      }\n *    </style>\n *    <div ng-controller=\"ExampleController\">\n *      <input ng-model=\"title\" aria-label=\"title\"> <br/>\n *      <textarea ng-model=\"text\" aria-label=\"text\"></textarea> <br/>\n *      <pane>\n *        <pane-title><a ng-href=\"{{link}}\">{{title}}</a></pane-title>\n *        <pane-body><p>{{text}}</p></pane-body>\n *      </pane>\n *    </div>\n *   </file>\n *   <file name=\"app.js\">\n *    angular.module('multiSlotTranscludeExample', [])\n *     .directive('pane', function() {\n *        return {\n *          restrict: 'E',\n *          transclude: {\n *            'title': '?paneTitle',\n *            'body': 'paneBody',\n *            'footer': '?paneFooter'\n *          },\n *          template: '<div style=\"border: 1px solid black;\">' +\n *                      '<div class=\"title\" ng-transclude=\"title\">Fallback Title</div>' +\n *                      '<div ng-transclude=\"body\"></div>' +\n *                      '<div class=\"footer\" ng-transclude=\"footer\">Fallback Footer</div>' +\n *                    '</div>'\n *        };\n *    })\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.title = 'Lorem Ipsum';\n *      $scope.link = 'https://google.com';\n *      $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';\n *    }]);\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *      it('should have transcluded the title and the body', function() {\n *        var titleElement = element(by.model('title'));\n *        titleElement.clear();\n *        titleElement.sendKeys('TITLE');\n *        var textElement = element(by.model('text'));\n *        textElement.clear();\n *        textElement.sendKeys('TEXT');\n *        expect(element(by.css('.title')).getText()).toEqual('TITLE');\n *        expect(element(by.binding('text')).getText()).toEqual('TEXT');\n *        expect(element(by.css('.footer')).getText()).toEqual('Fallback Footer');\n *      });\n *   </file>\n * </example>\n */\nvar ngTranscludeMinErr = minErr('ngTransclude');\nvar ngTranscludeDirective = ['$compile', function($compile) {\n  return {\n    restrict: 'EAC',\n    terminal: true,\n    compile: function ngTranscludeCompile(tElement) {\n\n      // Remove and cache any original content to act as a fallback\n      var fallbackLinkFn = $compile(tElement.contents());\n      tElement.empty();\n\n      return function ngTranscludePostLink($scope, $element, $attrs, controller, $transclude) {\n\n        if (!$transclude) {\n          throw ngTranscludeMinErr('orphan',\n          'Illegal use of ngTransclude directive in the template! ' +\n          'No parent directive that requires a transclusion found. ' +\n          'Element: {0}',\n          startingTag($element));\n        }\n\n\n        // If the attribute is of the form: `ng-transclude=\"ng-transclude\"` then treat it like the default\n        if ($attrs.ngTransclude === $attrs.$attr.ngTransclude) {\n          $attrs.ngTransclude = '';\n        }\n        var slotName = $attrs.ngTransclude || $attrs.ngTranscludeSlot;\n\n        // If the slot is required and no transclusion content is provided then this call will throw an error\n        $transclude(ngTranscludeCloneAttachFn, null, slotName);\n\n        // If the slot is optional and no transclusion content is provided then use the fallback content\n        if (slotName && !$transclude.isSlotFilled(slotName)) {\n          useFallbackContent();\n        }\n\n        function ngTranscludeCloneAttachFn(clone, transcludedScope) {\n          if (clone.length && notWhitespace(clone)) {\n            $element.append(clone);\n          } else {\n            useFallbackContent();\n            // There is nothing linked against the transcluded scope since no content was available,\n            // so it should be safe to clean up the generated scope.\n            transcludedScope.$destroy();\n          }\n        }\n\n        function useFallbackContent() {\n          // Since this is the fallback content rather than the transcluded content,\n          // we link against the scope of this directive rather than the transcluded scope\n          fallbackLinkFn($scope, function(clone) {\n            $element.append(clone);\n          });\n        }\n\n        function notWhitespace(nodes) {\n          for (var i = 0, ii = nodes.length; i < ii; i++) {\n            var node = nodes[i];\n            if (node.nodeType !== NODE_TYPE_TEXT || node.nodeValue.trim()) {\n              return true;\n            }\n          }\n        }\n      };\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name script\n * @restrict E\n *\n * @description\n * Load the content of a `<script>` element into {@link ng.$templateCache `$templateCache`}, so that the\n * template can be used by {@link ng.directive:ngInclude `ngInclude`},\n * {@link ngRoute.directive:ngView `ngView`}, or {@link guide/directive directives}. The type of the\n * `<script>` element must be specified as `text/ng-template`, and a cache name for the template must be\n * assigned through the element's `id`, which can then be used as a directive's `templateUrl`.\n *\n * @param {string} type Must be set to `'text/ng-template'`.\n * @param {string} id Cache name of the template.\n *\n * @example\n  <example  name=\"script-tag\">\n    <file name=\"index.html\">\n      <script type=\"text/ng-template\" id=\"/tpl.html\">\n        Content of the template.\n      </script>\n\n      <a ng-click=\"currentTpl='/tpl.html'\" id=\"tpl-link\">Load inlined template</a>\n      <div id=\"tpl-content\" ng-include src=\"currentTpl\"></div>\n    </file>\n    <file name=\"protractor.js\" type=\"protractor\">\n      it('should load template defined inside script tag', function() {\n        element(by.css('#tpl-link')).click();\n        expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/);\n      });\n    </file>\n  </example>\n */\nvar scriptDirective = ['$templateCache', function($templateCache) {\n  return {\n    restrict: 'E',\n    terminal: true,\n    compile: function(element, attr) {\n      if (attr.type === 'text/ng-template') {\n        var templateUrl = attr.id,\n            text = element[0].text;\n\n        $templateCache.put(templateUrl, text);\n      }\n    }\n  };\n}];\n\n/* exported selectDirective, optionDirective */\n\nvar noopNgModelController = { $setViewValue: noop, $render: noop };\n\nfunction setOptionSelectedStatus(optionEl, value) {\n  optionEl.prop('selected', value); // needed for IE\n  /**\n   * When unselecting an option, setting the property to null / false should be enough\n   * However, screenreaders might react to the selected attribute instead, see\n   * https://github.com/angular/angular.js/issues/14419\n   * Note: \"selected\" is a boolean attr and will be removed when the \"value\" arg in attr() is false\n   * or null\n   */\n  optionEl.attr('selected', value);\n}\n\n/**\n * @ngdoc type\n * @name  select.SelectController\n * @description\n * The controller for the `<select>` directive. This provides support for reading\n * and writing the selected value(s) of the control and also coordinates dynamically\n * added `<option>` elements, perhaps by an `ngRepeat` directive.\n */\nvar SelectController =\n        ['$element', '$scope', /** @this */ function($element, $scope) {\n\n  var self = this,\n      optionsMap = new NgMap();\n\n  self.selectValueMap = {}; // Keys are the hashed values, values the original values\n\n  // If the ngModel doesn't get provided then provide a dummy noop version to prevent errors\n  self.ngModelCtrl = noopNgModelController;\n  self.multiple = false;\n\n  // The \"unknown\" option is one that is prepended to the list if the viewValue\n  // does not match any of the options. When it is rendered the value of the unknown\n  // option is '? XXX ?' where XXX is the hashKey of the value that is not known.\n  //\n  // We can't just jqLite('<option>') since jqLite is not smart enough\n  // to create it in <select> and IE barfs otherwise.\n  self.unknownOption = jqLite(window.document.createElement('option'));\n\n  // The empty option is an option with the value '' that te application developer can\n  // provide inside the select. When the model changes to a value that doesn't match an option,\n  // it is selected - so if an empty option is provided, no unknown option is generated.\n  // However, the empty option is not removed when the model matches an option. It is always selectable\n  // and indicates that a \"null\" selection has been made.\n  self.hasEmptyOption = false;\n  self.emptyOption = undefined;\n\n  self.renderUnknownOption = function(val) {\n    var unknownVal = self.generateUnknownOptionValue(val);\n    self.unknownOption.val(unknownVal);\n    $element.prepend(self.unknownOption);\n    setOptionSelectedStatus(self.unknownOption, true);\n    $element.val(unknownVal);\n  };\n\n  self.updateUnknownOption = function(val) {\n    var unknownVal = self.generateUnknownOptionValue(val);\n    self.unknownOption.val(unknownVal);\n    setOptionSelectedStatus(self.unknownOption, true);\n    $element.val(unknownVal);\n  };\n\n  self.generateUnknownOptionValue = function(val) {\n    return '? ' + hashKey(val) + ' ?';\n  };\n\n  self.removeUnknownOption = function() {\n    if (self.unknownOption.parent()) self.unknownOption.remove();\n  };\n\n  self.selectEmptyOption = function() {\n    if (self.emptyOption) {\n      $element.val('');\n      setOptionSelectedStatus(self.emptyOption, true);\n    }\n  };\n\n  self.unselectEmptyOption = function() {\n    if (self.hasEmptyOption) {\n      self.emptyOption.removeAttr('selected');\n    }\n  };\n\n  $scope.$on('$destroy', function() {\n    // disable unknown option so that we don't do work when the whole select is being destroyed\n    self.renderUnknownOption = noop;\n  });\n\n  // Read the value of the select control, the implementation of this changes depending\n  // upon whether the select can have multiple values and whether ngOptions is at work.\n  self.readValue = function readSingleValue() {\n    var val = $element.val();\n    // ngValue added option values are stored in the selectValueMap, normal interpolations are not\n    var realVal = val in self.selectValueMap ? self.selectValueMap[val] : val;\n\n    if (self.hasOption(realVal)) {\n      return realVal;\n    }\n\n    return null;\n  };\n\n\n  // Write the value to the select control, the implementation of this changes depending\n  // upon whether the select can have multiple values and whether ngOptions is at work.\n  self.writeValue = function writeSingleValue(value) {\n    // Make sure to remove the selected attribute from the previously selected option\n    // Otherwise, screen readers might get confused\n    var currentlySelectedOption = $element[0].options[$element[0].selectedIndex];\n    if (currentlySelectedOption) setOptionSelectedStatus(jqLite(currentlySelectedOption), false);\n\n    if (self.hasOption(value)) {\n      self.removeUnknownOption();\n\n      var hashedVal = hashKey(value);\n      $element.val(hashedVal in self.selectValueMap ? hashedVal : value);\n\n      // Set selected attribute and property on selected option for screen readers\n      var selectedOption = $element[0].options[$element[0].selectedIndex];\n      setOptionSelectedStatus(jqLite(selectedOption), true);\n    } else {\n      if (value == null && self.emptyOption) {\n        self.removeUnknownOption();\n        self.selectEmptyOption();\n      } else if (self.unknownOption.parent().length) {\n        self.updateUnknownOption(value);\n      } else {\n        self.renderUnknownOption(value);\n      }\n    }\n  };\n\n\n  // Tell the select control that an option, with the given value, has been added\n  self.addOption = function(value, element) {\n    // Skip comment nodes, as they only pollute the `optionsMap`\n    if (element[0].nodeType === NODE_TYPE_COMMENT) return;\n\n    assertNotHasOwnProperty(value, '\"option value\"');\n    if (value === '') {\n      self.hasEmptyOption = true;\n      self.emptyOption = element;\n    }\n    var count = optionsMap.get(value) || 0;\n    optionsMap.set(value, count + 1);\n    // Only render at the end of a digest. This improves render performance when many options\n    // are added during a digest and ensures all relevant options are correctly marked as selected\n    scheduleRender();\n  };\n\n  // Tell the select control that an option, with the given value, has been removed\n  self.removeOption = function(value) {\n    var count = optionsMap.get(value);\n    if (count) {\n      if (count === 1) {\n        optionsMap.delete(value);\n        if (value === '') {\n          self.hasEmptyOption = false;\n          self.emptyOption = undefined;\n        }\n      } else {\n        optionsMap.set(value, count - 1);\n      }\n    }\n  };\n\n  // Check whether the select control has an option matching the given value\n  self.hasOption = function(value) {\n    return !!optionsMap.get(value);\n  };\n\n\n  var renderScheduled = false;\n  function scheduleRender() {\n    if (renderScheduled) return;\n    renderScheduled = true;\n    $scope.$$postDigest(function() {\n      renderScheduled = false;\n      self.ngModelCtrl.$render();\n    });\n  }\n\n  var updateScheduled = false;\n  function scheduleViewValueUpdate(renderAfter) {\n    if (updateScheduled) return;\n\n    updateScheduled = true;\n\n    $scope.$$postDigest(function() {\n      if ($scope.$$destroyed) return;\n\n      updateScheduled = false;\n      self.ngModelCtrl.$setViewValue(self.readValue());\n      if (renderAfter) self.ngModelCtrl.$render();\n    });\n  }\n\n\n  self.registerOption = function(optionScope, optionElement, optionAttrs, interpolateValueFn, interpolateTextFn) {\n\n    if (optionAttrs.$attr.ngValue) {\n      // The value attribute is set by ngValue\n      var oldVal, hashedVal = NaN;\n      optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) {\n\n        var removal;\n        var previouslySelected = optionElement.prop('selected');\n\n        if (isDefined(hashedVal)) {\n          self.removeOption(oldVal);\n          delete self.selectValueMap[hashedVal];\n          removal = true;\n        }\n\n        hashedVal = hashKey(newVal);\n        oldVal = newVal;\n        self.selectValueMap[hashedVal] = newVal;\n        self.addOption(newVal, optionElement);\n        // Set the attribute directly instead of using optionAttrs.$set - this stops the observer\n        // from firing a second time. Other $observers on value will also get the result of the\n        // ngValue expression, not the hashed value\n        optionElement.attr('value', hashedVal);\n\n        if (removal && previouslySelected) {\n          scheduleViewValueUpdate();\n        }\n\n      });\n    } else if (interpolateValueFn) {\n      // The value attribute is interpolated\n      optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) {\n        // This method is overwritten in ngOptions and has side-effects!\n        self.readValue();\n\n        var removal;\n        var previouslySelected = optionElement.prop('selected');\n\n        if (isDefined(oldVal)) {\n          self.removeOption(oldVal);\n          removal = true;\n        }\n        oldVal = newVal;\n        self.addOption(newVal, optionElement);\n\n        if (removal && previouslySelected) {\n          scheduleViewValueUpdate();\n        }\n      });\n    } else if (interpolateTextFn) {\n      // The text content is interpolated\n      optionScope.$watch(interpolateTextFn, function interpolateWatchAction(newVal, oldVal) {\n        optionAttrs.$set('value', newVal);\n        var previouslySelected = optionElement.prop('selected');\n        if (oldVal !== newVal) {\n          self.removeOption(oldVal);\n        }\n        self.addOption(newVal, optionElement);\n\n        if (oldVal && previouslySelected) {\n          scheduleViewValueUpdate();\n        }\n      });\n    } else {\n      // The value attribute is static\n      self.addOption(optionAttrs.value, optionElement);\n    }\n\n\n    optionAttrs.$observe('disabled', function(newVal) {\n\n      // Since model updates will also select disabled options (like ngOptions),\n      // we only have to handle options becoming disabled, not enabled\n\n      if (newVal === 'true' || newVal && optionElement.prop('selected')) {\n        if (self.multiple) {\n          scheduleViewValueUpdate(true);\n        } else {\n          self.ngModelCtrl.$setViewValue(null);\n          self.ngModelCtrl.$render();\n        }\n      }\n    });\n\n    optionElement.on('$destroy', function() {\n      var currentValue = self.readValue();\n      var removeValue = optionAttrs.value;\n\n      self.removeOption(removeValue);\n      scheduleRender();\n\n      if (self.multiple && currentValue && currentValue.indexOf(removeValue) !== -1 ||\n          currentValue === removeValue\n      ) {\n        // When multiple (selected) options are destroyed at the same time, we don't want\n        // to run a model update for each of them. Instead, run a single update in the $$postDigest\n        scheduleViewValueUpdate(true);\n      }\n    });\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name select\n * @restrict E\n *\n * @description\n * HTML `select` element with angular data-binding.\n *\n * The `select` directive is used together with {@link ngModel `ngModel`} to provide data-binding\n * between the scope and the `<select>` control (including setting default values).\n * It also handles dynamic `<option>` elements, which can be added using the {@link ngRepeat `ngRepeat}` or\n * {@link ngOptions `ngOptions`} directives.\n *\n * When an item in the `<select>` menu is selected, the value of the selected option will be bound\n * to the model identified by the `ngModel` directive. With static or repeated options, this is\n * the content of the `value` attribute or the textContent of the `<option>`, if the value attribute is missing.\n * Value and textContent can be interpolated.\n *\n * ## Matching model and option values\n *\n * In general, the match between the model and an option is evaluated by strictly comparing the model\n * value against the value of the available options.\n *\n * If you are setting the option value with the option's `value` attribute, or textContent, the\n * value will always be a `string` which means that the model value must also be a string.\n * Otherwise the `select` directive cannot match them correctly.\n *\n * To bind the model to a non-string value, you can use one of the following strategies:\n * - the {@link ng.ngOptions `ngOptions`} directive\n *   ({@link ng.select#using-select-with-ngoptions-and-setting-a-default-value})\n * - the {@link ng.ngValue `ngValue`} directive, which allows arbitrary expressions to be\n *   option values ({@link ng.select#using-ngvalue-to-bind-the-model-to-an-array-of-objects Example})\n * - model $parsers / $formatters to convert the string value\n *   ({@link ng.select#binding-select-to-a-non-string-value-via-ngmodel-parsing-formatting Example})\n *\n * If the viewValue of `ngModel` does not match any of the options, then the control\n * will automatically add an \"unknown\" option, which it then removes when the mismatch is resolved.\n *\n * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can\n * be nested into the `<select>` element. This element will then represent the `null` or \"not selected\"\n * option. See example below for demonstration.\n *\n * ## Choosing between `ngRepeat` and `ngOptions`\n *\n * In many cases, `ngRepeat` can be used on `<option>` elements instead of {@link ng.directive:ngOptions\n * ngOptions} to achieve a similar result. However, `ngOptions` provides some benefits:\n * - more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the\n * comprehension expression\n * - reduced memory consumption by not creating a new scope for each repeated instance\n * - increased render speed by creating the options in a documentFragment instead of individually\n *\n * Specifically, select with repeated options slows down significantly starting at 2000 options in\n * Chrome and Internet Explorer / Edge.\n *\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} name Property name of the form under which the control is published.\n * @param {string=} multiple Allows multiple options to be selected. The selected values will be\n *     bound to the model as an array.\n * @param {string=} required Sets `required` validation error key if the value is not entered.\n * @param {string=} ngRequired Adds required attribute and required validation constraint to\n * the element when the ngRequired expression evaluates to true. Use ngRequired instead of required\n * when you want to data-bind to the required attribute.\n * @param {string=} ngChange Angular expression to be executed when selected option(s) changes due to user\n *    interaction with the select element.\n * @param {string=} ngOptions sets the options that the select is populated with and defines what is\n * set on the model on selection. See {@link ngOptions `ngOptions`}.\n * @param {string=} ngAttrSize sets the size of the select element dynamically. Uses the\n * {@link guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes ngAttr} directive.\n *\n * @example\n * ### Simple `select` elements with static options\n *\n * <example name=\"static-select\" module=\"staticSelect\">\n * <file name=\"index.html\">\n * <div ng-controller=\"ExampleController\">\n *   <form name=\"myForm\">\n *     <label for=\"singleSelect\"> Single select: </label><br>\n *     <select name=\"singleSelect\" ng-model=\"data.singleSelect\">\n *       <option value=\"option-1\">Option 1</option>\n *       <option value=\"option-2\">Option 2</option>\n *     </select><br>\n *\n *     <label for=\"singleSelect\"> Single select with \"not selected\" option and dynamic option values: </label><br>\n *     <select name=\"singleSelect\" id=\"singleSelect\" ng-model=\"data.singleSelect\">\n *       <option value=\"\">---Please select---</option> <!-- not selected / blank option -->\n *       <option value=\"{{data.option1}}\">Option 1</option> <!-- interpolation -->\n *       <option value=\"option-2\">Option 2</option>\n *     </select><br>\n *     <button ng-click=\"forceUnknownOption()\">Force unknown option</button><br>\n *     <tt>singleSelect = {{data.singleSelect}}</tt>\n *\n *     <hr>\n *     <label for=\"multipleSelect\"> Multiple select: </label><br>\n *     <select name=\"multipleSelect\" id=\"multipleSelect\" ng-model=\"data.multipleSelect\" multiple>\n *       <option value=\"option-1\">Option 1</option>\n *       <option value=\"option-2\">Option 2</option>\n *       <option value=\"option-3\">Option 3</option>\n *     </select><br>\n *     <tt>multipleSelect = {{data.multipleSelect}}</tt><br/>\n *   </form>\n * </div>\n * </file>\n * <file name=\"app.js\">\n *  angular.module('staticSelect', [])\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.data = {\n *       singleSelect: null,\n *       multipleSelect: [],\n *       option1: 'option-1'\n *      };\n *\n *      $scope.forceUnknownOption = function() {\n *        $scope.data.singleSelect = 'nonsense';\n *      };\n *   }]);\n * </file>\n *</example>\n *\n * ### Using `ngRepeat` to generate `select` options\n * <example name=\"select-ngrepeat\" module=\"ngrepeatSelect\">\n * <file name=\"index.html\">\n * <div ng-controller=\"ExampleController\">\n *   <form name=\"myForm\">\n *     <label for=\"repeatSelect\"> Repeat select: </label>\n *     <select name=\"repeatSelect\" id=\"repeatSelect\" ng-model=\"data.model\">\n *       <option ng-repeat=\"option in data.availableOptions\" value=\"{{option.id}}\">{{option.name}}</option>\n *     </select>\n *   </form>\n *   <hr>\n *   <tt>model = {{data.model}}</tt><br/>\n * </div>\n * </file>\n * <file name=\"app.js\">\n *  angular.module('ngrepeatSelect', [])\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.data = {\n *       model: null,\n *       availableOptions: [\n *         {id: '1', name: 'Option A'},\n *         {id: '2', name: 'Option B'},\n *         {id: '3', name: 'Option C'}\n *       ]\n *      };\n *   }]);\n * </file>\n *</example>\n *\n * ### Using `ngValue` to bind the model to an array of objects\n * <example name=\"select-ngvalue\" module=\"ngvalueSelect\">\n * <file name=\"index.html\">\n * <div ng-controller=\"ExampleController\">\n *   <form name=\"myForm\">\n *     <label for=\"ngvalueselect\"> ngvalue select: </label>\n *     <select size=\"6\" name=\"ngvalueselect\" ng-model=\"data.model\" multiple>\n *       <option ng-repeat=\"option in data.availableOptions\" ng-value=\"option.value\">{{option.name}}</option>\n *     </select>\n *   </form>\n *   <hr>\n *   <pre>model = {{data.model | json}}</pre><br/>\n * </div>\n * </file>\n * <file name=\"app.js\">\n *  angular.module('ngvalueSelect', [])\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.data = {\n *       model: null,\n *       availableOptions: [\n           {value: 'myString', name: 'string'},\n           {value: 1, name: 'integer'},\n           {value: true, name: 'boolean'},\n           {value: null, name: 'null'},\n           {value: {prop: 'value'}, name: 'object'},\n           {value: ['a'], name: 'array'}\n *       ]\n *      };\n *   }]);\n * </file>\n *</example>\n *\n * ### Using `select` with `ngOptions` and setting a default value\n * See the {@link ngOptions ngOptions documentation} for more `ngOptions` usage examples.\n *\n * <example name=\"select-with-default-values\" module=\"defaultValueSelect\">\n * <file name=\"index.html\">\n * <div ng-controller=\"ExampleController\">\n *   <form name=\"myForm\">\n *     <label for=\"mySelect\">Make a choice:</label>\n *     <select name=\"mySelect\" id=\"mySelect\"\n *       ng-options=\"option.name for option in data.availableOptions track by option.id\"\n *       ng-model=\"data.selectedOption\"></select>\n *   </form>\n *   <hr>\n *   <tt>option = {{data.selectedOption}}</tt><br/>\n * </div>\n * </file>\n * <file name=\"app.js\">\n *  angular.module('defaultValueSelect', [])\n *    .controller('ExampleController', ['$scope', function($scope) {\n *      $scope.data = {\n *       availableOptions: [\n *         {id: '1', name: 'Option A'},\n *         {id: '2', name: 'Option B'},\n *         {id: '3', name: 'Option C'}\n *       ],\n *       selectedOption: {id: '3', name: 'Option C'} //This sets the default value of the select in the ui\n *       };\n *   }]);\n * </file>\n *</example>\n *\n *\n * ### Binding `select` to a non-string value via `ngModel` parsing / formatting\n *\n * <example name=\"select-with-non-string-options\" module=\"nonStringSelect\">\n *   <file name=\"index.html\">\n *     <select ng-model=\"model.id\" convert-to-number>\n *       <option value=\"0\">Zero</option>\n *       <option value=\"1\">One</option>\n *       <option value=\"2\">Two</option>\n *     </select>\n *     {{ model }}\n *   </file>\n *   <file name=\"app.js\">\n *     angular.module('nonStringSelect', [])\n *       .run(function($rootScope) {\n *         $rootScope.model = { id: 2 };\n *       })\n *       .directive('convertToNumber', function() {\n *         return {\n *           require: 'ngModel',\n *           link: function(scope, element, attrs, ngModel) {\n *             ngModel.$parsers.push(function(val) {\n *               return parseInt(val, 10);\n *             });\n *             ngModel.$formatters.push(function(val) {\n *               return '' + val;\n *             });\n *           }\n *         };\n *       });\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n *     it('should initialize to model', function() {\n *       expect(element(by.model('model.id')).$('option:checked').getText()).toEqual('Two');\n *     });\n *   </file>\n * </example>\n *\n */\nvar selectDirective = function() {\n\n  return {\n    restrict: 'E',\n    require: ['select', '?ngModel'],\n    controller: SelectController,\n    priority: 1,\n    link: {\n      pre: selectPreLink,\n      post: selectPostLink\n    }\n  };\n\n  function selectPreLink(scope, element, attr, ctrls) {\n\n      var selectCtrl = ctrls[0];\n      var ngModelCtrl = ctrls[1];\n\n      // if ngModel is not defined, we don't need to do anything but set the registerOption\n      // function to noop, so options don't get added internally\n      if (!ngModelCtrl) {\n        selectCtrl.registerOption = noop;\n        return;\n      }\n\n\n      selectCtrl.ngModelCtrl = ngModelCtrl;\n\n      // When the selected item(s) changes we delegate getting the value of the select control\n      // to the `readValue` method, which can be changed if the select can have multiple\n      // selected values or if the options are being generated by `ngOptions`\n      element.on('change', function() {\n        selectCtrl.removeUnknownOption();\n        scope.$apply(function() {\n          ngModelCtrl.$setViewValue(selectCtrl.readValue());\n        });\n      });\n\n      // If the select allows multiple values then we need to modify how we read and write\n      // values from and to the control; also what it means for the value to be empty and\n      // we have to add an extra watch since ngModel doesn't work well with arrays - it\n      // doesn't trigger rendering if only an item in the array changes.\n      if (attr.multiple) {\n        selectCtrl.multiple = true;\n\n        // Read value now needs to check each option to see if it is selected\n        selectCtrl.readValue = function readMultipleValue() {\n          var array = [];\n          forEach(element.find('option'), function(option) {\n            if (option.selected && !option.disabled) {\n              var val = option.value;\n              array.push(val in selectCtrl.selectValueMap ? selectCtrl.selectValueMap[val] : val);\n            }\n          });\n          return array;\n        };\n\n        // Write value now needs to set the selected property of each matching option\n        selectCtrl.writeValue = function writeMultipleValue(value) {\n          forEach(element.find('option'), function(option) {\n            var shouldBeSelected = !!value && (includes(value, option.value) ||\n                                               includes(value, selectCtrl.selectValueMap[option.value]));\n            var currentlySelected = option.selected;\n\n            // IE and Edge, adding options to the selection via shift+click/UP/DOWN,\n            // will de-select already selected options if \"selected\" on those options was set\n            // more than once (i.e. when the options were already selected)\n            // So we only modify the selected property if neccessary.\n            // Note: this behavior cannot be replicated via unit tests because it only shows in the\n            // actual user interface.\n            if (shouldBeSelected !== currentlySelected) {\n              setOptionSelectedStatus(jqLite(option), shouldBeSelected);\n            }\n\n          });\n        };\n\n        // we have to do it on each watch since ngModel watches reference, but\n        // we need to work of an array, so we need to see if anything was inserted/removed\n        var lastView, lastViewRef = NaN;\n        scope.$watch(function selectMultipleWatch() {\n          if (lastViewRef === ngModelCtrl.$viewValue && !equals(lastView, ngModelCtrl.$viewValue)) {\n            lastView = shallowCopy(ngModelCtrl.$viewValue);\n            ngModelCtrl.$render();\n          }\n          lastViewRef = ngModelCtrl.$viewValue;\n        });\n\n        // If we are a multiple select then value is now a collection\n        // so the meaning of $isEmpty changes\n        ngModelCtrl.$isEmpty = function(value) {\n          return !value || value.length === 0;\n        };\n\n      }\n    }\n\n    function selectPostLink(scope, element, attrs, ctrls) {\n      // if ngModel is not defined, we don't need to do anything\n      var ngModelCtrl = ctrls[1];\n      if (!ngModelCtrl) return;\n\n      var selectCtrl = ctrls[0];\n\n      // We delegate rendering to the `writeValue` method, which can be changed\n      // if the select can have multiple selected values or if the options are being\n      // generated by `ngOptions`.\n      // This must be done in the postLink fn to prevent $render to be called before\n      // all nodes have been linked correctly.\n      ngModelCtrl.$render = function() {\n        selectCtrl.writeValue(ngModelCtrl.$viewValue);\n      };\n    }\n};\n\n\n// The option directive is purely designed to communicate the existence (or lack of)\n// of dynamically created (and destroyed) option elements to their containing select\n// directive via its controller.\nvar optionDirective = ['$interpolate', function($interpolate) {\n  return {\n    restrict: 'E',\n    priority: 100,\n    compile: function(element, attr) {\n      var interpolateValueFn, interpolateTextFn;\n\n      if (isDefined(attr.ngValue)) {\n        // Will be handled by registerOption\n      } else if (isDefined(attr.value)) {\n        // If the value attribute is defined, check if it contains an interpolation\n        interpolateValueFn = $interpolate(attr.value, true);\n      } else {\n        // If the value attribute is not defined then we fall back to the\n        // text content of the option element, which may be interpolated\n        interpolateTextFn = $interpolate(element.text(), true);\n        if (!interpolateTextFn) {\n          attr.$set('value', element.text());\n        }\n      }\n\n      return function(scope, element, attr) {\n        // This is an optimization over using ^^ since we don't want to have to search\n        // all the way to the root of the DOM for every single option element\n        var selectCtrlName = '$selectController',\n            parent = element.parent(),\n            selectCtrl = parent.data(selectCtrlName) ||\n              parent.parent().data(selectCtrlName); // in case we are in optgroup\n\n        if (selectCtrl) {\n          selectCtrl.registerOption(scope, element, attr, interpolateValueFn, interpolateTextFn);\n        }\n      };\n    }\n  };\n}];\n\n/**\n * @ngdoc directive\n * @name ngRequired\n * @restrict A\n *\n * @description\n *\n * ngRequired adds the required {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for {@link input `input`} and {@link select `select`} controls, but can also be\n * applied to custom controls.\n *\n * The directive sets the `required` attribute on the element if the Angular expression inside\n * `ngRequired` evaluates to true. A special directive for setting `required` is necessary because we\n * cannot use interpolation inside `required`. See the {@link guide/interpolation interpolation guide}\n * for more info.\n *\n * The validator will set the `required` error key to true if the `required` attribute is set and\n * calling {@link ngModel.NgModelController#$isEmpty `NgModelController.$isEmpty`} with the\n * {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`} returns `true`. For example, the\n * `$isEmpty()` implementation for `input[text]` checks the length of the `$viewValue`. When developing\n * custom controls, `$isEmpty()` can be overwritten to account for a $viewValue that is not string-based.\n *\n * @example\n * <example name=\"ngRequiredDirective\" module=\"ngRequiredExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('ngRequiredExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.required = true;\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"form\">\n *         <label for=\"required\">Toggle required: </label>\n *         <input type=\"checkbox\" ng-model=\"required\" id=\"required\" />\n *         <br>\n *         <label for=\"input\">This input must be filled if `required` is true: </label>\n *         <input type=\"text\" ng-model=\"model\" id=\"input\" name=\"input\" ng-required=\"required\" /><br>\n *         <hr>\n *         required error set? = <code>{{form.input.$error.required}}</code><br>\n *         model = <code>{{model}}</code>\n *       </form>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n       var required = element(by.binding('form.input.$error.required'));\n       var model = element(by.binding('model'));\n       var input = element(by.id('input'));\n\n       it('should set the required error', function() {\n         expect(required.getText()).toContain('true');\n\n         input.sendKeys('123');\n         expect(required.getText()).not.toContain('true');\n         expect(model.getText()).toContain('123');\n       });\n *   </file>\n * </example>\n */\nvar requiredDirective = function() {\n  return {\n    restrict: 'A',\n    require: '?ngModel',\n    link: function(scope, elm, attr, ctrl) {\n      if (!ctrl) return;\n      attr.required = true; // force truthy in case we are on non input element\n\n      ctrl.$validators.required = function(modelValue, viewValue) {\n        return !attr.required || !ctrl.$isEmpty(viewValue);\n      };\n\n      attr.$observe('required', function() {\n        ctrl.$validate();\n      });\n    }\n  };\n};\n\n/**\n * @ngdoc directive\n * @name ngPattern\n *\n * @description\n *\n * ngPattern adds the pattern {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.\n *\n * The validator sets the `pattern` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}\n * does not match a RegExp which is obtained by evaluating the Angular expression given in the\n * `ngPattern` attribute value:\n * * If the expression evaluates to a RegExp object, then this is used directly.\n * * If the expression evaluates to a string, then it will be converted to a RegExp after wrapping it\n * in `^` and `$` characters. For instance, `\"abc\"` will be converted to `new RegExp('^abc$')`.\n *\n * <div class=\"alert alert-info\">\n * **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to\n * start at the index of the last search's match, thus not taking the whole input value into\n * account.\n * </div>\n *\n * <div class=\"alert alert-info\">\n * **Note:** This directive is also added when the plain `pattern` attribute is used, with two\n * differences:\n * <ol>\n *   <li>\n *     `ngPattern` does not set the `pattern` attribute and therefore HTML5 constraint validation is\n *     not available.\n *   </li>\n *   <li>\n *     The `ngPattern` attribute must be an expression, while the `pattern` value must be\n *     interpolated.\n *   </li>\n * </ol>\n * </div>\n *\n * @example\n * <example name=\"ngPatternDirective\" module=\"ngPatternExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('ngPatternExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.regex = '\\\\d+';\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"form\">\n *         <label for=\"regex\">Set a pattern (regex string): </label>\n *         <input type=\"text\" ng-model=\"regex\" id=\"regex\" />\n *         <br>\n *         <label for=\"input\">This input is restricted by the current pattern: </label>\n *         <input type=\"text\" ng-model=\"model\" id=\"input\" name=\"input\" ng-pattern=\"regex\" /><br>\n *         <hr>\n *         input valid? = <code>{{form.input.$valid}}</code><br>\n *         model = <code>{{model}}</code>\n *       </form>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n       var model = element(by.binding('model'));\n       var input = element(by.id('input'));\n\n       it('should validate the input with the default pattern', function() {\n         input.sendKeys('aaa');\n         expect(model.getText()).not.toContain('aaa');\n\n         input.clear().then(function() {\n           input.sendKeys('123');\n           expect(model.getText()).toContain('123');\n         });\n       });\n *   </file>\n * </example>\n */\nvar patternDirective = function() {\n  return {\n    restrict: 'A',\n    require: '?ngModel',\n    link: function(scope, elm, attr, ctrl) {\n      if (!ctrl) return;\n\n      var regexp, patternExp = attr.ngPattern || attr.pattern;\n      attr.$observe('pattern', function(regex) {\n        if (isString(regex) && regex.length > 0) {\n          regex = new RegExp('^' + regex + '$');\n        }\n\n        if (regex && !regex.test) {\n          throw minErr('ngPattern')('noregexp',\n            'Expected {0} to be a RegExp but was {1}. Element: {2}', patternExp,\n            regex, startingTag(elm));\n        }\n\n        regexp = regex || undefined;\n        ctrl.$validate();\n      });\n\n      ctrl.$validators.pattern = function(modelValue, viewValue) {\n        // HTML5 pattern constraint validates the input value, so we validate the viewValue\n        return ctrl.$isEmpty(viewValue) || isUndefined(regexp) || regexp.test(viewValue);\n      };\n    }\n  };\n};\n\n/**\n * @ngdoc directive\n * @name ngMaxlength\n *\n * @description\n *\n * ngMaxlength adds the maxlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.\n *\n * The validator sets the `maxlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}\n * is longer than the integer obtained by evaluating the Angular expression given in the\n * `ngMaxlength` attribute value.\n *\n * <div class=\"alert alert-info\">\n * **Note:** This directive is also added when the plain `maxlength` attribute is used, with two\n * differences:\n * <ol>\n *   <li>\n *     `ngMaxlength` does not set the `maxlength` attribute and therefore HTML5 constraint\n *     validation is not available.\n *   </li>\n *   <li>\n *     The `ngMaxlength` attribute must be an expression, while the `maxlength` value must be\n *     interpolated.\n *   </li>\n * </ol>\n * </div>\n *\n * @example\n * <example name=\"ngMaxlengthDirective\" module=\"ngMaxlengthExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('ngMaxlengthExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.maxlength = 5;\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"form\">\n *         <label for=\"maxlength\">Set a maxlength: </label>\n *         <input type=\"number\" ng-model=\"maxlength\" id=\"maxlength\" />\n *         <br>\n *         <label for=\"input\">This input is restricted by the current maxlength: </label>\n *         <input type=\"text\" ng-model=\"model\" id=\"input\" name=\"input\" ng-maxlength=\"maxlength\" /><br>\n *         <hr>\n *         input valid? = <code>{{form.input.$valid}}</code><br>\n *         model = <code>{{model}}</code>\n *       </form>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n       var model = element(by.binding('model'));\n       var input = element(by.id('input'));\n\n       it('should validate the input with the default maxlength', function() {\n         input.sendKeys('abcdef');\n         expect(model.getText()).not.toContain('abcdef');\n\n         input.clear().then(function() {\n           input.sendKeys('abcde');\n           expect(model.getText()).toContain('abcde');\n         });\n       });\n *   </file>\n * </example>\n */\nvar maxlengthDirective = function() {\n  return {\n    restrict: 'A',\n    require: '?ngModel',\n    link: function(scope, elm, attr, ctrl) {\n      if (!ctrl) return;\n\n      var maxlength = -1;\n      attr.$observe('maxlength', function(value) {\n        var intVal = toInt(value);\n        maxlength = isNumberNaN(intVal) ? -1 : intVal;\n        ctrl.$validate();\n      });\n      ctrl.$validators.maxlength = function(modelValue, viewValue) {\n        return (maxlength < 0) || ctrl.$isEmpty(viewValue) || (viewValue.length <= maxlength);\n      };\n    }\n  };\n};\n\n/**\n * @ngdoc directive\n * @name ngMinlength\n *\n * @description\n *\n * ngMinlength adds the minlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.\n * It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.\n *\n * The validator sets the `minlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}\n * is shorter than the integer obtained by evaluating the Angular expression given in the\n * `ngMinlength` attribute value.\n *\n * <div class=\"alert alert-info\">\n * **Note:** This directive is also added when the plain `minlength` attribute is used, with two\n * differences:\n * <ol>\n *   <li>\n *     `ngMinlength` does not set the `minlength` attribute and therefore HTML5 constraint\n *     validation is not available.\n *   </li>\n *   <li>\n *     The `ngMinlength` value must be an expression, while the `minlength` value must be\n *     interpolated.\n *   </li>\n * </ol>\n * </div>\n *\n * @example\n * <example name=\"ngMinlengthDirective\" module=\"ngMinlengthExample\">\n *   <file name=\"index.html\">\n *     <script>\n *       angular.module('ngMinlengthExample', [])\n *         .controller('ExampleController', ['$scope', function($scope) {\n *           $scope.minlength = 3;\n *         }]);\n *     </script>\n *     <div ng-controller=\"ExampleController\">\n *       <form name=\"form\">\n *         <label for=\"minlength\">Set a minlength: </label>\n *         <input type=\"number\" ng-model=\"minlength\" id=\"minlength\" />\n *         <br>\n *         <label for=\"input\">This input is restricted by the current minlength: </label>\n *         <input type=\"text\" ng-model=\"model\" id=\"input\" name=\"input\" ng-minlength=\"minlength\" /><br>\n *         <hr>\n *         input valid? = <code>{{form.input.$valid}}</code><br>\n *         model = <code>{{model}}</code>\n *       </form>\n *     </div>\n *   </file>\n *   <file name=\"protractor.js\" type=\"protractor\">\n       var model = element(by.binding('model'));\n       var input = element(by.id('input'));\n\n       it('should validate the input with the default minlength', function() {\n         input.sendKeys('ab');\n         expect(model.getText()).not.toContain('ab');\n\n         input.sendKeys('abc');\n         expect(model.getText()).toContain('abc');\n       });\n *   </file>\n * </example>\n */\nvar minlengthDirective = function() {\n  return {\n    restrict: 'A',\n    require: '?ngModel',\n    link: function(scope, elm, attr, ctrl) {\n      if (!ctrl) return;\n\n      var minlength = 0;\n      attr.$observe('minlength', function(value) {\n        minlength = toInt(value) || 0;\n        ctrl.$validate();\n      });\n      ctrl.$validators.minlength = function(modelValue, viewValue) {\n        return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;\n      };\n    }\n  };\n};\n\nif (window.angular.bootstrap) {\n  // AngularJS is already loaded, so we can return here...\n  if (window.console) {\n    console.log('WARNING: Tried to load angular more than once.');\n  }\n  return;\n}\n\n// try to bind to jquery now so that one can write jqLite(fn)\n// but we will rebind on bootstrap again.\nbindJQuery();\n\npublishExternalAPI(angular);\n\nangular.module(\"ngLocale\", [], [\"$provide\", function($provide) {\nvar PLURAL_CATEGORY = {ZERO: \"zero\", ONE: \"one\", TWO: \"two\", FEW: \"few\", MANY: \"many\", OTHER: \"other\"};\nfunction getDecimals(n) {\n  n = n + '';\n  var i = n.indexOf('.');\n  return (i == -1) ? 0 : n.length - i - 1;\n}\n\nfunction getVF(n, opt_precision) {\n  var v = opt_precision;\n\n  if (undefined === v) {\n    v = Math.min(getDecimals(n), 3);\n  }\n\n  var base = Math.pow(10, v);\n  var f = ((n * base) | 0) % base;\n  return {v: v, f: f};\n}\n\n$provide.value(\"$locale\", {\n  \"DATETIME_FORMATS\": {\n    \"AMPMS\": [\n      \"AM\",\n      \"PM\"\n    ],\n    \"DAY\": [\n      \"Sunday\",\n      \"Monday\",\n      \"Tuesday\",\n      \"Wednesday\",\n      \"Thursday\",\n      \"Friday\",\n      \"Saturday\"\n    ],\n    \"ERANAMES\": [\n      \"Before Christ\",\n      \"Anno Domini\"\n    ],\n    \"ERAS\": [\n      \"BC\",\n      \"AD\"\n    ],\n    \"FIRSTDAYOFWEEK\": 6,\n    \"MONTH\": [\n      \"January\",\n      \"February\",\n      \"March\",\n      \"April\",\n      \"May\",\n      \"June\",\n      \"July\",\n      \"August\",\n      \"September\",\n      \"October\",\n      \"November\",\n      \"December\"\n    ],\n    \"SHORTDAY\": [\n      \"Sun\",\n      \"Mon\",\n      \"Tue\",\n      \"Wed\",\n      \"Thu\",\n      \"Fri\",\n      \"Sat\"\n    ],\n    \"SHORTMONTH\": [\n      \"Jan\",\n      \"Feb\",\n      \"Mar\",\n      \"Apr\",\n      \"May\",\n      \"Jun\",\n      \"Jul\",\n      \"Aug\",\n      \"Sep\",\n      \"Oct\",\n      \"Nov\",\n      \"Dec\"\n    ],\n    \"STANDALONEMONTH\": [\n      \"January\",\n      \"February\",\n      \"March\",\n      \"April\",\n      \"May\",\n      \"June\",\n      \"July\",\n      \"August\",\n      \"September\",\n      \"October\",\n      \"November\",\n      \"December\"\n    ],\n    \"WEEKENDRANGE\": [\n      5,\n      6\n    ],\n    \"fullDate\": \"EEEE, MMMM d, y\",\n    \"longDate\": \"MMMM d, y\",\n    \"medium\": \"MMM d, y h:mm:ss a\",\n    \"mediumDate\": \"MMM d, y\",\n    \"mediumTime\": \"h:mm:ss a\",\n    \"short\": \"M/d/yy h:mm a\",\n    \"shortDate\": \"M/d/yy\",\n    \"shortTime\": \"h:mm a\"\n  },\n  \"NUMBER_FORMATS\": {\n    \"CURRENCY_SYM\": \"$\",\n    \"DECIMAL_SEP\": \".\",\n    \"GROUP_SEP\": \",\",\n    \"PATTERNS\": [\n      {\n        \"gSize\": 3,\n        \"lgSize\": 3,\n        \"maxFrac\": 3,\n        \"minFrac\": 0,\n        \"minInt\": 1,\n        \"negPre\": \"-\",\n        \"negSuf\": \"\",\n        \"posPre\": \"\",\n        \"posSuf\": \"\"\n      },\n      {\n        \"gSize\": 3,\n        \"lgSize\": 3,\n        \"maxFrac\": 2,\n        \"minFrac\": 2,\n        \"minInt\": 1,\n        \"negPre\": \"-\\u00a4\",\n        \"negSuf\": \"\",\n        \"posPre\": \"\\u00a4\",\n        \"posSuf\": \"\"\n      }\n    ]\n  },\n  \"id\": \"en-us\",\n  \"localeID\": \"en_US\",\n  \"pluralCat\": function(n, opt_precision) {  var i = n | 0;  var vf = getVF(n, opt_precision);  if (i == 1 && vf.v == 0) {    return PLURAL_CATEGORY.ONE;  }  return PLURAL_CATEGORY.OTHER;}\n});\n}]);\n\n  jqLite(function() {\n    angularInit(window.document, bootstrap);\n  });\n\n})(window);\n\n!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend('<style type=\"text/css\">@charset \"UTF-8\";[ng\\\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\\\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/angular/angular.js\n// module id = 10\n// module chunks = 0","module.exports = \"\\n<!--\\nCopyright 2017-present Open Networking Foundation\\n\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\");\\nyou may not use this file except in compliance with the License.\\nYou may obtain a copy of the License at\\n\\nhttp://www.apache.org/licenses/LICENSE-2.0\\n\\nUnless required by applicable law or agreed to in writing, software\\ndistributed under the License is distributed on an \\\"AS IS\\\" BASIS,\\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\\nSee the License for the specific language governing permissions and\\nlimitations under the License.\\n-->\\n\\n<div class = \\\"elinepanel\\\">\\n  <h1>ELine Overview</h1>\\n  <form ng-submit=\\\"vm.saveEline(vm.eng.eline)\\\">\\n    <div class=\\\"form-group\\\" ng-hide=\\\"vm.eng.createMode\\\">\\n      <label>ID</label><br/>\\n      <p>{{vm.eng.eline.id}}</p>\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"name\\\">Name</label>\\n      <input required class=\\\"form-control\\\" id=\\\"name\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.name\\\" ng-model=\\\"vm.eng.eline.name\\\">\\n    </div>\\n    <div class=\\\"form-group\\\" ng-hide=\\\"vm.eng.createMode\\\">\\n      <label>Backend Status</label><br/>\\n      <p>{{vm.eng.eline.backend_status}}</p>\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"cpi1\\\">Connect point 1 ID</label>\\n      <input required class=\\\"form-control\\\" id=\\\"cpi1\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.connect_point_1_id\\\" ng-model=\\\"vm.eng.eline.connect_point_1_id\\\">\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"cpi2\\\">Connect point 2 ID</label>\\n      <input required class=\\\"form-control\\\" id=\\\"cpi2\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.connect_point_2_id\\\" ng-model=\\\"vm.eng.eline.connect_point_2_id\\\">\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"bwps\\\">Bandwidth Profile</label>\\n      <select required class=\\\"form-control\\\"\\n              id=\\\"bwps\\\"\\n              ng-model=\\\"vm.eng.eline.bwp\\\"\\n              ng-options=\\\"bwp.name as bwp.name for bwp in vm.eng.bwps | orderBy:'name'\\\"\\n      >\\n      </select>\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"sitename\\\">CORD Site Name</label>\\n      <input required class=\\\"form-control\\\" id=\\\"sitename\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.cord_site_name\\\" ng-model=\\\"vm.eng.eline.cord_site_name\\\">\\n    </div>\\n    <div class=\\\"form-group\\\">\\n      <label for=\\\"vlanids\\\">Vlan IDs</label>\\n      <input required class=\\\"form-control\\\" id=\\\"vlanids\\\" type=\\\"text\\\" ng-value=\\\"vm.eng.eline.vlanids\\\" ng-model=\\\"vm.eng.eline.vlanids\\\">\\n    </div>\\n    <div class=\\\"form-group\\\" style=\\\"text-align: center\\\">\\n      <button type=\\\"submit\\\" class=\\\"btn btn-success btn-block\\\">Save Changes</button>\\n    </div>\\n  </form>\\n  <button type=\\\"button\\\" class=\\\"btn btn-danger btn-block\\\" ng-click=\\\"vm.eng.elinePanel({}, vm.eng.eline, false)\\\">Close</button>\\n  <button type=\\\"button\\\" class=\\\"btn btn-danger delete-eline\\\" ng-click=\\\"vm.deleteEline(vm.eng.eline)\\\">Delete Eline</button>\\n</div>\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/components/eline-side.component.html\n// module id = 11\n// module chunks = 0","module.exports = \"\\n<!--\\nCopyright 2017-present Open Networking Foundation\\n\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\");\\nyou may not use this file except in compliance with the License.\\nYou may obtain a copy of the License at\\n\\nhttp://www.apache.org/licenses/LICENSE-2.0\\n\\nUnless required by applicable law or agreed to in writing, software\\ndistributed under the License is distributed on an \\\"AS IS\\\" BASIS,\\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\\nSee the License for the specific language governing permissions and\\nlimitations under the License.\\n-->\\n\\n\\n<div class = \\\"row\\\">\\n  <div class = \\\"col-xs-12\\\">\\n    <h1>Enterprise Network Map</h1>\\n    <div map-lazy-load=\\\"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4\\\">\\n      <ng-map\\n        default-style=\\\"false\\\"\\n        id=\\\"foobar\\\"\\n        center=\\\"0,0\\\"\\n        disable-default-u-i=\\\"true\\\"\\n        map-type-id=\\\"ROADMAP\\\"\\n        zoom-control=\\\"true\\\"\\n        min-zoom=\\\"2\\\"\\n        styles=\\\"{{vm.mapStyles}}\\\"\\n      >\\n        <!--Markers-->\\n        <marker\\n          ng-repeat=\\\"uni in vm.unis\\\"\\n          id=\\\"marker-{{uni.id}}\\\"\\n          position=\\\"{{uni.latlng.toString()}}\\\"\\n          icon=\\\"{{vm.MapConfig.marker}}\\\"\\n          on-click=\\\"vm.showUni(uni)\\\"\\n        >\\n        </marker>\\n\\n        <!--Marker Info Window-->\\n\\n        <info-window id = \\\"uni-info\\\">\\n          <div class = \\\"marker-info\\\">\\n            <h4>{{vm.current_uni.name}}</h4>\\n            <p>\\n              <b>LatLng: </b>{{vm.current_uni.latlng.toString()}}<br/>\\n              <b>Cpe id: </b>{{vm.current_uni.cpe_id}}<br/>\\n              <b>Tenant: </b>{{vm.current_uni.tenant}}<br/>\\n            </p>\\n            <button ng-show=\\\"vm.canCreateEline\\\" ng-click=\\\"vm.createConnection(vm.current_uni)()\\\">Create connection</button>\\n            <button ng-show=\\\"!vm.canCreateEline && !uni.eline_start\\\" ng-click=\\\"vm.finishConnection(vm.current_uni)\\\">Finish connection</button>\\n          </div>\\n        </info-window>\\n\\n        <!--Connections-->\\n\\n        <shape\\n          ng-repeat=\\\"eline in vm.elines\\\"\\n          name=\\\"polyline\\\"\\n          id=\\\"eline-{{eline.id}}\\\"\\n          path=\\\"{{eline.path}}\\\"\\n          stroke-color=\\\"{{vm.colorLine(eline.backend_status)}}\\\"\\n          stroke-opacity=\\\"1.0\\\"\\n          stroke-weight=\\\"5\\\"\\n          on-click=\\\"vm.elinePanel({{eline}}, true)\\\"\\n        >\\n        </shape>\\n\\n      </ng-map>\\n\\n    </div>\\n    Changes may not display until page refresh.\\n  </div>\\n</div>\\n<!--\\\"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4\\\"-->\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/components/engMap.component.html\n// module id = 12\n// module chunks = 0","/**\n * @license\n * Lodash <https://lodash.com/>\n * Copyright JS Foundation and other contributors <https://js.foundation/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n;(function() {\n\n  /** Used as a safe reference for `undefined` in pre-ES5 environments. */\n  var undefined;\n\n  /** Used as the semantic version number. */\n  var VERSION = '4.17.4';\n\n  /** Used as the size to enable large array optimizations. */\n  var LARGE_ARRAY_SIZE = 200;\n\n  /** Error message constants. */\n  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',\n      FUNC_ERROR_TEXT = 'Expected a function';\n\n  /** Used to stand-in for `undefined` hash values. */\n  var HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n  /** Used as the maximum memoize cache size. */\n  var MAX_MEMOIZE_SIZE = 500;\n\n  /** Used as the internal argument placeholder. */\n  var PLACEHOLDER = '__lodash_placeholder__';\n\n  /** Used to compose bitmasks for cloning. */\n  var CLONE_DEEP_FLAG = 1,\n      CLONE_FLAT_FLAG = 2,\n      CLONE_SYMBOLS_FLAG = 4;\n\n  /** Used to compose bitmasks for value comparisons. */\n  var COMPARE_PARTIAL_FLAG = 1,\n      COMPARE_UNORDERED_FLAG = 2;\n\n  /** Used to compose bitmasks for function metadata. */\n  var WRAP_BIND_FLAG = 1,\n      WRAP_BIND_KEY_FLAG = 2,\n      WRAP_CURRY_BOUND_FLAG = 4,\n      WRAP_CURRY_FLAG = 8,\n      WRAP_CURRY_RIGHT_FLAG = 16,\n      WRAP_PARTIAL_FLAG = 32,\n      WRAP_PARTIAL_RIGHT_FLAG = 64,\n      WRAP_ARY_FLAG = 128,\n      WRAP_REARG_FLAG = 256,\n      WRAP_FLIP_FLAG = 512;\n\n  /** Used as default options for `_.truncate`. */\n  var DEFAULT_TRUNC_LENGTH = 30,\n      DEFAULT_TRUNC_OMISSION = '...';\n\n  /** Used to detect hot functions by number of calls within a span of milliseconds. */\n  var HOT_COUNT = 800,\n      HOT_SPAN = 16;\n\n  /** Used to indicate the type of lazy iteratees. */\n  var LAZY_FILTER_FLAG = 1,\n      LAZY_MAP_FLAG = 2,\n      LAZY_WHILE_FLAG = 3;\n\n  /** Used as references for various `Number` constants. */\n  var INFINITY = 1 / 0,\n      MAX_SAFE_INTEGER = 9007199254740991,\n      MAX_INTEGER = 1.7976931348623157e+308,\n      NAN = 0 / 0;\n\n  /** Used as references for the maximum length and index of an array. */\n  var MAX_ARRAY_LENGTH = 4294967295,\n      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,\n      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;\n\n  /** Used to associate wrap methods with their bit flags. */\n  var wrapFlags = [\n    ['ary', WRAP_ARY_FLAG],\n    ['bind', WRAP_BIND_FLAG],\n    ['bindKey', WRAP_BIND_KEY_FLAG],\n    ['curry', WRAP_CURRY_FLAG],\n    ['curryRight', WRAP_CURRY_RIGHT_FLAG],\n    ['flip', WRAP_FLIP_FLAG],\n    ['partial', WRAP_PARTIAL_FLAG],\n    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],\n    ['rearg', WRAP_REARG_FLAG]\n  ];\n\n  /** `Object#toString` result references. */\n  var argsTag = '[object Arguments]',\n      arrayTag = '[object Array]',\n      asyncTag = '[object AsyncFunction]',\n      boolTag = '[object Boolean]',\n      dateTag = '[object Date]',\n      domExcTag = '[object DOMException]',\n      errorTag = '[object Error]',\n      funcTag = '[object Function]',\n      genTag = '[object GeneratorFunction]',\n      mapTag = '[object Map]',\n      numberTag = '[object Number]',\n      nullTag = '[object Null]',\n      objectTag = '[object Object]',\n      promiseTag = '[object Promise]',\n      proxyTag = '[object Proxy]',\n      regexpTag = '[object RegExp]',\n      setTag = '[object Set]',\n      stringTag = '[object String]',\n      symbolTag = '[object Symbol]',\n      undefinedTag = '[object Undefined]',\n      weakMapTag = '[object WeakMap]',\n      weakSetTag = '[object WeakSet]';\n\n  var arrayBufferTag = '[object ArrayBuffer]',\n      dataViewTag = '[object DataView]',\n      float32Tag = '[object Float32Array]',\n      float64Tag = '[object Float64Array]',\n      int8Tag = '[object Int8Array]',\n      int16Tag = '[object Int16Array]',\n      int32Tag = '[object Int32Array]',\n      uint8Tag = '[object Uint8Array]',\n      uint8ClampedTag = '[object Uint8ClampedArray]',\n      uint16Tag = '[object Uint16Array]',\n      uint32Tag = '[object Uint32Array]';\n\n  /** Used to match empty string literals in compiled template source. */\n  var reEmptyStringLeading = /\\b__p \\+= '';/g,\n      reEmptyStringMiddle = /\\b(__p \\+=) '' \\+/g,\n      reEmptyStringTrailing = /(__e\\(.*?\\)|\\b__t\\)) \\+\\n'';/g;\n\n  /** Used to match HTML entities and HTML characters. */\n  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,\n      reUnescapedHtml = /[&<>\"']/g,\n      reHasEscapedHtml = RegExp(reEscapedHtml.source),\n      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);\n\n  /** Used to match template delimiters. */\n  var reEscape = /<%-([\\s\\S]+?)%>/g,\n      reEvaluate = /<%([\\s\\S]+?)%>/g,\n      reInterpolate = /<%=([\\s\\S]+?)%>/g;\n\n  /** Used to match property names within property paths. */\n  var reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n      reIsPlainProp = /^\\w*$/,\n      reLeadingDot = /^\\./,\n      rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n  /**\n   * Used to match `RegExp`\n   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n   */\n  var reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g,\n      reHasRegExpChar = RegExp(reRegExpChar.source);\n\n  /** Used to match leading and trailing whitespace. */\n  var reTrim = /^\\s+|\\s+$/g,\n      reTrimStart = /^\\s+/,\n      reTrimEnd = /\\s+$/;\n\n  /** Used to match wrap detail comments. */\n  var reWrapComment = /\\{(?:\\n\\/\\* \\[wrapped with .+\\] \\*\\/)?\\n?/,\n      reWrapDetails = /\\{\\n\\/\\* \\[wrapped with (.+)\\] \\*/,\n      reSplitDetails = /,? & /;\n\n  /** Used to match words composed of alphanumeric characters. */\n  var reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n  /** Used to match backslashes in property paths. */\n  var reEscapeChar = /\\\\(\\\\)?/g;\n\n  /**\n   * Used to match\n   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).\n   */\n  var reEsTemplate = /\\$\\{([^\\\\}]*(?:\\\\.[^\\\\}]*)*)\\}/g;\n\n  /** Used to match `RegExp` flags from their coerced string values. */\n  var reFlags = /\\w*$/;\n\n  /** Used to detect bad signed hexadecimal string values. */\n  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n  /** Used to detect binary string values. */\n  var reIsBinary = /^0b[01]+$/i;\n\n  /** Used to detect host constructors (Safari). */\n  var reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n  /** Used to detect octal string values. */\n  var reIsOctal = /^0o[0-7]+$/i;\n\n  /** Used to detect unsigned integer values. */\n  var reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n  /** Used to match Latin Unicode letters (excluding mathematical operators). */\n  var reLatin = /[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g;\n\n  /** Used to ensure capturing order of template delimiters. */\n  var reNoMatch = /($^)/;\n\n  /** Used to match unescaped characters in compiled string literals. */\n  var reUnescapedString = /['\\n\\r\\u2028\\u2029\\\\]/g;\n\n  /** Used to compose unicode character classes. */\n  var rsAstralRange = '\\\\ud800-\\\\udfff',\n      rsComboMarksRange = '\\\\u0300-\\\\u036f',\n      reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n      rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n      rsDingbatRange = '\\\\u2700-\\\\u27bf',\n      rsLowerRange = 'a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff',\n      rsMathOpRange = '\\\\xac\\\\xb1\\\\xd7\\\\xf7',\n      rsNonCharRange = '\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf',\n      rsPunctuationRange = '\\\\u2000-\\\\u206f',\n      rsSpaceRange = ' \\\\t\\\\x0b\\\\f\\\\xa0\\\\ufeff\\\\n\\\\r\\\\u2028\\\\u2029\\\\u1680\\\\u180e\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u202f\\\\u205f\\\\u3000',\n      rsUpperRange = 'A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde',\n      rsVarRange = '\\\\ufe0e\\\\ufe0f',\n      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;\n\n  /** Used to compose unicode capture groups. */\n  var rsApos = \"['\\u2019]\",\n      rsAstral = '[' + rsAstralRange + ']',\n      rsBreak = '[' + rsBreakRange + ']',\n      rsCombo = '[' + rsComboRange + ']',\n      rsDigits = '\\\\d+',\n      rsDingbat = '[' + rsDingbatRange + ']',\n      rsLower = '[' + rsLowerRange + ']',\n      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',\n      rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n      rsNonAstral = '[^' + rsAstralRange + ']',\n      rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n      rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n      rsUpper = '[' + rsUpperRange + ']',\n      rsZWJ = '\\\\u200d';\n\n  /** Used to compose unicode regexes. */\n  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',\n      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',\n      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',\n      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',\n      reOptMod = rsModifier + '?',\n      rsOptVar = '[' + rsVarRange + ']?',\n      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n      rsOrdLower = '\\\\d*(?:(?:1st|2nd|3rd|(?![123])\\\\dth)\\\\b)',\n      rsOrdUpper = '\\\\d*(?:(?:1ST|2ND|3RD|(?![123])\\\\dTH)\\\\b)',\n      rsSeq = rsOptVar + reOptMod + rsOptJoin,\n      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,\n      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n  /** Used to match apostrophes. */\n  var reApos = RegExp(rsApos, 'g');\n\n  /**\n   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and\n   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).\n   */\n  var reComboMark = RegExp(rsCombo, 'g');\n\n  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\n  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n  /** Used to match complex or compound words. */\n  var reUnicodeWord = RegExp([\n    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',\n    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',\n    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,\n    rsUpper + '+' + rsOptContrUpper,\n    rsOrdUpper,\n    rsOrdLower,\n    rsDigits,\n    rsEmoji\n  ].join('|'), 'g');\n\n  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\n  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');\n\n  /** Used to detect strings that need a more robust regexp to match words. */\n  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;\n\n  /** Used to assign default `context` object properties. */\n  var contextProps = [\n    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',\n    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',\n    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',\n    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',\n    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'\n  ];\n\n  /** Used to make template sourceURLs easier to identify. */\n  var templateCounter = -1;\n\n  /** Used to identify `toStringTag` values of typed arrays. */\n  var typedArrayTags = {};\n  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\n  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\n  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\n  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\n  typedArrayTags[uint32Tag] = true;\n  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =\n  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\n  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\n  typedArrayTags[errorTag] = typedArrayTags[funcTag] =\n  typedArrayTags[mapTag] = typedArrayTags[numberTag] =\n  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =\n  typedArrayTags[setTag] = typedArrayTags[stringTag] =\n  typedArrayTags[weakMapTag] = false;\n\n  /** Used to identify `toStringTag` values supported by `_.clone`. */\n  var cloneableTags = {};\n  cloneableTags[argsTag] = cloneableTags[arrayTag] =\n  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\n  cloneableTags[boolTag] = cloneableTags[dateTag] =\n  cloneableTags[float32Tag] = cloneableTags[float64Tag] =\n  cloneableTags[int8Tag] = cloneableTags[int16Tag] =\n  cloneableTags[int32Tag] = cloneableTags[mapTag] =\n  cloneableTags[numberTag] = cloneableTags[objectTag] =\n  cloneableTags[regexpTag] = cloneableTags[setTag] =\n  cloneableTags[stringTag] = cloneableTags[symbolTag] =\n  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\n  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\n  cloneableTags[errorTag] = cloneableTags[funcTag] =\n  cloneableTags[weakMapTag] = false;\n\n  /** Used to map Latin Unicode letters to basic Latin letters. */\n  var deburredLetters = {\n    // Latin-1 Supplement block.\n    '\\xc0': 'A',  '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n    '\\xe0': 'a',  '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n    '\\xc7': 'C',  '\\xe7': 'c',\n    '\\xd0': 'D',  '\\xf0': 'd',\n    '\\xc8': 'E',  '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n    '\\xe8': 'e',  '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n    '\\xcc': 'I',  '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n    '\\xec': 'i',  '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n    '\\xd1': 'N',  '\\xf1': 'n',\n    '\\xd2': 'O',  '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n    '\\xf2': 'o',  '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n    '\\xd9': 'U',  '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n    '\\xf9': 'u',  '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n    '\\xdd': 'Y',  '\\xfd': 'y', '\\xff': 'y',\n    '\\xc6': 'Ae', '\\xe6': 'ae',\n    '\\xde': 'Th', '\\xfe': 'th',\n    '\\xdf': 'ss',\n    // Latin Extended-A block.\n    '\\u0100': 'A',  '\\u0102': 'A', '\\u0104': 'A',\n    '\\u0101': 'a',  '\\u0103': 'a', '\\u0105': 'a',\n    '\\u0106': 'C',  '\\u0108': 'C', '\\u010a': 'C', '\\u010c': 'C',\n    '\\u0107': 'c',  '\\u0109': 'c', '\\u010b': 'c', '\\u010d': 'c',\n    '\\u010e': 'D',  '\\u0110': 'D', '\\u010f': 'd', '\\u0111': 'd',\n    '\\u0112': 'E',  '\\u0114': 'E', '\\u0116': 'E', '\\u0118': 'E', '\\u011a': 'E',\n    '\\u0113': 'e',  '\\u0115': 'e', '\\u0117': 'e', '\\u0119': 'e', '\\u011b': 'e',\n    '\\u011c': 'G',  '\\u011e': 'G', '\\u0120': 'G', '\\u0122': 'G',\n    '\\u011d': 'g',  '\\u011f': 'g', '\\u0121': 'g', '\\u0123': 'g',\n    '\\u0124': 'H',  '\\u0126': 'H', '\\u0125': 'h', '\\u0127': 'h',\n    '\\u0128': 'I',  '\\u012a': 'I', '\\u012c': 'I', '\\u012e': 'I', '\\u0130': 'I',\n    '\\u0129': 'i',  '\\u012b': 'i', '\\u012d': 'i', '\\u012f': 'i', '\\u0131': 'i',\n    '\\u0134': 'J',  '\\u0135': 'j',\n    '\\u0136': 'K',  '\\u0137': 'k', '\\u0138': 'k',\n    '\\u0139': 'L',  '\\u013b': 'L', '\\u013d': 'L', '\\u013f': 'L', '\\u0141': 'L',\n    '\\u013a': 'l',  '\\u013c': 'l', '\\u013e': 'l', '\\u0140': 'l', '\\u0142': 'l',\n    '\\u0143': 'N',  '\\u0145': 'N', '\\u0147': 'N', '\\u014a': 'N',\n    '\\u0144': 'n',  '\\u0146': 'n', '\\u0148': 'n', '\\u014b': 'n',\n    '\\u014c': 'O',  '\\u014e': 'O', '\\u0150': 'O',\n    '\\u014d': 'o',  '\\u014f': 'o', '\\u0151': 'o',\n    '\\u0154': 'R',  '\\u0156': 'R', '\\u0158': 'R',\n    '\\u0155': 'r',  '\\u0157': 'r', '\\u0159': 'r',\n    '\\u015a': 'S',  '\\u015c': 'S', '\\u015e': 'S', '\\u0160': 'S',\n    '\\u015b': 's',  '\\u015d': 's', '\\u015f': 's', '\\u0161': 's',\n    '\\u0162': 'T',  '\\u0164': 'T', '\\u0166': 'T',\n    '\\u0163': 't',  '\\u0165': 't', '\\u0167': 't',\n    '\\u0168': 'U',  '\\u016a': 'U', '\\u016c': 'U', '\\u016e': 'U', '\\u0170': 'U', '\\u0172': 'U',\n    '\\u0169': 'u',  '\\u016b': 'u', '\\u016d': 'u', '\\u016f': 'u', '\\u0171': 'u', '\\u0173': 'u',\n    '\\u0174': 'W',  '\\u0175': 'w',\n    '\\u0176': 'Y',  '\\u0177': 'y', '\\u0178': 'Y',\n    '\\u0179': 'Z',  '\\u017b': 'Z', '\\u017d': 'Z',\n    '\\u017a': 'z',  '\\u017c': 'z', '\\u017e': 'z',\n    '\\u0132': 'IJ', '\\u0133': 'ij',\n    '\\u0152': 'Oe', '\\u0153': 'oe',\n    '\\u0149': \"'n\", '\\u017f': 's'\n  };\n\n  /** Used to map characters to HTML entities. */\n  var htmlEscapes = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  };\n\n  /** Used to map HTML entities to characters. */\n  var htmlUnescapes = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#39;': \"'\"\n  };\n\n  /** Used to escape characters for inclusion in compiled string literals. */\n  var stringEscapes = {\n    '\\\\': '\\\\',\n    \"'\": \"'\",\n    '\\n': 'n',\n    '\\r': 'r',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  /** Built-in method references without a dependency on `root`. */\n  var freeParseFloat = parseFloat,\n      freeParseInt = parseInt;\n\n  /** Detect free variable `global` from Node.js. */\n  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n  /** Detect free variable `self`. */\n  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n  /** Used as a reference to the global object. */\n  var root = freeGlobal || freeSelf || Function('return this')();\n\n  /** Detect free variable `exports`. */\n  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n  /** Detect free variable `module`. */\n  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n  /** Detect the popular CommonJS extension `module.exports`. */\n  var moduleExports = freeModule && freeModule.exports === freeExports;\n\n  /** Detect free variable `process` from Node.js. */\n  var freeProcess = moduleExports && freeGlobal.process;\n\n  /** Used to access faster Node.js helpers. */\n  var nodeUtil = (function() {\n    try {\n      return freeProcess && freeProcess.binding && freeProcess.binding('util');\n    } catch (e) {}\n  }());\n\n  /* Node.js helper references. */\n  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,\n      nodeIsDate = nodeUtil && nodeUtil.isDate,\n      nodeIsMap = nodeUtil && nodeUtil.isMap,\n      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,\n      nodeIsSet = nodeUtil && nodeUtil.isSet,\n      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Adds the key-value `pair` to `map`.\n   *\n   * @private\n   * @param {Object} map The map to modify.\n   * @param {Array} pair The key-value pair to add.\n   * @returns {Object} Returns `map`.\n   */\n  function addMapEntry(map, pair) {\n    // Don't return `map.set` because it's not chainable in IE 11.\n    map.set(pair[0], pair[1]);\n    return map;\n  }\n\n  /**\n   * Adds `value` to `set`.\n   *\n   * @private\n   * @param {Object} set The set to modify.\n   * @param {*} value The value to add.\n   * @returns {Object} Returns `set`.\n   */\n  function addSetEntry(set, value) {\n    // Don't return `set.add` because it's not chainable in IE 11.\n    set.add(value);\n    return set;\n  }\n\n  /**\n   * A faster alternative to `Function#apply`, this function invokes `func`\n   * with the `this` binding of `thisArg` and the arguments of `args`.\n   *\n   * @private\n   * @param {Function} func The function to invoke.\n   * @param {*} thisArg The `this` binding of `func`.\n   * @param {Array} args The arguments to invoke `func` with.\n   * @returns {*} Returns the result of `func`.\n   */\n  function apply(func, thisArg, args) {\n    switch (args.length) {\n      case 0: return func.call(thisArg);\n      case 1: return func.call(thisArg, args[0]);\n      case 2: return func.call(thisArg, args[0], args[1]);\n      case 3: return func.call(thisArg, args[0], args[1], args[2]);\n    }\n    return func.apply(thisArg, args);\n  }\n\n  /**\n   * A specialized version of `baseAggregator` for arrays.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} setter The function to set `accumulator` values.\n   * @param {Function} iteratee The iteratee to transform keys.\n   * @param {Object} accumulator The initial aggregated object.\n   * @returns {Function} Returns `accumulator`.\n   */\n  function arrayAggregator(array, setter, iteratee, accumulator) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      var value = array[index];\n      setter(accumulator, value, iteratee(value), array);\n    }\n    return accumulator;\n  }\n\n  /**\n   * A specialized version of `_.forEach` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns `array`.\n   */\n  function arrayEach(array, iteratee) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (iteratee(array[index], index, array) === false) {\n        break;\n      }\n    }\n    return array;\n  }\n\n  /**\n   * A specialized version of `_.forEachRight` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns `array`.\n   */\n  function arrayEachRight(array, iteratee) {\n    var length = array == null ? 0 : array.length;\n\n    while (length--) {\n      if (iteratee(array[length], length, array) === false) {\n        break;\n      }\n    }\n    return array;\n  }\n\n  /**\n   * A specialized version of `_.every` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} predicate The function invoked per iteration.\n   * @returns {boolean} Returns `true` if all elements pass the predicate check,\n   *  else `false`.\n   */\n  function arrayEvery(array, predicate) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (!predicate(array[index], index, array)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  /**\n   * A specialized version of `_.filter` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} predicate The function invoked per iteration.\n   * @returns {Array} Returns the new filtered array.\n   */\n  function arrayFilter(array, predicate) {\n    var index = -1,\n        length = array == null ? 0 : array.length,\n        resIndex = 0,\n        result = [];\n\n    while (++index < length) {\n      var value = array[index];\n      if (predicate(value, index, array)) {\n        result[resIndex++] = value;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * A specialized version of `_.includes` for arrays without support for\n   * specifying an index to search from.\n   *\n   * @private\n   * @param {Array} [array] The array to inspect.\n   * @param {*} target The value to search for.\n   * @returns {boolean} Returns `true` if `target` is found, else `false`.\n   */\n  function arrayIncludes(array, value) {\n    var length = array == null ? 0 : array.length;\n    return !!length && baseIndexOf(array, value, 0) > -1;\n  }\n\n  /**\n   * This function is like `arrayIncludes` except that it accepts a comparator.\n   *\n   * @private\n   * @param {Array} [array] The array to inspect.\n   * @param {*} target The value to search for.\n   * @param {Function} comparator The comparator invoked per element.\n   * @returns {boolean} Returns `true` if `target` is found, else `false`.\n   */\n  function arrayIncludesWith(array, value, comparator) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (comparator(value, array[index])) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * A specialized version of `_.map` for arrays without support for iteratee\n   * shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns the new mapped array.\n   */\n  function arrayMap(array, iteratee) {\n    var index = -1,\n        length = array == null ? 0 : array.length,\n        result = Array(length);\n\n    while (++index < length) {\n      result[index] = iteratee(array[index], index, array);\n    }\n    return result;\n  }\n\n  /**\n   * Appends the elements of `values` to `array`.\n   *\n   * @private\n   * @param {Array} array The array to modify.\n   * @param {Array} values The values to append.\n   * @returns {Array} Returns `array`.\n   */\n  function arrayPush(array, values) {\n    var index = -1,\n        length = values.length,\n        offset = array.length;\n\n    while (++index < length) {\n      array[offset + index] = values[index];\n    }\n    return array;\n  }\n\n  /**\n   * A specialized version of `_.reduce` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @param {*} [accumulator] The initial value.\n   * @param {boolean} [initAccum] Specify using the first element of `array` as\n   *  the initial value.\n   * @returns {*} Returns the accumulated value.\n   */\n  function arrayReduce(array, iteratee, accumulator, initAccum) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    if (initAccum && length) {\n      accumulator = array[++index];\n    }\n    while (++index < length) {\n      accumulator = iteratee(accumulator, array[index], index, array);\n    }\n    return accumulator;\n  }\n\n  /**\n   * A specialized version of `_.reduceRight` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @param {*} [accumulator] The initial value.\n   * @param {boolean} [initAccum] Specify using the last element of `array` as\n   *  the initial value.\n   * @returns {*} Returns the accumulated value.\n   */\n  function arrayReduceRight(array, iteratee, accumulator, initAccum) {\n    var length = array == null ? 0 : array.length;\n    if (initAccum && length) {\n      accumulator = array[--length];\n    }\n    while (length--) {\n      accumulator = iteratee(accumulator, array[length], length, array);\n    }\n    return accumulator;\n  }\n\n  /**\n   * A specialized version of `_.some` for arrays without support for iteratee\n   * shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} predicate The function invoked per iteration.\n   * @returns {boolean} Returns `true` if any element passes the predicate check,\n   *  else `false`.\n   */\n  function arraySome(array, predicate) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (predicate(array[index], index, array)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Gets the size of an ASCII `string`.\n   *\n   * @private\n   * @param {string} string The string inspect.\n   * @returns {number} Returns the string size.\n   */\n  var asciiSize = baseProperty('length');\n\n  /**\n   * Converts an ASCII `string` to an array.\n   *\n   * @private\n   * @param {string} string The string to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function asciiToArray(string) {\n    return string.split('');\n  }\n\n  /**\n   * Splits an ASCII `string` into an array of its words.\n   *\n   * @private\n   * @param {string} The string to inspect.\n   * @returns {Array} Returns the words of `string`.\n   */\n  function asciiWords(string) {\n    return string.match(reAsciiWord) || [];\n  }\n\n  /**\n   * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n   * without support for iteratee shorthands, which iterates over `collection`\n   * using `eachFunc`.\n   *\n   * @private\n   * @param {Array|Object} collection The collection to inspect.\n   * @param {Function} predicate The function invoked per iteration.\n   * @param {Function} eachFunc The function to iterate over `collection`.\n   * @returns {*} Returns the found element or its key, else `undefined`.\n   */\n  function baseFindKey(collection, predicate, eachFunc) {\n    var result;\n    eachFunc(collection, function(value, key, collection) {\n      if (predicate(value, key, collection)) {\n        result = key;\n        return false;\n      }\n    });\n    return result;\n  }\n\n  /**\n   * The base implementation of `_.findIndex` and `_.findLastIndex` without\n   * support for iteratee shorthands.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {Function} predicate The function invoked per iteration.\n   * @param {number} fromIndex The index to search from.\n   * @param {boolean} [fromRight] Specify iterating from right to left.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseFindIndex(array, predicate, fromIndex, fromRight) {\n    var length = array.length,\n        index = fromIndex + (fromRight ? 1 : -1);\n\n    while ((fromRight ? index-- : ++index < length)) {\n      if (predicate(array[index], index, array)) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseIndexOf(array, value, fromIndex) {\n    return value === value\n      ? strictIndexOf(array, value, fromIndex)\n      : baseFindIndex(array, baseIsNaN, fromIndex);\n  }\n\n  /**\n   * This function is like `baseIndexOf` except that it accepts a comparator.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @param {Function} comparator The comparator invoked per element.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseIndexOfWith(array, value, fromIndex, comparator) {\n    var index = fromIndex - 1,\n        length = array.length;\n\n    while (++index < length) {\n      if (comparator(array[index], value)) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * The base implementation of `_.isNaN` without support for number objects.\n   *\n   * @private\n   * @param {*} value The value to check.\n   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n   */\n  function baseIsNaN(value) {\n    return value !== value;\n  }\n\n  /**\n   * The base implementation of `_.mean` and `_.meanBy` without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} array The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {number} Returns the mean.\n   */\n  function baseMean(array, iteratee) {\n    var length = array == null ? 0 : array.length;\n    return length ? (baseSum(array, iteratee) / length) : NAN;\n  }\n\n  /**\n   * The base implementation of `_.property` without support for deep paths.\n   *\n   * @private\n   * @param {string} key The key of the property to get.\n   * @returns {Function} Returns the new accessor function.\n   */\n  function baseProperty(key) {\n    return function(object) {\n      return object == null ? undefined : object[key];\n    };\n  }\n\n  /**\n   * The base implementation of `_.propertyOf` without support for deep paths.\n   *\n   * @private\n   * @param {Object} object The object to query.\n   * @returns {Function} Returns the new accessor function.\n   */\n  function basePropertyOf(object) {\n    return function(key) {\n      return object == null ? undefined : object[key];\n    };\n  }\n\n  /**\n   * The base implementation of `_.reduce` and `_.reduceRight`, without support\n   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.\n   *\n   * @private\n   * @param {Array|Object} collection The collection to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @param {*} accumulator The initial value.\n   * @param {boolean} initAccum Specify using the first or last element of\n   *  `collection` as the initial value.\n   * @param {Function} eachFunc The function to iterate over `collection`.\n   * @returns {*} Returns the accumulated value.\n   */\n  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {\n    eachFunc(collection, function(value, index, collection) {\n      accumulator = initAccum\n        ? (initAccum = false, value)\n        : iteratee(accumulator, value, index, collection);\n    });\n    return accumulator;\n  }\n\n  /**\n   * The base implementation of `_.sortBy` which uses `comparer` to define the\n   * sort order of `array` and replaces criteria objects with their corresponding\n   * values.\n   *\n   * @private\n   * @param {Array} array The array to sort.\n   * @param {Function} comparer The function to define sort order.\n   * @returns {Array} Returns `array`.\n   */\n  function baseSortBy(array, comparer) {\n    var length = array.length;\n\n    array.sort(comparer);\n    while (length--) {\n      array[length] = array[length].value;\n    }\n    return array;\n  }\n\n  /**\n   * The base implementation of `_.sum` and `_.sumBy` without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} array The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {number} Returns the sum.\n   */\n  function baseSum(array, iteratee) {\n    var result,\n        index = -1,\n        length = array.length;\n\n    while (++index < length) {\n      var current = iteratee(array[index]);\n      if (current !== undefined) {\n        result = result === undefined ? current : (result + current);\n      }\n    }\n    return result;\n  }\n\n  /**\n   * The base implementation of `_.times` without support for iteratee shorthands\n   * or max array length checks.\n   *\n   * @private\n   * @param {number} n The number of times to invoke `iteratee`.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns the array of results.\n   */\n  function baseTimes(n, iteratee) {\n    var index = -1,\n        result = Array(n);\n\n    while (++index < n) {\n      result[index] = iteratee(index);\n    }\n    return result;\n  }\n\n  /**\n   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array\n   * of key-value pairs for `object` corresponding to the property names of `props`.\n   *\n   * @private\n   * @param {Object} object The object to query.\n   * @param {Array} props The property names to get values for.\n   * @returns {Object} Returns the key-value pairs.\n   */\n  function baseToPairs(object, props) {\n    return arrayMap(props, function(key) {\n      return [key, object[key]];\n    });\n  }\n\n  /**\n   * The base implementation of `_.unary` without support for storing metadata.\n   *\n   * @private\n   * @param {Function} func The function to cap arguments for.\n   * @returns {Function} Returns the new capped function.\n   */\n  function baseUnary(func) {\n    return function(value) {\n      return func(value);\n    };\n  }\n\n  /**\n   * The base implementation of `_.values` and `_.valuesIn` which creates an\n   * array of `object` property values corresponding to the property names\n   * of `props`.\n   *\n   * @private\n   * @param {Object} object The object to query.\n   * @param {Array} props The property names to get values for.\n   * @returns {Object} Returns the array of property values.\n   */\n  function baseValues(object, props) {\n    return arrayMap(props, function(key) {\n      return object[key];\n    });\n  }\n\n  /**\n   * Checks if a `cache` value for `key` exists.\n   *\n   * @private\n   * @param {Object} cache The cache to query.\n   * @param {string} key The key of the entry to check.\n   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n   */\n  function cacheHas(cache, key) {\n    return cache.has(key);\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol\n   * that is not found in the character symbols.\n   *\n   * @private\n   * @param {Array} strSymbols The string symbols to inspect.\n   * @param {Array} chrSymbols The character symbols to find.\n   * @returns {number} Returns the index of the first unmatched string symbol.\n   */\n  function charsStartIndex(strSymbols, chrSymbols) {\n    var index = -1,\n        length = strSymbols.length;\n\n    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n    return index;\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol\n   * that is not found in the character symbols.\n   *\n   * @private\n   * @param {Array} strSymbols The string symbols to inspect.\n   * @param {Array} chrSymbols The character symbols to find.\n   * @returns {number} Returns the index of the last unmatched string symbol.\n   */\n  function charsEndIndex(strSymbols, chrSymbols) {\n    var index = strSymbols.length;\n\n    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n    return index;\n  }\n\n  /**\n   * Gets the number of `placeholder` occurrences in `array`.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} placeholder The placeholder to search for.\n   * @returns {number} Returns the placeholder count.\n   */\n  function countHolders(array, placeholder) {\n    var length = array.length,\n        result = 0;\n\n    while (length--) {\n      if (array[length] === placeholder) {\n        ++result;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A\n   * letters to basic Latin letters.\n   *\n   * @private\n   * @param {string} letter The matched letter to deburr.\n   * @returns {string} Returns the deburred letter.\n   */\n  var deburrLetter = basePropertyOf(deburredLetters);\n\n  /**\n   * Used by `_.escape` to convert characters to HTML entities.\n   *\n   * @private\n   * @param {string} chr The matched character to escape.\n   * @returns {string} Returns the escaped character.\n   */\n  var escapeHtmlChar = basePropertyOf(htmlEscapes);\n\n  /**\n   * Used by `_.template` to escape characters for inclusion in compiled string literals.\n   *\n   * @private\n   * @param {string} chr The matched character to escape.\n   * @returns {string} Returns the escaped character.\n   */\n  function escapeStringChar(chr) {\n    return '\\\\' + stringEscapes[chr];\n  }\n\n  /**\n   * Gets the value at `key` of `object`.\n   *\n   * @private\n   * @param {Object} [object] The object to query.\n   * @param {string} key The key of the property to get.\n   * @returns {*} Returns the property value.\n   */\n  function getValue(object, key) {\n    return object == null ? undefined : object[key];\n  }\n\n  /**\n   * Checks if `string` contains Unicode symbols.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n   */\n  function hasUnicode(string) {\n    return reHasUnicode.test(string);\n  }\n\n  /**\n   * Checks if `string` contains a word composed of Unicode symbols.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {boolean} Returns `true` if a word is found, else `false`.\n   */\n  function hasUnicodeWord(string) {\n    return reHasUnicodeWord.test(string);\n  }\n\n  /**\n   * Converts `iterator` to an array.\n   *\n   * @private\n   * @param {Object} iterator The iterator to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function iteratorToArray(iterator) {\n    var data,\n        result = [];\n\n    while (!(data = iterator.next()).done) {\n      result.push(data.value);\n    }\n    return result;\n  }\n\n  /**\n   * Converts `map` to its key-value pairs.\n   *\n   * @private\n   * @param {Object} map The map to convert.\n   * @returns {Array} Returns the key-value pairs.\n   */\n  function mapToArray(map) {\n    var index = -1,\n        result = Array(map.size);\n\n    map.forEach(function(value, key) {\n      result[++index] = [key, value];\n    });\n    return result;\n  }\n\n  /**\n   * Creates a unary function that invokes `func` with its argument transformed.\n   *\n   * @private\n   * @param {Function} func The function to wrap.\n   * @param {Function} transform The argument transform.\n   * @returns {Function} Returns the new function.\n   */\n  function overArg(func, transform) {\n    return function(arg) {\n      return func(transform(arg));\n    };\n  }\n\n  /**\n   * Replaces all `placeholder` elements in `array` with an internal placeholder\n   * and returns an array of their indexes.\n   *\n   * @private\n   * @param {Array} array The array to modify.\n   * @param {*} placeholder The placeholder to replace.\n   * @returns {Array} Returns the new array of placeholder indexes.\n   */\n  function replaceHolders(array, placeholder) {\n    var index = -1,\n        length = array.length,\n        resIndex = 0,\n        result = [];\n\n    while (++index < length) {\n      var value = array[index];\n      if (value === placeholder || value === PLACEHOLDER) {\n        array[index] = PLACEHOLDER;\n        result[resIndex++] = index;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Converts `set` to an array of its values.\n   *\n   * @private\n   * @param {Object} set The set to convert.\n   * @returns {Array} Returns the values.\n   */\n  function setToArray(set) {\n    var index = -1,\n        result = Array(set.size);\n\n    set.forEach(function(value) {\n      result[++index] = value;\n    });\n    return result;\n  }\n\n  /**\n   * Converts `set` to its value-value pairs.\n   *\n   * @private\n   * @param {Object} set The set to convert.\n   * @returns {Array} Returns the value-value pairs.\n   */\n  function setToPairs(set) {\n    var index = -1,\n        result = Array(set.size);\n\n    set.forEach(function(value) {\n      result[++index] = [value, value];\n    });\n    return result;\n  }\n\n  /**\n   * A specialized version of `_.indexOf` which performs strict equality\n   * comparisons of values, i.e. `===`.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function strictIndexOf(array, value, fromIndex) {\n    var index = fromIndex - 1,\n        length = array.length;\n\n    while (++index < length) {\n      if (array[index] === value) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * A specialized version of `_.lastIndexOf` which performs strict equality\n   * comparisons of values, i.e. `===`.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function strictLastIndexOf(array, value, fromIndex) {\n    var index = fromIndex + 1;\n    while (index--) {\n      if (array[index] === value) {\n        return index;\n      }\n    }\n    return index;\n  }\n\n  /**\n   * Gets the number of symbols in `string`.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {number} Returns the string size.\n   */\n  function stringSize(string) {\n    return hasUnicode(string)\n      ? unicodeSize(string)\n      : asciiSize(string);\n  }\n\n  /**\n   * Converts `string` to an array.\n   *\n   * @private\n   * @param {string} string The string to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function stringToArray(string) {\n    return hasUnicode(string)\n      ? unicodeToArray(string)\n      : asciiToArray(string);\n  }\n\n  /**\n   * Used by `_.unescape` to convert HTML entities to characters.\n   *\n   * @private\n   * @param {string} chr The matched character to unescape.\n   * @returns {string} Returns the unescaped character.\n   */\n  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);\n\n  /**\n   * Gets the size of a Unicode `string`.\n   *\n   * @private\n   * @param {string} string The string inspect.\n   * @returns {number} Returns the string size.\n   */\n  function unicodeSize(string) {\n    var result = reUnicode.lastIndex = 0;\n    while (reUnicode.test(string)) {\n      ++result;\n    }\n    return result;\n  }\n\n  /**\n   * Converts a Unicode `string` to an array.\n   *\n   * @private\n   * @param {string} string The string to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function unicodeToArray(string) {\n    return string.match(reUnicode) || [];\n  }\n\n  /**\n   * Splits a Unicode `string` into an array of its words.\n   *\n   * @private\n   * @param {string} The string to inspect.\n   * @returns {Array} Returns the words of `string`.\n   */\n  function unicodeWords(string) {\n    return string.match(reUnicodeWord) || [];\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Create a new pristine `lodash` function using the `context` object.\n   *\n   * @static\n   * @memberOf _\n   * @since 1.1.0\n   * @category Util\n   * @param {Object} [context=root] The context object.\n   * @returns {Function} Returns a new `lodash` function.\n   * @example\n   *\n   * _.mixin({ 'foo': _.constant('foo') });\n   *\n   * var lodash = _.runInContext();\n   * lodash.mixin({ 'bar': lodash.constant('bar') });\n   *\n   * _.isFunction(_.foo);\n   * // => true\n   * _.isFunction(_.bar);\n   * // => false\n   *\n   * lodash.isFunction(lodash.foo);\n   * // => false\n   * lodash.isFunction(lodash.bar);\n   * // => true\n   *\n   * // Create a suped-up `defer` in Node.js.\n   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;\n   */\n  var runInContext = (function runInContext(context) {\n    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));\n\n    /** Built-in constructor references. */\n    var Array = context.Array,\n        Date = context.Date,\n        Error = context.Error,\n        Function = context.Function,\n        Math = context.Math,\n        Object = context.Object,\n        RegExp = context.RegExp,\n        String = context.String,\n        TypeError = context.TypeError;\n\n    /** Used for built-in method references. */\n    var arrayProto = Array.prototype,\n        funcProto = Function.prototype,\n        objectProto = Object.prototype;\n\n    /** Used to detect overreaching core-js shims. */\n    var coreJsData = context['__core-js_shared__'];\n\n    /** Used to resolve the decompiled source of functions. */\n    var funcToString = funcProto.toString;\n\n    /** Used to check objects for own properties. */\n    var hasOwnProperty = objectProto.hasOwnProperty;\n\n    /** Used to generate unique IDs. */\n    var idCounter = 0;\n\n    /** Used to detect methods masquerading as native. */\n    var maskSrcKey = (function() {\n      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n      return uid ? ('Symbol(src)_1.' + uid) : '';\n    }());\n\n    /**\n     * Used to resolve the\n     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n     * of values.\n     */\n    var nativeObjectToString = objectProto.toString;\n\n    /** Used to infer the `Object` constructor. */\n    var objectCtorString = funcToString.call(Object);\n\n    /** Used to restore the original `_` reference in `_.noConflict`. */\n    var oldDash = root._;\n\n    /** Used to detect if a method is native. */\n    var reIsNative = RegExp('^' +\n      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n      .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n    );\n\n    /** Built-in value references. */\n    var Buffer = moduleExports ? context.Buffer : undefined,\n        Symbol = context.Symbol,\n        Uint8Array = context.Uint8Array,\n        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,\n        getPrototype = overArg(Object.getPrototypeOf, Object),\n        objectCreate = Object.create,\n        propertyIsEnumerable = objectProto.propertyIsEnumerable,\n        splice = arrayProto.splice,\n        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,\n        symIterator = Symbol ? Symbol.iterator : undefined,\n        symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n    var defineProperty = (function() {\n      try {\n        var func = getNative(Object, 'defineProperty');\n        func({}, '', {});\n        return func;\n      } catch (e) {}\n    }());\n\n    /** Mocked built-ins. */\n    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,\n        ctxNow = Date && Date.now !== root.Date.now && Date.now,\n        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;\n\n    /* Built-in method references for those with the same name as other `lodash` methods. */\n    var nativeCeil = Math.ceil,\n        nativeFloor = Math.floor,\n        nativeGetSymbols = Object.getOwnPropertySymbols,\n        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n        nativeIsFinite = context.isFinite,\n        nativeJoin = arrayProto.join,\n        nativeKeys = overArg(Object.keys, Object),\n        nativeMax = Math.max,\n        nativeMin = Math.min,\n        nativeNow = Date.now,\n        nativeParseInt = context.parseInt,\n        nativeRandom = Math.random,\n        nativeReverse = arrayProto.reverse;\n\n    /* Built-in method references that are verified to be native. */\n    var DataView = getNative(context, 'DataView'),\n        Map = getNative(context, 'Map'),\n        Promise = getNative(context, 'Promise'),\n        Set = getNative(context, 'Set'),\n        WeakMap = getNative(context, 'WeakMap'),\n        nativeCreate = getNative(Object, 'create');\n\n    /** Used to store function metadata. */\n    var metaMap = WeakMap && new WeakMap;\n\n    /** Used to lookup unminified function names. */\n    var realNames = {};\n\n    /** Used to detect maps, sets, and weakmaps. */\n    var dataViewCtorString = toSource(DataView),\n        mapCtorString = toSource(Map),\n        promiseCtorString = toSource(Promise),\n        setCtorString = toSource(Set),\n        weakMapCtorString = toSource(WeakMap);\n\n    /** Used to convert symbols to primitives and strings. */\n    var symbolProto = Symbol ? Symbol.prototype : undefined,\n        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,\n        symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a `lodash` object which wraps `value` to enable implicit method\n     * chain sequences. Methods that operate on and return arrays, collections,\n     * and functions can be chained together. Methods that retrieve a single value\n     * or may return a primitive value will automatically end the chain sequence\n     * and return the unwrapped value. Otherwise, the value must be unwrapped\n     * with `_#value`.\n     *\n     * Explicit chain sequences, which must be unwrapped with `_#value`, may be\n     * enabled using `_.chain`.\n     *\n     * The execution of chained methods is lazy, that is, it's deferred until\n     * `_#value` is implicitly or explicitly called.\n     *\n     * Lazy evaluation allows several methods to support shortcut fusion.\n     * Shortcut fusion is an optimization to merge iteratee calls; this avoids\n     * the creation of intermediate arrays and can greatly reduce the number of\n     * iteratee executions. Sections of a chain sequence qualify for shortcut\n     * fusion if the section is applied to an array and iteratees accept only\n     * one argument. The heuristic for whether a section qualifies for shortcut\n     * fusion is subject to change.\n     *\n     * Chaining is supported in custom builds as long as the `_#value` method is\n     * directly or indirectly included in the build.\n     *\n     * In addition to lodash methods, wrappers have `Array` and `String` methods.\n     *\n     * The wrapper `Array` methods are:\n     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`\n     *\n     * The wrapper `String` methods are:\n     * `replace` and `split`\n     *\n     * The wrapper methods that support shortcut fusion are:\n     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,\n     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,\n     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`\n     *\n     * The chainable wrapper methods are:\n     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,\n     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,\n     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,\n     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,\n     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,\n     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,\n     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,\n     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,\n     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,\n     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,\n     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,\n     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,\n     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,\n     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,\n     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,\n     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,\n     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,\n     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,\n     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,\n     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,\n     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,\n     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,\n     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,\n     * `zipObject`, `zipObjectDeep`, and `zipWith`\n     *\n     * The wrapper methods that are **not** chainable by default are:\n     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,\n     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,\n     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,\n     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,\n     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,\n     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,\n     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,\n     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,\n     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,\n     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,\n     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,\n     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,\n     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,\n     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,\n     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,\n     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,\n     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,\n     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,\n     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,\n     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,\n     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,\n     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,\n     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,\n     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,\n     * `upperFirst`, `value`, and `words`\n     *\n     * @name _\n     * @constructor\n     * @category Seq\n     * @param {*} value The value to wrap in a `lodash` instance.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var wrapped = _([1, 2, 3]);\n     *\n     * // Returns an unwrapped value.\n     * wrapped.reduce(_.add);\n     * // => 6\n     *\n     * // Returns a wrapped value.\n     * var squares = wrapped.map(square);\n     *\n     * _.isArray(squares);\n     * // => false\n     *\n     * _.isArray(squares.value());\n     * // => true\n     */\n    function lodash(value) {\n      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {\n        if (value instanceof LodashWrapper) {\n          return value;\n        }\n        if (hasOwnProperty.call(value, '__wrapped__')) {\n          return wrapperClone(value);\n        }\n      }\n      return new LodashWrapper(value);\n    }\n\n    /**\n     * The base implementation of `_.create` without support for assigning\n     * properties to the created object.\n     *\n     * @private\n     * @param {Object} proto The object to inherit from.\n     * @returns {Object} Returns the new object.\n     */\n    var baseCreate = (function() {\n      function object() {}\n      return function(proto) {\n        if (!isObject(proto)) {\n          return {};\n        }\n        if (objectCreate) {\n          return objectCreate(proto);\n        }\n        object.prototype = proto;\n        var result = new object;\n        object.prototype = undefined;\n        return result;\n      };\n    }());\n\n    /**\n     * The function whose prototype chain sequence wrappers inherit from.\n     *\n     * @private\n     */\n    function baseLodash() {\n      // No operation performed.\n    }\n\n    /**\n     * The base constructor for creating `lodash` wrapper objects.\n     *\n     * @private\n     * @param {*} value The value to wrap.\n     * @param {boolean} [chainAll] Enable explicit method chain sequences.\n     */\n    function LodashWrapper(value, chainAll) {\n      this.__wrapped__ = value;\n      this.__actions__ = [];\n      this.__chain__ = !!chainAll;\n      this.__index__ = 0;\n      this.__values__ = undefined;\n    }\n\n    /**\n     * By default, the template delimiters used by lodash are like those in\n     * embedded Ruby (ERB) as well as ES2015 template strings. Change the\n     * following template settings to use alternative delimiters.\n     *\n     * @static\n     * @memberOf _\n     * @type {Object}\n     */\n    lodash.templateSettings = {\n\n      /**\n       * Used to detect `data` property values to be HTML-escaped.\n       *\n       * @memberOf _.templateSettings\n       * @type {RegExp}\n       */\n      'escape': reEscape,\n\n      /**\n       * Used to detect code to be evaluated.\n       *\n       * @memberOf _.templateSettings\n       * @type {RegExp}\n       */\n      'evaluate': reEvaluate,\n\n      /**\n       * Used to detect `data` property values to inject.\n       *\n       * @memberOf _.templateSettings\n       * @type {RegExp}\n       */\n      'interpolate': reInterpolate,\n\n      /**\n       * Used to reference the data object in the template text.\n       *\n       * @memberOf _.templateSettings\n       * @type {string}\n       */\n      'variable': '',\n\n      /**\n       * Used to import variables into the compiled template.\n       *\n       * @memberOf _.templateSettings\n       * @type {Object}\n       */\n      'imports': {\n\n        /**\n         * A reference to the `lodash` function.\n         *\n         * @memberOf _.templateSettings.imports\n         * @type {Function}\n         */\n        '_': lodash\n      }\n    };\n\n    // Ensure wrappers are instances of `baseLodash`.\n    lodash.prototype = baseLodash.prototype;\n    lodash.prototype.constructor = lodash;\n\n    LodashWrapper.prototype = baseCreate(baseLodash.prototype);\n    LodashWrapper.prototype.constructor = LodashWrapper;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.\n     *\n     * @private\n     * @constructor\n     * @param {*} value The value to wrap.\n     */\n    function LazyWrapper(value) {\n      this.__wrapped__ = value;\n      this.__actions__ = [];\n      this.__dir__ = 1;\n      this.__filtered__ = false;\n      this.__iteratees__ = [];\n      this.__takeCount__ = MAX_ARRAY_LENGTH;\n      this.__views__ = [];\n    }\n\n    /**\n     * Creates a clone of the lazy wrapper object.\n     *\n     * @private\n     * @name clone\n     * @memberOf LazyWrapper\n     * @returns {Object} Returns the cloned `LazyWrapper` object.\n     */\n    function lazyClone() {\n      var result = new LazyWrapper(this.__wrapped__);\n      result.__actions__ = copyArray(this.__actions__);\n      result.__dir__ = this.__dir__;\n      result.__filtered__ = this.__filtered__;\n      result.__iteratees__ = copyArray(this.__iteratees__);\n      result.__takeCount__ = this.__takeCount__;\n      result.__views__ = copyArray(this.__views__);\n      return result;\n    }\n\n    /**\n     * Reverses the direction of lazy iteration.\n     *\n     * @private\n     * @name reverse\n     * @memberOf LazyWrapper\n     * @returns {Object} Returns the new reversed `LazyWrapper` object.\n     */\n    function lazyReverse() {\n      if (this.__filtered__) {\n        var result = new LazyWrapper(this);\n        result.__dir__ = -1;\n        result.__filtered__ = true;\n      } else {\n        result = this.clone();\n        result.__dir__ *= -1;\n      }\n      return result;\n    }\n\n    /**\n     * Extracts the unwrapped value from its lazy wrapper.\n     *\n     * @private\n     * @name value\n     * @memberOf LazyWrapper\n     * @returns {*} Returns the unwrapped value.\n     */\n    function lazyValue() {\n      var array = this.__wrapped__.value(),\n          dir = this.__dir__,\n          isArr = isArray(array),\n          isRight = dir < 0,\n          arrLength = isArr ? array.length : 0,\n          view = getView(0, arrLength, this.__views__),\n          start = view.start,\n          end = view.end,\n          length = end - start,\n          index = isRight ? end : (start - 1),\n          iteratees = this.__iteratees__,\n          iterLength = iteratees.length,\n          resIndex = 0,\n          takeCount = nativeMin(length, this.__takeCount__);\n\n      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {\n        return baseWrapperValue(array, this.__actions__);\n      }\n      var result = [];\n\n      outer:\n      while (length-- && resIndex < takeCount) {\n        index += dir;\n\n        var iterIndex = -1,\n            value = array[index];\n\n        while (++iterIndex < iterLength) {\n          var data = iteratees[iterIndex],\n              iteratee = data.iteratee,\n              type = data.type,\n              computed = iteratee(value);\n\n          if (type == LAZY_MAP_FLAG) {\n            value = computed;\n          } else if (!computed) {\n            if (type == LAZY_FILTER_FLAG) {\n              continue outer;\n            } else {\n              break outer;\n            }\n          }\n        }\n        result[resIndex++] = value;\n      }\n      return result;\n    }\n\n    // Ensure `LazyWrapper` is an instance of `baseLodash`.\n    LazyWrapper.prototype = baseCreate(baseLodash.prototype);\n    LazyWrapper.prototype.constructor = LazyWrapper;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a hash object.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function Hash(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n\n      this.clear();\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    }\n\n    /**\n     * Removes all key-value entries from the hash.\n     *\n     * @private\n     * @name clear\n     * @memberOf Hash\n     */\n    function hashClear() {\n      this.__data__ = nativeCreate ? nativeCreate(null) : {};\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the hash.\n     *\n     * @private\n     * @name delete\n     * @memberOf Hash\n     * @param {Object} hash The hash to modify.\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function hashDelete(key) {\n      var result = this.has(key) && delete this.__data__[key];\n      this.size -= result ? 1 : 0;\n      return result;\n    }\n\n    /**\n     * Gets the hash value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf Hash\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function hashGet(key) {\n      var data = this.__data__;\n      if (nativeCreate) {\n        var result = data[key];\n        return result === HASH_UNDEFINED ? undefined : result;\n      }\n      return hasOwnProperty.call(data, key) ? data[key] : undefined;\n    }\n\n    /**\n     * Checks if a hash value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf Hash\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function hashHas(key) {\n      var data = this.__data__;\n      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n    }\n\n    /**\n     * Sets the hash `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf Hash\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the hash instance.\n     */\n    function hashSet(key, value) {\n      var data = this.__data__;\n      this.size += this.has(key) ? 0 : 1;\n      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n      return this;\n    }\n\n    // Add methods to `Hash`.\n    Hash.prototype.clear = hashClear;\n    Hash.prototype['delete'] = hashDelete;\n    Hash.prototype.get = hashGet;\n    Hash.prototype.has = hashHas;\n    Hash.prototype.set = hashSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an list cache object.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function ListCache(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n\n      this.clear();\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    }\n\n    /**\n     * Removes all key-value entries from the list cache.\n     *\n     * @private\n     * @name clear\n     * @memberOf ListCache\n     */\n    function listCacheClear() {\n      this.__data__ = [];\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the list cache.\n     *\n     * @private\n     * @name delete\n     * @memberOf ListCache\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function listCacheDelete(key) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      if (index < 0) {\n        return false;\n      }\n      var lastIndex = data.length - 1;\n      if (index == lastIndex) {\n        data.pop();\n      } else {\n        splice.call(data, index, 1);\n      }\n      --this.size;\n      return true;\n    }\n\n    /**\n     * Gets the list cache value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf ListCache\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function listCacheGet(key) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      return index < 0 ? undefined : data[index][1];\n    }\n\n    /**\n     * Checks if a list cache value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf ListCache\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function listCacheHas(key) {\n      return assocIndexOf(this.__data__, key) > -1;\n    }\n\n    /**\n     * Sets the list cache `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf ListCache\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the list cache instance.\n     */\n    function listCacheSet(key, value) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      if (index < 0) {\n        ++this.size;\n        data.push([key, value]);\n      } else {\n        data[index][1] = value;\n      }\n      return this;\n    }\n\n    // Add methods to `ListCache`.\n    ListCache.prototype.clear = listCacheClear;\n    ListCache.prototype['delete'] = listCacheDelete;\n    ListCache.prototype.get = listCacheGet;\n    ListCache.prototype.has = listCacheHas;\n    ListCache.prototype.set = listCacheSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a map cache object to store key-value pairs.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function MapCache(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n\n      this.clear();\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    }\n\n    /**\n     * Removes all key-value entries from the map.\n     *\n     * @private\n     * @name clear\n     * @memberOf MapCache\n     */\n    function mapCacheClear() {\n      this.size = 0;\n      this.__data__ = {\n        'hash': new Hash,\n        'map': new (Map || ListCache),\n        'string': new Hash\n      };\n    }\n\n    /**\n     * Removes `key` and its value from the map.\n     *\n     * @private\n     * @name delete\n     * @memberOf MapCache\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function mapCacheDelete(key) {\n      var result = getMapData(this, key)['delete'](key);\n      this.size -= result ? 1 : 0;\n      return result;\n    }\n\n    /**\n     * Gets the map value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf MapCache\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function mapCacheGet(key) {\n      return getMapData(this, key).get(key);\n    }\n\n    /**\n     * Checks if a map value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf MapCache\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function mapCacheHas(key) {\n      return getMapData(this, key).has(key);\n    }\n\n    /**\n     * Sets the map `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf MapCache\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the map cache instance.\n     */\n    function mapCacheSet(key, value) {\n      var data = getMapData(this, key),\n          size = data.size;\n\n      data.set(key, value);\n      this.size += data.size == size ? 0 : 1;\n      return this;\n    }\n\n    // Add methods to `MapCache`.\n    MapCache.prototype.clear = mapCacheClear;\n    MapCache.prototype['delete'] = mapCacheDelete;\n    MapCache.prototype.get = mapCacheGet;\n    MapCache.prototype.has = mapCacheHas;\n    MapCache.prototype.set = mapCacheSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     *\n     * Creates an array cache object to store unique values.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [values] The values to cache.\n     */\n    function SetCache(values) {\n      var index = -1,\n          length = values == null ? 0 : values.length;\n\n      this.__data__ = new MapCache;\n      while (++index < length) {\n        this.add(values[index]);\n      }\n    }\n\n    /**\n     * Adds `value` to the array cache.\n     *\n     * @private\n     * @name add\n     * @memberOf SetCache\n     * @alias push\n     * @param {*} value The value to cache.\n     * @returns {Object} Returns the cache instance.\n     */\n    function setCacheAdd(value) {\n      this.__data__.set(value, HASH_UNDEFINED);\n      return this;\n    }\n\n    /**\n     * Checks if `value` is in the array cache.\n     *\n     * @private\n     * @name has\n     * @memberOf SetCache\n     * @param {*} value The value to search for.\n     * @returns {number} Returns `true` if `value` is found, else `false`.\n     */\n    function setCacheHas(value) {\n      return this.__data__.has(value);\n    }\n\n    // Add methods to `SetCache`.\n    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\n    SetCache.prototype.has = setCacheHas;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a stack cache object to store key-value pairs.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function Stack(entries) {\n      var data = this.__data__ = new ListCache(entries);\n      this.size = data.size;\n    }\n\n    /**\n     * Removes all key-value entries from the stack.\n     *\n     * @private\n     * @name clear\n     * @memberOf Stack\n     */\n    function stackClear() {\n      this.__data__ = new ListCache;\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the stack.\n     *\n     * @private\n     * @name delete\n     * @memberOf Stack\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function stackDelete(key) {\n      var data = this.__data__,\n          result = data['delete'](key);\n\n      this.size = data.size;\n      return result;\n    }\n\n    /**\n     * Gets the stack value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf Stack\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function stackGet(key) {\n      return this.__data__.get(key);\n    }\n\n    /**\n     * Checks if a stack value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf Stack\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function stackHas(key) {\n      return this.__data__.has(key);\n    }\n\n    /**\n     * Sets the stack `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf Stack\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the stack cache instance.\n     */\n    function stackSet(key, value) {\n      var data = this.__data__;\n      if (data instanceof ListCache) {\n        var pairs = data.__data__;\n        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n          pairs.push([key, value]);\n          this.size = ++data.size;\n          return this;\n        }\n        data = this.__data__ = new MapCache(pairs);\n      }\n      data.set(key, value);\n      this.size = data.size;\n      return this;\n    }\n\n    // Add methods to `Stack`.\n    Stack.prototype.clear = stackClear;\n    Stack.prototype['delete'] = stackDelete;\n    Stack.prototype.get = stackGet;\n    Stack.prototype.has = stackHas;\n    Stack.prototype.set = stackSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an array of the enumerable property names of the array-like `value`.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @param {boolean} inherited Specify returning inherited property names.\n     * @returns {Array} Returns the array of property names.\n     */\n    function arrayLikeKeys(value, inherited) {\n      var isArr = isArray(value),\n          isArg = !isArr && isArguments(value),\n          isBuff = !isArr && !isArg && isBuffer(value),\n          isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n          skipIndexes = isArr || isArg || isBuff || isType,\n          result = skipIndexes ? baseTimes(value.length, String) : [],\n          length = result.length;\n\n      for (var key in value) {\n        if ((inherited || hasOwnProperty.call(value, key)) &&\n            !(skipIndexes && (\n               // Safari 9 has enumerable `arguments.length` in strict mode.\n               key == 'length' ||\n               // Node.js 0.10 has enumerable non-index properties on buffers.\n               (isBuff && (key == 'offset' || key == 'parent')) ||\n               // PhantomJS 2 has enumerable non-index properties on typed arrays.\n               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n               // Skip index properties.\n               isIndex(key, length)\n            ))) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * A specialized version of `_.sample` for arrays.\n     *\n     * @private\n     * @param {Array} array The array to sample.\n     * @returns {*} Returns the random element.\n     */\n    function arraySample(array) {\n      var length = array.length;\n      return length ? array[baseRandom(0, length - 1)] : undefined;\n    }\n\n    /**\n     * A specialized version of `_.sampleSize` for arrays.\n     *\n     * @private\n     * @param {Array} array The array to sample.\n     * @param {number} n The number of elements to sample.\n     * @returns {Array} Returns the random elements.\n     */\n    function arraySampleSize(array, n) {\n      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));\n    }\n\n    /**\n     * A specialized version of `_.shuffle` for arrays.\n     *\n     * @private\n     * @param {Array} array The array to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     */\n    function arrayShuffle(array) {\n      return shuffleSelf(copyArray(array));\n    }\n\n    /**\n     * This function is like `assignValue` except that it doesn't assign\n     * `undefined` values.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {string} key The key of the property to assign.\n     * @param {*} value The value to assign.\n     */\n    function assignMergeValue(object, key, value) {\n      if ((value !== undefined && !eq(object[key], value)) ||\n          (value === undefined && !(key in object))) {\n        baseAssignValue(object, key, value);\n      }\n    }\n\n    /**\n     * Assigns `value` to `key` of `object` if the existing value is not equivalent\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {string} key The key of the property to assign.\n     * @param {*} value The value to assign.\n     */\n    function assignValue(object, key, value) {\n      var objValue = object[key];\n      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n          (value === undefined && !(key in object))) {\n        baseAssignValue(object, key, value);\n      }\n    }\n\n    /**\n     * Gets the index at which the `key` is found in `array` of key-value pairs.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {*} key The key to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     */\n    function assocIndexOf(array, key) {\n      var length = array.length;\n      while (length--) {\n        if (eq(array[length][0], key)) {\n          return length;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * Aggregates elements of `collection` on `accumulator` with keys transformed\n     * by `iteratee` and values set by `setter`.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} setter The function to set `accumulator` values.\n     * @param {Function} iteratee The iteratee to transform keys.\n     * @param {Object} accumulator The initial aggregated object.\n     * @returns {Function} Returns `accumulator`.\n     */\n    function baseAggregator(collection, setter, iteratee, accumulator) {\n      baseEach(collection, function(value, key, collection) {\n        setter(accumulator, value, iteratee(value), collection);\n      });\n      return accumulator;\n    }\n\n    /**\n     * The base implementation of `_.assign` without support for multiple sources\n     * or `customizer` functions.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @returns {Object} Returns `object`.\n     */\n    function baseAssign(object, source) {\n      return object && copyObject(source, keys(source), object);\n    }\n\n    /**\n     * The base implementation of `_.assignIn` without support for multiple sources\n     * or `customizer` functions.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @returns {Object} Returns `object`.\n     */\n    function baseAssignIn(object, source) {\n      return object && copyObject(source, keysIn(source), object);\n    }\n\n    /**\n     * The base implementation of `assignValue` and `assignMergeValue` without\n     * value checks.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {string} key The key of the property to assign.\n     * @param {*} value The value to assign.\n     */\n    function baseAssignValue(object, key, value) {\n      if (key == '__proto__' && defineProperty) {\n        defineProperty(object, key, {\n          'configurable': true,\n          'enumerable': true,\n          'value': value,\n          'writable': true\n        });\n      } else {\n        object[key] = value;\n      }\n    }\n\n    /**\n     * The base implementation of `_.at` without support for individual paths.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {string[]} paths The property paths to pick.\n     * @returns {Array} Returns the picked elements.\n     */\n    function baseAt(object, paths) {\n      var index = -1,\n          length = paths.length,\n          result = Array(length),\n          skip = object == null;\n\n      while (++index < length) {\n        result[index] = skip ? undefined : get(object, paths[index]);\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.clamp` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {number} number The number to clamp.\n     * @param {number} [lower] The lower bound.\n     * @param {number} upper The upper bound.\n     * @returns {number} Returns the clamped number.\n     */\n    function baseClamp(number, lower, upper) {\n      if (number === number) {\n        if (upper !== undefined) {\n          number = number <= upper ? number : upper;\n        }\n        if (lower !== undefined) {\n          number = number >= lower ? number : lower;\n        }\n      }\n      return number;\n    }\n\n    /**\n     * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n     * traversed objects.\n     *\n     * @private\n     * @param {*} value The value to clone.\n     * @param {boolean} bitmask The bitmask flags.\n     *  1 - Deep clone\n     *  2 - Flatten inherited properties\n     *  4 - Clone symbols\n     * @param {Function} [customizer] The function to customize cloning.\n     * @param {string} [key] The key of `value`.\n     * @param {Object} [object] The parent object of `value`.\n     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n     * @returns {*} Returns the cloned value.\n     */\n    function baseClone(value, bitmask, customizer, key, object, stack) {\n      var result,\n          isDeep = bitmask & CLONE_DEEP_FLAG,\n          isFlat = bitmask & CLONE_FLAT_FLAG,\n          isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n      if (customizer) {\n        result = object ? customizer(value, key, object, stack) : customizer(value);\n      }\n      if (result !== undefined) {\n        return result;\n      }\n      if (!isObject(value)) {\n        return value;\n      }\n      var isArr = isArray(value);\n      if (isArr) {\n        result = initCloneArray(value);\n        if (!isDeep) {\n          return copyArray(value, result);\n        }\n      } else {\n        var tag = getTag(value),\n            isFunc = tag == funcTag || tag == genTag;\n\n        if (isBuffer(value)) {\n          return cloneBuffer(value, isDeep);\n        }\n        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n          result = (isFlat || isFunc) ? {} : initCloneObject(value);\n          if (!isDeep) {\n            return isFlat\n              ? copySymbolsIn(value, baseAssignIn(result, value))\n              : copySymbols(value, baseAssign(result, value));\n          }\n        } else {\n          if (!cloneableTags[tag]) {\n            return object ? value : {};\n          }\n          result = initCloneByTag(value, tag, baseClone, isDeep);\n        }\n      }\n      // Check for circular references and return its corresponding clone.\n      stack || (stack = new Stack);\n      var stacked = stack.get(value);\n      if (stacked) {\n        return stacked;\n      }\n      stack.set(value, result);\n\n      var keysFunc = isFull\n        ? (isFlat ? getAllKeysIn : getAllKeys)\n        : (isFlat ? keysIn : keys);\n\n      var props = isArr ? undefined : keysFunc(value);\n      arrayEach(props || value, function(subValue, key) {\n        if (props) {\n          key = subValue;\n          subValue = value[key];\n        }\n        // Recursively populate clone (susceptible to call stack limits).\n        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.conforms` which doesn't clone `source`.\n     *\n     * @private\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {Function} Returns the new spec function.\n     */\n    function baseConforms(source) {\n      var props = keys(source);\n      return function(object) {\n        return baseConformsTo(object, source, props);\n      };\n    }\n\n    /**\n     * The base implementation of `_.conformsTo` which accepts `props` to check.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n     */\n    function baseConformsTo(object, source, props) {\n      var length = props.length;\n      if (object == null) {\n        return !length;\n      }\n      object = Object(object);\n      while (length--) {\n        var key = props[length],\n            predicate = source[key],\n            value = object[key];\n\n        if ((value === undefined && !(key in object)) || !predicate(value)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    /**\n     * The base implementation of `_.delay` and `_.defer` which accepts `args`\n     * to provide to `func`.\n     *\n     * @private\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @param {Array} args The arguments to provide to `func`.\n     * @returns {number|Object} Returns the timer id or timeout object.\n     */\n    function baseDelay(func, wait, args) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      return setTimeout(function() { func.apply(undefined, args); }, wait);\n    }\n\n    /**\n     * The base implementation of methods like `_.difference` without support\n     * for excluding multiple arrays or iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Array} values The values to exclude.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     */\n    function baseDifference(array, values, iteratee, comparator) {\n      var index = -1,\n          includes = arrayIncludes,\n          isCommon = true,\n          length = array.length,\n          result = [],\n          valuesLength = values.length;\n\n      if (!length) {\n        return result;\n      }\n      if (iteratee) {\n        values = arrayMap(values, baseUnary(iteratee));\n      }\n      if (comparator) {\n        includes = arrayIncludesWith;\n        isCommon = false;\n      }\n      else if (values.length >= LARGE_ARRAY_SIZE) {\n        includes = cacheHas;\n        isCommon = false;\n        values = new SetCache(values);\n      }\n      outer:\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee == null ? value : iteratee(value);\n\n        value = (comparator || value !== 0) ? value : 0;\n        if (isCommon && computed === computed) {\n          var valuesIndex = valuesLength;\n          while (valuesIndex--) {\n            if (values[valuesIndex] === computed) {\n              continue outer;\n            }\n          }\n          result.push(value);\n        }\n        else if (!includes(values, computed, comparator)) {\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.forEach` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     */\n    var baseEach = createBaseEach(baseForOwn);\n\n    /**\n     * The base implementation of `_.forEachRight` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     */\n    var baseEachRight = createBaseEach(baseForOwnRight, true);\n\n    /**\n     * The base implementation of `_.every` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if all elements pass the predicate check,\n     *  else `false`\n     */\n    function baseEvery(collection, predicate) {\n      var result = true;\n      baseEach(collection, function(value, index, collection) {\n        result = !!predicate(value, index, collection);\n        return result;\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of methods like `_.max` and `_.min` which accepts a\n     * `comparator` to determine the extremum value.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The iteratee invoked per iteration.\n     * @param {Function} comparator The comparator used to compare values.\n     * @returns {*} Returns the extremum value.\n     */\n    function baseExtremum(array, iteratee, comparator) {\n      var index = -1,\n          length = array.length;\n\n      while (++index < length) {\n        var value = array[index],\n            current = iteratee(value);\n\n        if (current != null && (computed === undefined\n              ? (current === current && !isSymbol(current))\n              : comparator(current, computed)\n            )) {\n          var computed = current,\n              result = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.fill` without an iteratee call guard.\n     *\n     * @private\n     * @param {Array} array The array to fill.\n     * @param {*} value The value to fill `array` with.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns `array`.\n     */\n    function baseFill(array, value, start, end) {\n      var length = array.length;\n\n      start = toInteger(start);\n      if (start < 0) {\n        start = -start > length ? 0 : (length + start);\n      }\n      end = (end === undefined || end > length) ? length : toInteger(end);\n      if (end < 0) {\n        end += length;\n      }\n      end = start > end ? 0 : toLength(end);\n      while (start < end) {\n        array[start++] = value;\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.filter` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     */\n    function baseFilter(collection, predicate) {\n      var result = [];\n      baseEach(collection, function(value, index, collection) {\n        if (predicate(value, index, collection)) {\n          result.push(value);\n        }\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.flatten` with support for restricting flattening.\n     *\n     * @private\n     * @param {Array} array The array to flatten.\n     * @param {number} depth The maximum recursion depth.\n     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n     * @param {Array} [result=[]] The initial result value.\n     * @returns {Array} Returns the new flattened array.\n     */\n    function baseFlatten(array, depth, predicate, isStrict, result) {\n      var index = -1,\n          length = array.length;\n\n      predicate || (predicate = isFlattenable);\n      result || (result = []);\n\n      while (++index < length) {\n        var value = array[index];\n        if (depth > 0 && predicate(value)) {\n          if (depth > 1) {\n            // Recursively flatten arrays (susceptible to call stack limits).\n            baseFlatten(value, depth - 1, predicate, isStrict, result);\n          } else {\n            arrayPush(result, value);\n          }\n        } else if (!isStrict) {\n          result[result.length] = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `baseForOwn` which iterates over `object`\n     * properties returned by `keysFunc` and invokes `iteratee` for each property.\n     * Iteratee functions may exit iteration early by explicitly returning `false`.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @returns {Object} Returns `object`.\n     */\n    var baseFor = createBaseFor();\n\n    /**\n     * This function is like `baseFor` except that it iterates over properties\n     * in the opposite order.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @returns {Object} Returns `object`.\n     */\n    var baseForRight = createBaseFor(true);\n\n    /**\n     * The base implementation of `_.forOwn` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     */\n    function baseForOwn(object, iteratee) {\n      return object && baseFor(object, iteratee, keys);\n    }\n\n    /**\n     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     */\n    function baseForOwnRight(object, iteratee) {\n      return object && baseForRight(object, iteratee, keys);\n    }\n\n    /**\n     * The base implementation of `_.functions` which creates an array of\n     * `object` function property names filtered from `props`.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Array} props The property names to filter.\n     * @returns {Array} Returns the function names.\n     */\n    function baseFunctions(object, props) {\n      return arrayFilter(props, function(key) {\n        return isFunction(object[key]);\n      });\n    }\n\n    /**\n     * The base implementation of `_.get` without support for default values.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to get.\n     * @returns {*} Returns the resolved value.\n     */\n    function baseGet(object, path) {\n      path = castPath(path, object);\n\n      var index = 0,\n          length = path.length;\n\n      while (object != null && index < length) {\n        object = object[toKey(path[index++])];\n      }\n      return (index && index == length) ? object : undefined;\n    }\n\n    /**\n     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n     * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n     * symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @param {Function} symbolsFunc The function to get the symbols of `object`.\n     * @returns {Array} Returns the array of property names and symbols.\n     */\n    function baseGetAllKeys(object, keysFunc, symbolsFunc) {\n      var result = keysFunc(object);\n      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n    }\n\n    /**\n     * The base implementation of `getTag` without fallbacks for buggy environments.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the `toStringTag`.\n     */\n    function baseGetTag(value) {\n      if (value == null) {\n        return value === undefined ? undefinedTag : nullTag;\n      }\n      return (symToStringTag && symToStringTag in Object(value))\n        ? getRawTag(value)\n        : objectToString(value);\n    }\n\n    /**\n     * The base implementation of `_.gt` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than `other`,\n     *  else `false`.\n     */\n    function baseGt(value, other) {\n      return value > other;\n    }\n\n    /**\n     * The base implementation of `_.has` without support for deep paths.\n     *\n     * @private\n     * @param {Object} [object] The object to query.\n     * @param {Array|string} key The key to check.\n     * @returns {boolean} Returns `true` if `key` exists, else `false`.\n     */\n    function baseHas(object, key) {\n      return object != null && hasOwnProperty.call(object, key);\n    }\n\n    /**\n     * The base implementation of `_.hasIn` without support for deep paths.\n     *\n     * @private\n     * @param {Object} [object] The object to query.\n     * @param {Array|string} key The key to check.\n     * @returns {boolean} Returns `true` if `key` exists, else `false`.\n     */\n    function baseHasIn(object, key) {\n      return object != null && key in Object(object);\n    }\n\n    /**\n     * The base implementation of `_.inRange` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {number} number The number to check.\n     * @param {number} start The start of the range.\n     * @param {number} end The end of the range.\n     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n     */\n    function baseInRange(number, start, end) {\n      return number >= nativeMin(start, end) && number < nativeMax(start, end);\n    }\n\n    /**\n     * The base implementation of methods like `_.intersection`, without support\n     * for iteratee shorthands, that accepts an array of arrays to inspect.\n     *\n     * @private\n     * @param {Array} arrays The arrays to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of shared values.\n     */\n    function baseIntersection(arrays, iteratee, comparator) {\n      var includes = comparator ? arrayIncludesWith : arrayIncludes,\n          length = arrays[0].length,\n          othLength = arrays.length,\n          othIndex = othLength,\n          caches = Array(othLength),\n          maxLength = Infinity,\n          result = [];\n\n      while (othIndex--) {\n        var array = arrays[othIndex];\n        if (othIndex && iteratee) {\n          array = arrayMap(array, baseUnary(iteratee));\n        }\n        maxLength = nativeMin(array.length, maxLength);\n        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))\n          ? new SetCache(othIndex && array)\n          : undefined;\n      }\n      array = arrays[0];\n\n      var index = -1,\n          seen = caches[0];\n\n      outer:\n      while (++index < length && result.length < maxLength) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        value = (comparator || value !== 0) ? value : 0;\n        if (!(seen\n              ? cacheHas(seen, computed)\n              : includes(result, computed, comparator)\n            )) {\n          othIndex = othLength;\n          while (--othIndex) {\n            var cache = caches[othIndex];\n            if (!(cache\n                  ? cacheHas(cache, computed)\n                  : includes(arrays[othIndex], computed, comparator))\n                ) {\n              continue outer;\n            }\n          }\n          if (seen) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.invert` and `_.invertBy` which inverts\n     * `object` with values transformed by `iteratee` and set by `setter`.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} setter The function to set `accumulator` values.\n     * @param {Function} iteratee The iteratee to transform values.\n     * @param {Object} accumulator The initial inverted object.\n     * @returns {Function} Returns `accumulator`.\n     */\n    function baseInverter(object, setter, iteratee, accumulator) {\n      baseForOwn(object, function(value, key, object) {\n        setter(accumulator, iteratee(value), key, object);\n      });\n      return accumulator;\n    }\n\n    /**\n     * The base implementation of `_.invoke` without support for individual\n     * method arguments.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {Array} args The arguments to invoke the method with.\n     * @returns {*} Returns the result of the invoked method.\n     */\n    function baseInvoke(object, path, args) {\n      path = castPath(path, object);\n      object = parent(object, path);\n      var func = object == null ? object : object[toKey(last(path))];\n      return func == null ? undefined : apply(func, object, args);\n    }\n\n    /**\n     * The base implementation of `_.isArguments`.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n     */\n    function baseIsArguments(value) {\n      return isObjectLike(value) && baseGetTag(value) == argsTag;\n    }\n\n    /**\n     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n     */\n    function baseIsArrayBuffer(value) {\n      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;\n    }\n\n    /**\n     * The base implementation of `_.isDate` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n     */\n    function baseIsDate(value) {\n      return isObjectLike(value) && baseGetTag(value) == dateTag;\n    }\n\n    /**\n     * The base implementation of `_.isEqual` which supports partial comparisons\n     * and tracks traversed objects.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @param {boolean} bitmask The bitmask flags.\n     *  1 - Unordered comparison\n     *  2 - Partial comparison\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     */\n    function baseIsEqual(value, other, bitmask, customizer, stack) {\n      if (value === other) {\n        return true;\n      }\n      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n        return value !== value && other !== other;\n      }\n      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n    }\n\n    /**\n     * A specialized version of `baseIsEqual` for arrays and objects which performs\n     * deep comparisons and tracks traversed objects enabling objects with circular\n     * references to be compared.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n      var objIsArr = isArray(object),\n          othIsArr = isArray(other),\n          objTag = objIsArr ? arrayTag : getTag(object),\n          othTag = othIsArr ? arrayTag : getTag(other);\n\n      objTag = objTag == argsTag ? objectTag : objTag;\n      othTag = othTag == argsTag ? objectTag : othTag;\n\n      var objIsObj = objTag == objectTag,\n          othIsObj = othTag == objectTag,\n          isSameTag = objTag == othTag;\n\n      if (isSameTag && isBuffer(object)) {\n        if (!isBuffer(other)) {\n          return false;\n        }\n        objIsArr = true;\n        objIsObj = false;\n      }\n      if (isSameTag && !objIsObj) {\n        stack || (stack = new Stack);\n        return (objIsArr || isTypedArray(object))\n          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n      }\n      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n        if (objIsWrapped || othIsWrapped) {\n          var objUnwrapped = objIsWrapped ? object.value() : object,\n              othUnwrapped = othIsWrapped ? other.value() : other;\n\n          stack || (stack = new Stack);\n          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n        }\n      }\n      if (!isSameTag) {\n        return false;\n      }\n      stack || (stack = new Stack);\n      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n    }\n\n    /**\n     * The base implementation of `_.isMap` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n     */\n    function baseIsMap(value) {\n      return isObjectLike(value) && getTag(value) == mapTag;\n    }\n\n    /**\n     * The base implementation of `_.isMatch` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @param {Array} matchData The property names, values, and compare flags to match.\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     */\n    function baseIsMatch(object, source, matchData, customizer) {\n      var index = matchData.length,\n          length = index,\n          noCustomizer = !customizer;\n\n      if (object == null) {\n        return !length;\n      }\n      object = Object(object);\n      while (index--) {\n        var data = matchData[index];\n        if ((noCustomizer && data[2])\n              ? data[1] !== object[data[0]]\n              : !(data[0] in object)\n            ) {\n          return false;\n        }\n      }\n      while (++index < length) {\n        data = matchData[index];\n        var key = data[0],\n            objValue = object[key],\n            srcValue = data[1];\n\n        if (noCustomizer && data[2]) {\n          if (objValue === undefined && !(key in object)) {\n            return false;\n          }\n        } else {\n          var stack = new Stack;\n          if (customizer) {\n            var result = customizer(objValue, srcValue, key, object, source, stack);\n          }\n          if (!(result === undefined\n                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n                : result\n              )) {\n            return false;\n          }\n        }\n      }\n      return true;\n    }\n\n    /**\n     * The base implementation of `_.isNative` without bad shim checks.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a native function,\n     *  else `false`.\n     */\n    function baseIsNative(value) {\n      if (!isObject(value) || isMasked(value)) {\n        return false;\n      }\n      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n      return pattern.test(toSource(value));\n    }\n\n    /**\n     * The base implementation of `_.isRegExp` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n     */\n    function baseIsRegExp(value) {\n      return isObjectLike(value) && baseGetTag(value) == regexpTag;\n    }\n\n    /**\n     * The base implementation of `_.isSet` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n     */\n    function baseIsSet(value) {\n      return isObjectLike(value) && getTag(value) == setTag;\n    }\n\n    /**\n     * The base implementation of `_.isTypedArray` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n     */\n    function baseIsTypedArray(value) {\n      return isObjectLike(value) &&\n        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n    }\n\n    /**\n     * The base implementation of `_.iteratee`.\n     *\n     * @private\n     * @param {*} [value=_.identity] The value to convert to an iteratee.\n     * @returns {Function} Returns the iteratee.\n     */\n    function baseIteratee(value) {\n      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n      if (typeof value == 'function') {\n        return value;\n      }\n      if (value == null) {\n        return identity;\n      }\n      if (typeof value == 'object') {\n        return isArray(value)\n          ? baseMatchesProperty(value[0], value[1])\n          : baseMatches(value);\n      }\n      return property(value);\n    }\n\n    /**\n     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function baseKeys(object) {\n      if (!isPrototype(object)) {\n        return nativeKeys(object);\n      }\n      var result = [];\n      for (var key in Object(object)) {\n        if (hasOwnProperty.call(object, key) && key != 'constructor') {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function baseKeysIn(object) {\n      if (!isObject(object)) {\n        return nativeKeysIn(object);\n      }\n      var isProto = isPrototype(object),\n          result = [];\n\n      for (var key in object) {\n        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.lt` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than `other`,\n     *  else `false`.\n     */\n    function baseLt(value, other) {\n      return value < other;\n    }\n\n    /**\n     * The base implementation of `_.map` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array} Returns the new mapped array.\n     */\n    function baseMap(collection, iteratee) {\n      var index = -1,\n          result = isArrayLike(collection) ? Array(collection.length) : [];\n\n      baseEach(collection, function(value, key, collection) {\n        result[++index] = iteratee(value, key, collection);\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.matches` which doesn't clone `source`.\n     *\n     * @private\n     * @param {Object} source The object of property values to match.\n     * @returns {Function} Returns the new spec function.\n     */\n    function baseMatches(source) {\n      var matchData = getMatchData(source);\n      if (matchData.length == 1 && matchData[0][2]) {\n        return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n      }\n      return function(object) {\n        return object === source || baseIsMatch(object, source, matchData);\n      };\n    }\n\n    /**\n     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n     *\n     * @private\n     * @param {string} path The path of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new spec function.\n     */\n    function baseMatchesProperty(path, srcValue) {\n      if (isKey(path) && isStrictComparable(srcValue)) {\n        return matchesStrictComparable(toKey(path), srcValue);\n      }\n      return function(object) {\n        var objValue = get(object, path);\n        return (objValue === undefined && objValue === srcValue)\n          ? hasIn(object, path)\n          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n      };\n    }\n\n    /**\n     * The base implementation of `_.merge` without support for multiple sources.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @param {number} srcIndex The index of `source`.\n     * @param {Function} [customizer] The function to customize merged values.\n     * @param {Object} [stack] Tracks traversed source values and their merged\n     *  counterparts.\n     */\n    function baseMerge(object, source, srcIndex, customizer, stack) {\n      if (object === source) {\n        return;\n      }\n      baseFor(source, function(srcValue, key) {\n        if (isObject(srcValue)) {\n          stack || (stack = new Stack);\n          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n        }\n        else {\n          var newValue = customizer\n            ? customizer(object[key], srcValue, (key + ''), object, source, stack)\n            : undefined;\n\n          if (newValue === undefined) {\n            newValue = srcValue;\n          }\n          assignMergeValue(object, key, newValue);\n        }\n      }, keysIn);\n    }\n\n    /**\n     * A specialized version of `baseMerge` for arrays and objects which performs\n     * deep merges and tracks traversed objects enabling objects with circular\n     * references to be merged.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @param {string} key The key of the value to merge.\n     * @param {number} srcIndex The index of `source`.\n     * @param {Function} mergeFunc The function to merge values.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @param {Object} [stack] Tracks traversed source values and their merged\n     *  counterparts.\n     */\n    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n      var objValue = object[key],\n          srcValue = source[key],\n          stacked = stack.get(srcValue);\n\n      if (stacked) {\n        assignMergeValue(object, key, stacked);\n        return;\n      }\n      var newValue = customizer\n        ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n        : undefined;\n\n      var isCommon = newValue === undefined;\n\n      if (isCommon) {\n        var isArr = isArray(srcValue),\n            isBuff = !isArr && isBuffer(srcValue),\n            isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n        newValue = srcValue;\n        if (isArr || isBuff || isTyped) {\n          if (isArray(objValue)) {\n            newValue = objValue;\n          }\n          else if (isArrayLikeObject(objValue)) {\n            newValue = copyArray(objValue);\n          }\n          else if (isBuff) {\n            isCommon = false;\n            newValue = cloneBuffer(srcValue, true);\n          }\n          else if (isTyped) {\n            isCommon = false;\n            newValue = cloneTypedArray(srcValue, true);\n          }\n          else {\n            newValue = [];\n          }\n        }\n        else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n          newValue = objValue;\n          if (isArguments(objValue)) {\n            newValue = toPlainObject(objValue);\n          }\n          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {\n            newValue = initCloneObject(srcValue);\n          }\n        }\n        else {\n          isCommon = false;\n        }\n      }\n      if (isCommon) {\n        // Recursively merge objects and arrays (susceptible to call stack limits).\n        stack.set(srcValue, newValue);\n        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n        stack['delete'](srcValue);\n      }\n      assignMergeValue(object, key, newValue);\n    }\n\n    /**\n     * The base implementation of `_.nth` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {Array} array The array to query.\n     * @param {number} n The index of the element to return.\n     * @returns {*} Returns the nth element of `array`.\n     */\n    function baseNth(array, n) {\n      var length = array.length;\n      if (!length) {\n        return;\n      }\n      n += n < 0 ? length : 0;\n      return isIndex(n, length) ? array[n] : undefined;\n    }\n\n    /**\n     * The base implementation of `_.orderBy` without param guards.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n     * @param {string[]} orders The sort orders of `iteratees`.\n     * @returns {Array} Returns the new sorted array.\n     */\n    function baseOrderBy(collection, iteratees, orders) {\n      var index = -1;\n      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));\n\n      var result = baseMap(collection, function(value, key, collection) {\n        var criteria = arrayMap(iteratees, function(iteratee) {\n          return iteratee(value);\n        });\n        return { 'criteria': criteria, 'index': ++index, 'value': value };\n      });\n\n      return baseSortBy(result, function(object, other) {\n        return compareMultiple(object, other, orders);\n      });\n    }\n\n    /**\n     * The base implementation of `_.pick` without support for individual\n     * property identifiers.\n     *\n     * @private\n     * @param {Object} object The source object.\n     * @param {string[]} paths The property paths to pick.\n     * @returns {Object} Returns the new object.\n     */\n    function basePick(object, paths) {\n      return basePickBy(object, paths, function(value, path) {\n        return hasIn(object, path);\n      });\n    }\n\n    /**\n     * The base implementation of  `_.pickBy` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The source object.\n     * @param {string[]} paths The property paths to pick.\n     * @param {Function} predicate The function invoked per property.\n     * @returns {Object} Returns the new object.\n     */\n    function basePickBy(object, paths, predicate) {\n      var index = -1,\n          length = paths.length,\n          result = {};\n\n      while (++index < length) {\n        var path = paths[index],\n            value = baseGet(object, path);\n\n        if (predicate(value, path)) {\n          baseSet(result, castPath(path, object), value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * A specialized version of `baseProperty` which supports deep paths.\n     *\n     * @private\n     * @param {Array|string} path The path of the property to get.\n     * @returns {Function} Returns the new accessor function.\n     */\n    function basePropertyDeep(path) {\n      return function(object) {\n        return baseGet(object, path);\n      };\n    }\n\n    /**\n     * The base implementation of `_.pullAllBy` without support for iteratee\n     * shorthands.\n     *\n     * @private\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns `array`.\n     */\n    function basePullAll(array, values, iteratee, comparator) {\n      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,\n          index = -1,\n          length = values.length,\n          seen = array;\n\n      if (array === values) {\n        values = copyArray(values);\n      }\n      if (iteratee) {\n        seen = arrayMap(array, baseUnary(iteratee));\n      }\n      while (++index < length) {\n        var fromIndex = 0,\n            value = values[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {\n          if (seen !== array) {\n            splice.call(seen, fromIndex, 1);\n          }\n          splice.call(array, fromIndex, 1);\n        }\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.pullAt` without support for individual\n     * indexes or capturing the removed elements.\n     *\n     * @private\n     * @param {Array} array The array to modify.\n     * @param {number[]} indexes The indexes of elements to remove.\n     * @returns {Array} Returns `array`.\n     */\n    function basePullAt(array, indexes) {\n      var length = array ? indexes.length : 0,\n          lastIndex = length - 1;\n\n      while (length--) {\n        var index = indexes[length];\n        if (length == lastIndex || index !== previous) {\n          var previous = index;\n          if (isIndex(index)) {\n            splice.call(array, index, 1);\n          } else {\n            baseUnset(array, index);\n          }\n        }\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.random` without support for returning\n     * floating-point numbers.\n     *\n     * @private\n     * @param {number} lower The lower bound.\n     * @param {number} upper The upper bound.\n     * @returns {number} Returns the random number.\n     */\n    function baseRandom(lower, upper) {\n      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));\n    }\n\n    /**\n     * The base implementation of `_.range` and `_.rangeRight` which doesn't\n     * coerce arguments.\n     *\n     * @private\n     * @param {number} start The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} step The value to increment or decrement by.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Array} Returns the range of numbers.\n     */\n    function baseRange(start, end, step, fromRight) {\n      var index = -1,\n          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),\n          result = Array(length);\n\n      while (length--) {\n        result[fromRight ? length : ++index] = start;\n        start += step;\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.repeat` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {string} string The string to repeat.\n     * @param {number} n The number of times to repeat the string.\n     * @returns {string} Returns the repeated string.\n     */\n    function baseRepeat(string, n) {\n      var result = '';\n      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {\n        return result;\n      }\n      // Leverage the exponentiation by squaring algorithm for a faster repeat.\n      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.\n      do {\n        if (n % 2) {\n          result += string;\n        }\n        n = nativeFloor(n / 2);\n        if (n) {\n          string += string;\n        }\n      } while (n);\n\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n     *\n     * @private\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @returns {Function} Returns the new function.\n     */\n    function baseRest(func, start) {\n      return setToString(overRest(func, start, identity), func + '');\n    }\n\n    /**\n     * The base implementation of `_.sample`.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to sample.\n     * @returns {*} Returns the random element.\n     */\n    function baseSample(collection) {\n      return arraySample(values(collection));\n    }\n\n    /**\n     * The base implementation of `_.sampleSize` without param guards.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to sample.\n     * @param {number} n The number of elements to sample.\n     * @returns {Array} Returns the random elements.\n     */\n    function baseSampleSize(collection, n) {\n      var array = values(collection);\n      return shuffleSelf(array, baseClamp(n, 0, array.length));\n    }\n\n    /**\n     * The base implementation of `_.set`.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @param {Function} [customizer] The function to customize path creation.\n     * @returns {Object} Returns `object`.\n     */\n    function baseSet(object, path, value, customizer) {\n      if (!isObject(object)) {\n        return object;\n      }\n      path = castPath(path, object);\n\n      var index = -1,\n          length = path.length,\n          lastIndex = length - 1,\n          nested = object;\n\n      while (nested != null && ++index < length) {\n        var key = toKey(path[index]),\n            newValue = value;\n\n        if (index != lastIndex) {\n          var objValue = nested[key];\n          newValue = customizer ? customizer(objValue, key, nested) : undefined;\n          if (newValue === undefined) {\n            newValue = isObject(objValue)\n              ? objValue\n              : (isIndex(path[index + 1]) ? [] : {});\n          }\n        }\n        assignValue(nested, key, newValue);\n        nested = nested[key];\n      }\n      return object;\n    }\n\n    /**\n     * The base implementation of `setData` without support for hot loop shorting.\n     *\n     * @private\n     * @param {Function} func The function to associate metadata with.\n     * @param {*} data The metadata.\n     * @returns {Function} Returns `func`.\n     */\n    var baseSetData = !metaMap ? identity : function(func, data) {\n      metaMap.set(func, data);\n      return func;\n    };\n\n    /**\n     * The base implementation of `setToString` without support for hot loop shorting.\n     *\n     * @private\n     * @param {Function} func The function to modify.\n     * @param {Function} string The `toString` result.\n     * @returns {Function} Returns `func`.\n     */\n    var baseSetToString = !defineProperty ? identity : function(func, string) {\n      return defineProperty(func, 'toString', {\n        'configurable': true,\n        'enumerable': false,\n        'value': constant(string),\n        'writable': true\n      });\n    };\n\n    /**\n     * The base implementation of `_.shuffle`.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     */\n    function baseShuffle(collection) {\n      return shuffleSelf(values(collection));\n    }\n\n    /**\n     * The base implementation of `_.slice` without an iteratee call guard.\n     *\n     * @private\n     * @param {Array} array The array to slice.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function baseSlice(array, start, end) {\n      var index = -1,\n          length = array.length;\n\n      if (start < 0) {\n        start = -start > length ? 0 : (length + start);\n      }\n      end = end > length ? length : end;\n      if (end < 0) {\n        end += length;\n      }\n      length = start > end ? 0 : ((end - start) >>> 0);\n      start >>>= 0;\n\n      var result = Array(length);\n      while (++index < length) {\n        result[index] = array[index + start];\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.some` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if any element passes the predicate check,\n     *  else `false`.\n     */\n    function baseSome(collection, predicate) {\n      var result;\n\n      baseEach(collection, function(value, index, collection) {\n        result = predicate(value, index, collection);\n        return !result;\n      });\n      return !!result;\n    }\n\n    /**\n     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which\n     * performs a binary search of `array` to determine the index at which `value`\n     * should be inserted into `array` in order to maintain its sort order.\n     *\n     * @private\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {boolean} [retHighest] Specify returning the highest qualified index.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     */\n    function baseSortedIndex(array, value, retHighest) {\n      var low = 0,\n          high = array == null ? low : array.length;\n\n      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {\n        while (low < high) {\n          var mid = (low + high) >>> 1,\n              computed = array[mid];\n\n          if (computed !== null && !isSymbol(computed) &&\n              (retHighest ? (computed <= value) : (computed < value))) {\n            low = mid + 1;\n          } else {\n            high = mid;\n          }\n        }\n        return high;\n      }\n      return baseSortedIndexBy(array, value, identity, retHighest);\n    }\n\n    /**\n     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`\n     * which invokes `iteratee` for `value` and each element of `array` to compute\n     * their sort ranking. The iteratee is invoked with one argument; (value).\n     *\n     * @private\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} iteratee The iteratee invoked per element.\n     * @param {boolean} [retHighest] Specify returning the highest qualified index.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     */\n    function baseSortedIndexBy(array, value, iteratee, retHighest) {\n      value = iteratee(value);\n\n      var low = 0,\n          high = array == null ? 0 : array.length,\n          valIsNaN = value !== value,\n          valIsNull = value === null,\n          valIsSymbol = isSymbol(value),\n          valIsUndefined = value === undefined;\n\n      while (low < high) {\n        var mid = nativeFloor((low + high) / 2),\n            computed = iteratee(array[mid]),\n            othIsDefined = computed !== undefined,\n            othIsNull = computed === null,\n            othIsReflexive = computed === computed,\n            othIsSymbol = isSymbol(computed);\n\n        if (valIsNaN) {\n          var setLow = retHighest || othIsReflexive;\n        } else if (valIsUndefined) {\n          setLow = othIsReflexive && (retHighest || othIsDefined);\n        } else if (valIsNull) {\n          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);\n        } else if (valIsSymbol) {\n          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);\n        } else if (othIsNull || othIsSymbol) {\n          setLow = false;\n        } else {\n          setLow = retHighest ? (computed <= value) : (computed < value);\n        }\n        if (setLow) {\n          low = mid + 1;\n        } else {\n          high = mid;\n        }\n      }\n      return nativeMin(high, MAX_ARRAY_INDEX);\n    }\n\n    /**\n     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without\n     * support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     */\n    function baseSortedUniq(array, iteratee) {\n      var index = -1,\n          length = array.length,\n          resIndex = 0,\n          result = [];\n\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        if (!index || !eq(computed, seen)) {\n          var seen = computed;\n          result[resIndex++] = value === 0 ? 0 : value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.toNumber` which doesn't ensure correct\n     * conversions of binary, hexadecimal, or octal string values.\n     *\n     * @private\n     * @param {*} value The value to process.\n     * @returns {number} Returns the number.\n     */\n    function baseToNumber(value) {\n      if (typeof value == 'number') {\n        return value;\n      }\n      if (isSymbol(value)) {\n        return NAN;\n      }\n      return +value;\n    }\n\n    /**\n     * The base implementation of `_.toString` which doesn't convert nullish\n     * values to empty strings.\n     *\n     * @private\n     * @param {*} value The value to process.\n     * @returns {string} Returns the string.\n     */\n    function baseToString(value) {\n      // Exit early for strings to avoid a performance hit in some environments.\n      if (typeof value == 'string') {\n        return value;\n      }\n      if (isArray(value)) {\n        // Recursively convert values (susceptible to call stack limits).\n        return arrayMap(value, baseToString) + '';\n      }\n      if (isSymbol(value)) {\n        return symbolToString ? symbolToString.call(value) : '';\n      }\n      var result = (value + '');\n      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n    }\n\n    /**\n     * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     */\n    function baseUniq(array, iteratee, comparator) {\n      var index = -1,\n          includes = arrayIncludes,\n          length = array.length,\n          isCommon = true,\n          result = [],\n          seen = result;\n\n      if (comparator) {\n        isCommon = false;\n        includes = arrayIncludesWith;\n      }\n      else if (length >= LARGE_ARRAY_SIZE) {\n        var set = iteratee ? null : createSet(array);\n        if (set) {\n          return setToArray(set);\n        }\n        isCommon = false;\n        includes = cacheHas;\n        seen = new SetCache;\n      }\n      else {\n        seen = iteratee ? [] : result;\n      }\n      outer:\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        value = (comparator || value !== 0) ? value : 0;\n        if (isCommon && computed === computed) {\n          var seenIndex = seen.length;\n          while (seenIndex--) {\n            if (seen[seenIndex] === computed) {\n              continue outer;\n            }\n          }\n          if (iteratee) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n        else if (!includes(seen, computed, comparator)) {\n          if (seen !== result) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.unset`.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The property path to unset.\n     * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n     */\n    function baseUnset(object, path) {\n      path = castPath(path, object);\n      object = parent(object, path);\n      return object == null || delete object[toKey(last(path))];\n    }\n\n    /**\n     * The base implementation of `_.update`.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to update.\n     * @param {Function} updater The function to produce the updated value.\n     * @param {Function} [customizer] The function to customize path creation.\n     * @returns {Object} Returns `object`.\n     */\n    function baseUpdate(object, path, updater, customizer) {\n      return baseSet(object, path, updater(baseGet(object, path)), customizer);\n    }\n\n    /**\n     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`\n     * without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to query.\n     * @param {Function} predicate The function invoked per iteration.\n     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function baseWhile(array, predicate, isDrop, fromRight) {\n      var length = array.length,\n          index = fromRight ? length : -1;\n\n      while ((fromRight ? index-- : ++index < length) &&\n        predicate(array[index], index, array)) {}\n\n      return isDrop\n        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))\n        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));\n    }\n\n    /**\n     * The base implementation of `wrapperValue` which returns the result of\n     * performing a sequence of actions on the unwrapped `value`, where each\n     * successive action is supplied the return value of the previous.\n     *\n     * @private\n     * @param {*} value The unwrapped value.\n     * @param {Array} actions Actions to perform to resolve the unwrapped value.\n     * @returns {*} Returns the resolved value.\n     */\n    function baseWrapperValue(value, actions) {\n      var result = value;\n      if (result instanceof LazyWrapper) {\n        result = result.value();\n      }\n      return arrayReduce(actions, function(result, action) {\n        return action.func.apply(action.thisArg, arrayPush([result], action.args));\n      }, result);\n    }\n\n    /**\n     * The base implementation of methods like `_.xor`, without support for\n     * iteratee shorthands, that accepts an array of arrays to inspect.\n     *\n     * @private\n     * @param {Array} arrays The arrays to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of values.\n     */\n    function baseXor(arrays, iteratee, comparator) {\n      var length = arrays.length;\n      if (length < 2) {\n        return length ? baseUniq(arrays[0]) : [];\n      }\n      var index = -1,\n          result = Array(length);\n\n      while (++index < length) {\n        var array = arrays[index],\n            othIndex = -1;\n\n        while (++othIndex < length) {\n          if (othIndex != index) {\n            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);\n          }\n        }\n      }\n      return baseUniq(baseFlatten(result, 1), iteratee, comparator);\n    }\n\n    /**\n     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.\n     *\n     * @private\n     * @param {Array} props The property identifiers.\n     * @param {Array} values The property values.\n     * @param {Function} assignFunc The function to assign values.\n     * @returns {Object} Returns the new object.\n     */\n    function baseZipObject(props, values, assignFunc) {\n      var index = -1,\n          length = props.length,\n          valsLength = values.length,\n          result = {};\n\n      while (++index < length) {\n        var value = index < valsLength ? values[index] : undefined;\n        assignFunc(result, props[index], value);\n      }\n      return result;\n    }\n\n    /**\n     * Casts `value` to an empty array if it's not an array like object.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @returns {Array|Object} Returns the cast array-like object.\n     */\n    function castArrayLikeObject(value) {\n      return isArrayLikeObject(value) ? value : [];\n    }\n\n    /**\n     * Casts `value` to `identity` if it's not a function.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @returns {Function} Returns cast function.\n     */\n    function castFunction(value) {\n      return typeof value == 'function' ? value : identity;\n    }\n\n    /**\n     * Casts `value` to a path array if it's not one.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @param {Object} [object] The object to query keys on.\n     * @returns {Array} Returns the cast property path array.\n     */\n    function castPath(value, object) {\n      if (isArray(value)) {\n        return value;\n      }\n      return isKey(value, object) ? [value] : stringToPath(toString(value));\n    }\n\n    /**\n     * A `baseRest` alias which can be replaced with `identity` by module\n     * replacement plugins.\n     *\n     * @private\n     * @type {Function}\n     * @param {Function} func The function to apply a rest parameter to.\n     * @returns {Function} Returns the new function.\n     */\n    var castRest = baseRest;\n\n    /**\n     * Casts `array` to a slice if it's needed.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {number} start The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the cast slice.\n     */\n    function castSlice(array, start, end) {\n      var length = array.length;\n      end = end === undefined ? length : end;\n      return (!start && end >= length) ? array : baseSlice(array, start, end);\n    }\n\n    /**\n     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).\n     *\n     * @private\n     * @param {number|Object} id The timer id or timeout object of the timer to clear.\n     */\n    var clearTimeout = ctxClearTimeout || function(id) {\n      return root.clearTimeout(id);\n    };\n\n    /**\n     * Creates a clone of  `buffer`.\n     *\n     * @private\n     * @param {Buffer} buffer The buffer to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Buffer} Returns the cloned buffer.\n     */\n    function cloneBuffer(buffer, isDeep) {\n      if (isDeep) {\n        return buffer.slice();\n      }\n      var length = buffer.length,\n          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n      buffer.copy(result);\n      return result;\n    }\n\n    /**\n     * Creates a clone of `arrayBuffer`.\n     *\n     * @private\n     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n     * @returns {ArrayBuffer} Returns the cloned array buffer.\n     */\n    function cloneArrayBuffer(arrayBuffer) {\n      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n      new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n      return result;\n    }\n\n    /**\n     * Creates a clone of `dataView`.\n     *\n     * @private\n     * @param {Object} dataView The data view to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned data view.\n     */\n    function cloneDataView(dataView, isDeep) {\n      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n    }\n\n    /**\n     * Creates a clone of `map`.\n     *\n     * @private\n     * @param {Object} map The map to clone.\n     * @param {Function} cloneFunc The function to clone values.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned map.\n     */\n    function cloneMap(map, isDeep, cloneFunc) {\n      var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);\n      return arrayReduce(array, addMapEntry, new map.constructor);\n    }\n\n    /**\n     * Creates a clone of `regexp`.\n     *\n     * @private\n     * @param {Object} regexp The regexp to clone.\n     * @returns {Object} Returns the cloned regexp.\n     */\n    function cloneRegExp(regexp) {\n      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n      result.lastIndex = regexp.lastIndex;\n      return result;\n    }\n\n    /**\n     * Creates a clone of `set`.\n     *\n     * @private\n     * @param {Object} set The set to clone.\n     * @param {Function} cloneFunc The function to clone values.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned set.\n     */\n    function cloneSet(set, isDeep, cloneFunc) {\n      var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);\n      return arrayReduce(array, addSetEntry, new set.constructor);\n    }\n\n    /**\n     * Creates a clone of the `symbol` object.\n     *\n     * @private\n     * @param {Object} symbol The symbol object to clone.\n     * @returns {Object} Returns the cloned symbol object.\n     */\n    function cloneSymbol(symbol) {\n      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n    }\n\n    /**\n     * Creates a clone of `typedArray`.\n     *\n     * @private\n     * @param {Object} typedArray The typed array to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned typed array.\n     */\n    function cloneTypedArray(typedArray, isDeep) {\n      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n    }\n\n    /**\n     * Compares values to sort them in ascending order.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {number} Returns the sort order indicator for `value`.\n     */\n    function compareAscending(value, other) {\n      if (value !== other) {\n        var valIsDefined = value !== undefined,\n            valIsNull = value === null,\n            valIsReflexive = value === value,\n            valIsSymbol = isSymbol(value);\n\n        var othIsDefined = other !== undefined,\n            othIsNull = other === null,\n            othIsReflexive = other === other,\n            othIsSymbol = isSymbol(other);\n\n        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n            (valIsNull && othIsDefined && othIsReflexive) ||\n            (!valIsDefined && othIsReflexive) ||\n            !valIsReflexive) {\n          return 1;\n        }\n        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n            (othIsNull && valIsDefined && valIsReflexive) ||\n            (!othIsDefined && valIsReflexive) ||\n            !othIsReflexive) {\n          return -1;\n        }\n      }\n      return 0;\n    }\n\n    /**\n     * Used by `_.orderBy` to compare multiple properties of a value to another\n     * and stable sort them.\n     *\n     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,\n     * specify an order of \"desc\" for descending or \"asc\" for ascending sort order\n     * of corresponding values.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {boolean[]|string[]} orders The order to sort by for each property.\n     * @returns {number} Returns the sort order indicator for `object`.\n     */\n    function compareMultiple(object, other, orders) {\n      var index = -1,\n          objCriteria = object.criteria,\n          othCriteria = other.criteria,\n          length = objCriteria.length,\n          ordersLength = orders.length;\n\n      while (++index < length) {\n        var result = compareAscending(objCriteria[index], othCriteria[index]);\n        if (result) {\n          if (index >= ordersLength) {\n            return result;\n          }\n          var order = orders[index];\n          return result * (order == 'desc' ? -1 : 1);\n        }\n      }\n      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications\n      // that causes it, under certain circumstances, to provide the same value for\n      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247\n      // for more details.\n      //\n      // This also ensures a stable sort in V8 and other engines.\n      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n      return object.index - other.index;\n    }\n\n    /**\n     * Creates an array that is the composition of partially applied arguments,\n     * placeholders, and provided arguments into a single array of arguments.\n     *\n     * @private\n     * @param {Array} args The provided arguments.\n     * @param {Array} partials The arguments to prepend to those provided.\n     * @param {Array} holders The `partials` placeholder indexes.\n     * @params {boolean} [isCurried] Specify composing for a curried function.\n     * @returns {Array} Returns the new array of composed arguments.\n     */\n    function composeArgs(args, partials, holders, isCurried) {\n      var argsIndex = -1,\n          argsLength = args.length,\n          holdersLength = holders.length,\n          leftIndex = -1,\n          leftLength = partials.length,\n          rangeLength = nativeMax(argsLength - holdersLength, 0),\n          result = Array(leftLength + rangeLength),\n          isUncurried = !isCurried;\n\n      while (++leftIndex < leftLength) {\n        result[leftIndex] = partials[leftIndex];\n      }\n      while (++argsIndex < holdersLength) {\n        if (isUncurried || argsIndex < argsLength) {\n          result[holders[argsIndex]] = args[argsIndex];\n        }\n      }\n      while (rangeLength--) {\n        result[leftIndex++] = args[argsIndex++];\n      }\n      return result;\n    }\n\n    /**\n     * This function is like `composeArgs` except that the arguments composition\n     * is tailored for `_.partialRight`.\n     *\n     * @private\n     * @param {Array} args The provided arguments.\n     * @param {Array} partials The arguments to append to those provided.\n     * @param {Array} holders The `partials` placeholder indexes.\n     * @params {boolean} [isCurried] Specify composing for a curried function.\n     * @returns {Array} Returns the new array of composed arguments.\n     */\n    function composeArgsRight(args, partials, holders, isCurried) {\n      var argsIndex = -1,\n          argsLength = args.length,\n          holdersIndex = -1,\n          holdersLength = holders.length,\n          rightIndex = -1,\n          rightLength = partials.length,\n          rangeLength = nativeMax(argsLength - holdersLength, 0),\n          result = Array(rangeLength + rightLength),\n          isUncurried = !isCurried;\n\n      while (++argsIndex < rangeLength) {\n        result[argsIndex] = args[argsIndex];\n      }\n      var offset = argsIndex;\n      while (++rightIndex < rightLength) {\n        result[offset + rightIndex] = partials[rightIndex];\n      }\n      while (++holdersIndex < holdersLength) {\n        if (isUncurried || argsIndex < argsLength) {\n          result[offset + holders[holdersIndex]] = args[argsIndex++];\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Copies the values of `source` to `array`.\n     *\n     * @private\n     * @param {Array} source The array to copy values from.\n     * @param {Array} [array=[]] The array to copy values to.\n     * @returns {Array} Returns `array`.\n     */\n    function copyArray(source, array) {\n      var index = -1,\n          length = source.length;\n\n      array || (array = Array(length));\n      while (++index < length) {\n        array[index] = source[index];\n      }\n      return array;\n    }\n\n    /**\n     * Copies properties of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy properties from.\n     * @param {Array} props The property identifiers to copy.\n     * @param {Object} [object={}] The object to copy properties to.\n     * @param {Function} [customizer] The function to customize copied values.\n     * @returns {Object} Returns `object`.\n     */\n    function copyObject(source, props, object, customizer) {\n      var isNew = !object;\n      object || (object = {});\n\n      var index = -1,\n          length = props.length;\n\n      while (++index < length) {\n        var key = props[index];\n\n        var newValue = customizer\n          ? customizer(object[key], source[key], key, object, source)\n          : undefined;\n\n        if (newValue === undefined) {\n          newValue = source[key];\n        }\n        if (isNew) {\n          baseAssignValue(object, key, newValue);\n        } else {\n          assignValue(object, key, newValue);\n        }\n      }\n      return object;\n    }\n\n    /**\n     * Copies own symbols of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy symbols from.\n     * @param {Object} [object={}] The object to copy symbols to.\n     * @returns {Object} Returns `object`.\n     */\n    function copySymbols(source, object) {\n      return copyObject(source, getSymbols(source), object);\n    }\n\n    /**\n     * Copies own and inherited symbols of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy symbols from.\n     * @param {Object} [object={}] The object to copy symbols to.\n     * @returns {Object} Returns `object`.\n     */\n    function copySymbolsIn(source, object) {\n      return copyObject(source, getSymbolsIn(source), object);\n    }\n\n    /**\n     * Creates a function like `_.groupBy`.\n     *\n     * @private\n     * @param {Function} setter The function to set accumulator values.\n     * @param {Function} [initializer] The accumulator object initializer.\n     * @returns {Function} Returns the new aggregator function.\n     */\n    function createAggregator(setter, initializer) {\n      return function(collection, iteratee) {\n        var func = isArray(collection) ? arrayAggregator : baseAggregator,\n            accumulator = initializer ? initializer() : {};\n\n        return func(collection, setter, getIteratee(iteratee, 2), accumulator);\n      };\n    }\n\n    /**\n     * Creates a function like `_.assign`.\n     *\n     * @private\n     * @param {Function} assigner The function to assign values.\n     * @returns {Function} Returns the new assigner function.\n     */\n    function createAssigner(assigner) {\n      return baseRest(function(object, sources) {\n        var index = -1,\n            length = sources.length,\n            customizer = length > 1 ? sources[length - 1] : undefined,\n            guard = length > 2 ? sources[2] : undefined;\n\n        customizer = (assigner.length > 3 && typeof customizer == 'function')\n          ? (length--, customizer)\n          : undefined;\n\n        if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n          customizer = length < 3 ? undefined : customizer;\n          length = 1;\n        }\n        object = Object(object);\n        while (++index < length) {\n          var source = sources[index];\n          if (source) {\n            assigner(object, source, index, customizer);\n          }\n        }\n        return object;\n      });\n    }\n\n    /**\n     * Creates a `baseEach` or `baseEachRight` function.\n     *\n     * @private\n     * @param {Function} eachFunc The function to iterate over a collection.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new base function.\n     */\n    function createBaseEach(eachFunc, fromRight) {\n      return function(collection, iteratee) {\n        if (collection == null) {\n          return collection;\n        }\n        if (!isArrayLike(collection)) {\n          return eachFunc(collection, iteratee);\n        }\n        var length = collection.length,\n            index = fromRight ? length : -1,\n            iterable = Object(collection);\n\n        while ((fromRight ? index-- : ++index < length)) {\n          if (iteratee(iterable[index], index, iterable) === false) {\n            break;\n          }\n        }\n        return collection;\n      };\n    }\n\n    /**\n     * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new base function.\n     */\n    function createBaseFor(fromRight) {\n      return function(object, iteratee, keysFunc) {\n        var index = -1,\n            iterable = Object(object),\n            props = keysFunc(object),\n            length = props.length;\n\n        while (length--) {\n          var key = props[fromRight ? length : ++index];\n          if (iteratee(iterable[key], key, iterable) === false) {\n            break;\n          }\n        }\n        return object;\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` to invoke it with the optional `this`\n     * binding of `thisArg`.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createBind(func, bitmask, thisArg) {\n      var isBind = bitmask & WRAP_BIND_FLAG,\n          Ctor = createCtor(func);\n\n      function wrapper() {\n        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n        return fn.apply(isBind ? thisArg : this, arguments);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a function like `_.lowerFirst`.\n     *\n     * @private\n     * @param {string} methodName The name of the `String` case method to use.\n     * @returns {Function} Returns the new case function.\n     */\n    function createCaseFirst(methodName) {\n      return function(string) {\n        string = toString(string);\n\n        var strSymbols = hasUnicode(string)\n          ? stringToArray(string)\n          : undefined;\n\n        var chr = strSymbols\n          ? strSymbols[0]\n          : string.charAt(0);\n\n        var trailing = strSymbols\n          ? castSlice(strSymbols, 1).join('')\n          : string.slice(1);\n\n        return chr[methodName]() + trailing;\n      };\n    }\n\n    /**\n     * Creates a function like `_.camelCase`.\n     *\n     * @private\n     * @param {Function} callback The function to combine each word.\n     * @returns {Function} Returns the new compounder function.\n     */\n    function createCompounder(callback) {\n      return function(string) {\n        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');\n      };\n    }\n\n    /**\n     * Creates a function that produces an instance of `Ctor` regardless of\n     * whether it was invoked as part of a `new` expression or by `call` or `apply`.\n     *\n     * @private\n     * @param {Function} Ctor The constructor to wrap.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createCtor(Ctor) {\n      return function() {\n        // Use a `switch` statement to work with class constructors. See\n        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist\n        // for more details.\n        var args = arguments;\n        switch (args.length) {\n          case 0: return new Ctor;\n          case 1: return new Ctor(args[0]);\n          case 2: return new Ctor(args[0], args[1]);\n          case 3: return new Ctor(args[0], args[1], args[2]);\n          case 4: return new Ctor(args[0], args[1], args[2], args[3]);\n          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);\n          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);\n          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);\n        }\n        var thisBinding = baseCreate(Ctor.prototype),\n            result = Ctor.apply(thisBinding, args);\n\n        // Mimic the constructor's `return` behavior.\n        // See https://es5.github.io/#x13.2.2 for more details.\n        return isObject(result) ? result : thisBinding;\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` to enable currying.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {number} arity The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createCurry(func, bitmask, arity) {\n      var Ctor = createCtor(func);\n\n      function wrapper() {\n        var length = arguments.length,\n            args = Array(length),\n            index = length,\n            placeholder = getHolder(wrapper);\n\n        while (index--) {\n          args[index] = arguments[index];\n        }\n        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)\n          ? []\n          : replaceHolders(args, placeholder);\n\n        length -= holders.length;\n        if (length < arity) {\n          return createRecurry(\n            func, bitmask, createHybrid, wrapper.placeholder, undefined,\n            args, holders, undefined, undefined, arity - length);\n        }\n        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n        return apply(fn, this, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a `_.find` or `_.findLast` function.\n     *\n     * @private\n     * @param {Function} findIndexFunc The function to find the collection index.\n     * @returns {Function} Returns the new find function.\n     */\n    function createFind(findIndexFunc) {\n      return function(collection, predicate, fromIndex) {\n        var iterable = Object(collection);\n        if (!isArrayLike(collection)) {\n          var iteratee = getIteratee(predicate, 3);\n          collection = keys(collection);\n          predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n        }\n        var index = findIndexFunc(collection, predicate, fromIndex);\n        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n      };\n    }\n\n    /**\n     * Creates a `_.flow` or `_.flowRight` function.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new flow function.\n     */\n    function createFlow(fromRight) {\n      return flatRest(function(funcs) {\n        var length = funcs.length,\n            index = length,\n            prereq = LodashWrapper.prototype.thru;\n\n        if (fromRight) {\n          funcs.reverse();\n        }\n        while (index--) {\n          var func = funcs[index];\n          if (typeof func != 'function') {\n            throw new TypeError(FUNC_ERROR_TEXT);\n          }\n          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {\n            var wrapper = new LodashWrapper([], true);\n          }\n        }\n        index = wrapper ? index : length;\n        while (++index < length) {\n          func = funcs[index];\n\n          var funcName = getFuncName(func),\n              data = funcName == 'wrapper' ? getData(func) : undefined;\n\n          if (data && isLaziable(data[0]) &&\n                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&\n                !data[4].length && data[9] == 1\n              ) {\n            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);\n          } else {\n            wrapper = (func.length == 1 && isLaziable(func))\n              ? wrapper[funcName]()\n              : wrapper.thru(func);\n          }\n        }\n        return function() {\n          var args = arguments,\n              value = args[0];\n\n          if (wrapper && args.length == 1 && isArray(value)) {\n            return wrapper.plant(value).value();\n          }\n          var index = 0,\n              result = length ? funcs[index].apply(this, args) : value;\n\n          while (++index < length) {\n            result = funcs[index].call(this, result);\n          }\n          return result;\n        };\n      });\n    }\n\n    /**\n     * Creates a function that wraps `func` to invoke it with optional `this`\n     * binding of `thisArg`, partial application, and currying.\n     *\n     * @private\n     * @param {Function|string} func The function or method name to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to prepend to those provided to\n     *  the new function.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [partialsRight] The arguments to append to those provided\n     *  to the new function.\n     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {\n      var isAry = bitmask & WRAP_ARY_FLAG,\n          isBind = bitmask & WRAP_BIND_FLAG,\n          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,\n          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),\n          isFlip = bitmask & WRAP_FLIP_FLAG,\n          Ctor = isBindKey ? undefined : createCtor(func);\n\n      function wrapper() {\n        var length = arguments.length,\n            args = Array(length),\n            index = length;\n\n        while (index--) {\n          args[index] = arguments[index];\n        }\n        if (isCurried) {\n          var placeholder = getHolder(wrapper),\n              holdersCount = countHolders(args, placeholder);\n        }\n        if (partials) {\n          args = composeArgs(args, partials, holders, isCurried);\n        }\n        if (partialsRight) {\n          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);\n        }\n        length -= holdersCount;\n        if (isCurried && length < arity) {\n          var newHolders = replaceHolders(args, placeholder);\n          return createRecurry(\n            func, bitmask, createHybrid, wrapper.placeholder, thisArg,\n            args, newHolders, argPos, ary, arity - length\n          );\n        }\n        var thisBinding = isBind ? thisArg : this,\n            fn = isBindKey ? thisBinding[func] : func;\n\n        length = args.length;\n        if (argPos) {\n          args = reorder(args, argPos);\n        } else if (isFlip && length > 1) {\n          args.reverse();\n        }\n        if (isAry && ary < length) {\n          args.length = ary;\n        }\n        if (this && this !== root && this instanceof wrapper) {\n          fn = Ctor || createCtor(fn);\n        }\n        return fn.apply(thisBinding, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a function like `_.invertBy`.\n     *\n     * @private\n     * @param {Function} setter The function to set accumulator values.\n     * @param {Function} toIteratee The function to resolve iteratees.\n     * @returns {Function} Returns the new inverter function.\n     */\n    function createInverter(setter, toIteratee) {\n      return function(object, iteratee) {\n        return baseInverter(object, setter, toIteratee(iteratee), {});\n      };\n    }\n\n    /**\n     * Creates a function that performs a mathematical operation on two values.\n     *\n     * @private\n     * @param {Function} operator The function to perform the operation.\n     * @param {number} [defaultValue] The value used for `undefined` arguments.\n     * @returns {Function} Returns the new mathematical operation function.\n     */\n    function createMathOperation(operator, defaultValue) {\n      return function(value, other) {\n        var result;\n        if (value === undefined && other === undefined) {\n          return defaultValue;\n        }\n        if (value !== undefined) {\n          result = value;\n        }\n        if (other !== undefined) {\n          if (result === undefined) {\n            return other;\n          }\n          if (typeof value == 'string' || typeof other == 'string') {\n            value = baseToString(value);\n            other = baseToString(other);\n          } else {\n            value = baseToNumber(value);\n            other = baseToNumber(other);\n          }\n          result = operator(value, other);\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Creates a function like `_.over`.\n     *\n     * @private\n     * @param {Function} arrayFunc The function to iterate over iteratees.\n     * @returns {Function} Returns the new over function.\n     */\n    function createOver(arrayFunc) {\n      return flatRest(function(iteratees) {\n        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));\n        return baseRest(function(args) {\n          var thisArg = this;\n          return arrayFunc(iteratees, function(iteratee) {\n            return apply(iteratee, thisArg, args);\n          });\n        });\n      });\n    }\n\n    /**\n     * Creates the padding for `string` based on `length`. The `chars` string\n     * is truncated if the number of characters exceeds `length`.\n     *\n     * @private\n     * @param {number} length The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padding for `string`.\n     */\n    function createPadding(length, chars) {\n      chars = chars === undefined ? ' ' : baseToString(chars);\n\n      var charsLength = chars.length;\n      if (charsLength < 2) {\n        return charsLength ? baseRepeat(chars, length) : chars;\n      }\n      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));\n      return hasUnicode(chars)\n        ? castSlice(stringToArray(result), 0, length).join('')\n        : result.slice(0, length);\n    }\n\n    /**\n     * Creates a function that wraps `func` to invoke it with the `this` binding\n     * of `thisArg` and `partials` prepended to the arguments it receives.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {*} thisArg The `this` binding of `func`.\n     * @param {Array} partials The arguments to prepend to those provided to\n     *  the new function.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createPartial(func, bitmask, thisArg, partials) {\n      var isBind = bitmask & WRAP_BIND_FLAG,\n          Ctor = createCtor(func);\n\n      function wrapper() {\n        var argsIndex = -1,\n            argsLength = arguments.length,\n            leftIndex = -1,\n            leftLength = partials.length,\n            args = Array(leftLength + argsLength),\n            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n\n        while (++leftIndex < leftLength) {\n          args[leftIndex] = partials[leftIndex];\n        }\n        while (argsLength--) {\n          args[leftIndex++] = arguments[++argsIndex];\n        }\n        return apply(fn, isBind ? thisArg : this, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a `_.range` or `_.rangeRight` function.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new range function.\n     */\n    function createRange(fromRight) {\n      return function(start, end, step) {\n        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {\n          end = step = undefined;\n        }\n        // Ensure the sign of `-0` is preserved.\n        start = toFinite(start);\n        if (end === undefined) {\n          end = start;\n          start = 0;\n        } else {\n          end = toFinite(end);\n        }\n        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);\n        return baseRange(start, end, step, fromRight);\n      };\n    }\n\n    /**\n     * Creates a function that performs a relational operation on two values.\n     *\n     * @private\n     * @param {Function} operator The function to perform the operation.\n     * @returns {Function} Returns the new relational operation function.\n     */\n    function createRelationalOperation(operator) {\n      return function(value, other) {\n        if (!(typeof value == 'string' && typeof other == 'string')) {\n          value = toNumber(value);\n          other = toNumber(other);\n        }\n        return operator(value, other);\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` to continue currying.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {Function} wrapFunc The function to create the `func` wrapper.\n     * @param {*} placeholder The placeholder value.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to prepend to those provided to\n     *  the new function.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {\n      var isCurry = bitmask & WRAP_CURRY_FLAG,\n          newHolders = isCurry ? holders : undefined,\n          newHoldersRight = isCurry ? undefined : holders,\n          newPartials = isCurry ? partials : undefined,\n          newPartialsRight = isCurry ? undefined : partials;\n\n      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);\n      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);\n\n      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {\n        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);\n      }\n      var newData = [\n        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,\n        newHoldersRight, argPos, ary, arity\n      ];\n\n      var result = wrapFunc.apply(undefined, newData);\n      if (isLaziable(func)) {\n        setData(result, newData);\n      }\n      result.placeholder = placeholder;\n      return setWrapToString(result, func, bitmask);\n    }\n\n    /**\n     * Creates a function like `_.round`.\n     *\n     * @private\n     * @param {string} methodName The name of the `Math` method to use when rounding.\n     * @returns {Function} Returns the new round function.\n     */\n    function createRound(methodName) {\n      var func = Math[methodName];\n      return function(number, precision) {\n        number = toNumber(number);\n        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);\n        if (precision) {\n          // Shift with exponential notation to avoid floating-point issues.\n          // See [MDN](https://mdn.io/round#Examples) for more details.\n          var pair = (toString(number) + 'e').split('e'),\n              value = func(pair[0] + 'e' + (+pair[1] + precision));\n\n          pair = (toString(value) + 'e').split('e');\n          return +(pair[0] + 'e' + (+pair[1] - precision));\n        }\n        return func(number);\n      };\n    }\n\n    /**\n     * Creates a set object of `values`.\n     *\n     * @private\n     * @param {Array} values The values to add to the set.\n     * @returns {Object} Returns the new set.\n     */\n    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n      return new Set(values);\n    };\n\n    /**\n     * Creates a `_.toPairs` or `_.toPairsIn` function.\n     *\n     * @private\n     * @param {Function} keysFunc The function to get the keys of a given object.\n     * @returns {Function} Returns the new pairs function.\n     */\n    function createToPairs(keysFunc) {\n      return function(object) {\n        var tag = getTag(object);\n        if (tag == mapTag) {\n          return mapToArray(object);\n        }\n        if (tag == setTag) {\n          return setToPairs(object);\n        }\n        return baseToPairs(object, keysFunc(object));\n      };\n    }\n\n    /**\n     * Creates a function that either curries or invokes `func` with optional\n     * `this` binding and partially applied arguments.\n     *\n     * @private\n     * @param {Function|string} func The function or method name to wrap.\n     * @param {number} bitmask The bitmask flags.\n     *    1 - `_.bind`\n     *    2 - `_.bindKey`\n     *    4 - `_.curry` or `_.curryRight` of a bound function\n     *    8 - `_.curry`\n     *   16 - `_.curryRight`\n     *   32 - `_.partial`\n     *   64 - `_.partialRight`\n     *  128 - `_.rearg`\n     *  256 - `_.ary`\n     *  512 - `_.flip`\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to be partially applied.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {\n      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;\n      if (!isBindKey && typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      var length = partials ? partials.length : 0;\n      if (!length) {\n        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);\n        partials = holders = undefined;\n      }\n      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);\n      arity = arity === undefined ? arity : toInteger(arity);\n      length -= holders ? holders.length : 0;\n\n      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {\n        var partialsRight = partials,\n            holdersRight = holders;\n\n        partials = holders = undefined;\n      }\n      var data = isBindKey ? undefined : getData(func);\n\n      var newData = [\n        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,\n        argPos, ary, arity\n      ];\n\n      if (data) {\n        mergeData(newData, data);\n      }\n      func = newData[0];\n      bitmask = newData[1];\n      thisArg = newData[2];\n      partials = newData[3];\n      holders = newData[4];\n      arity = newData[9] = newData[9] === undefined\n        ? (isBindKey ? 0 : func.length)\n        : nativeMax(newData[9] - length, 0);\n\n      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {\n        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);\n      }\n      if (!bitmask || bitmask == WRAP_BIND_FLAG) {\n        var result = createBind(func, bitmask, thisArg);\n      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {\n        result = createCurry(func, bitmask, arity);\n      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {\n        result = createPartial(func, bitmask, thisArg, partials);\n      } else {\n        result = createHybrid.apply(undefined, newData);\n      }\n      var setter = data ? baseSetData : setData;\n      return setWrapToString(setter(result, newData), func, bitmask);\n    }\n\n    /**\n     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties\n     * of source objects to the destination object for all destination properties\n     * that resolve to `undefined`.\n     *\n     * @private\n     * @param {*} objValue The destination value.\n     * @param {*} srcValue The source value.\n     * @param {string} key The key of the property to assign.\n     * @param {Object} object The parent object of `objValue`.\n     * @returns {*} Returns the value to assign.\n     */\n    function customDefaultsAssignIn(objValue, srcValue, key, object) {\n      if (objValue === undefined ||\n          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {\n        return srcValue;\n      }\n      return objValue;\n    }\n\n    /**\n     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n     * objects into destination objects that are passed thru.\n     *\n     * @private\n     * @param {*} objValue The destination value.\n     * @param {*} srcValue The source value.\n     * @param {string} key The key of the property to merge.\n     * @param {Object} object The parent object of `objValue`.\n     * @param {Object} source The parent object of `srcValue`.\n     * @param {Object} [stack] Tracks traversed source values and their merged\n     *  counterparts.\n     * @returns {*} Returns the value to assign.\n     */\n    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n      if (isObject(objValue) && isObject(srcValue)) {\n        // Recursively merge objects and arrays (susceptible to call stack limits).\n        stack.set(srcValue, objValue);\n        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n        stack['delete'](srcValue);\n      }\n      return objValue;\n    }\n\n    /**\n     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain\n     * objects.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @param {string} key The key of the property to inspect.\n     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.\n     */\n    function customOmitClone(value) {\n      return isPlainObject(value) ? undefined : value;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for arrays with support for\n     * partial deep comparisons.\n     *\n     * @private\n     * @param {Array} array The array to compare.\n     * @param {Array} other The other array to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} stack Tracks traversed `array` and `other` objects.\n     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n     */\n    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n          arrLength = array.length,\n          othLength = other.length;\n\n      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n        return false;\n      }\n      // Assume cyclic values are equal.\n      var stacked = stack.get(array);\n      if (stacked && stack.get(other)) {\n        return stacked == other;\n      }\n      var index = -1,\n          result = true,\n          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n      stack.set(array, other);\n      stack.set(other, array);\n\n      // Ignore non-index properties.\n      while (++index < arrLength) {\n        var arrValue = array[index],\n            othValue = other[index];\n\n        if (customizer) {\n          var compared = isPartial\n            ? customizer(othValue, arrValue, index, other, array, stack)\n            : customizer(arrValue, othValue, index, array, other, stack);\n        }\n        if (compared !== undefined) {\n          if (compared) {\n            continue;\n          }\n          result = false;\n          break;\n        }\n        // Recursively compare arrays (susceptible to call stack limits).\n        if (seen) {\n          if (!arraySome(other, function(othValue, othIndex) {\n                if (!cacheHas(seen, othIndex) &&\n                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n                  return seen.push(othIndex);\n                }\n              })) {\n            result = false;\n            break;\n          }\n        } else if (!(\n              arrValue === othValue ||\n                equalFunc(arrValue, othValue, bitmask, customizer, stack)\n            )) {\n          result = false;\n          break;\n        }\n      }\n      stack['delete'](array);\n      stack['delete'](other);\n      return result;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for comparing objects of\n     * the same `toStringTag`.\n     *\n     * **Note:** This function only supports comparing values with tags of\n     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {string} tag The `toStringTag` of the objects to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} stack Tracks traversed `object` and `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n      switch (tag) {\n        case dataViewTag:\n          if ((object.byteLength != other.byteLength) ||\n              (object.byteOffset != other.byteOffset)) {\n            return false;\n          }\n          object = object.buffer;\n          other = other.buffer;\n\n        case arrayBufferTag:\n          if ((object.byteLength != other.byteLength) ||\n              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n            return false;\n          }\n          return true;\n\n        case boolTag:\n        case dateTag:\n        case numberTag:\n          // Coerce booleans to `1` or `0` and dates to milliseconds.\n          // Invalid dates are coerced to `NaN`.\n          return eq(+object, +other);\n\n        case errorTag:\n          return object.name == other.name && object.message == other.message;\n\n        case regexpTag:\n        case stringTag:\n          // Coerce regexes to strings and treat strings, primitives and objects,\n          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n          // for more details.\n          return object == (other + '');\n\n        case mapTag:\n          var convert = mapToArray;\n\n        case setTag:\n          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n          convert || (convert = setToArray);\n\n          if (object.size != other.size && !isPartial) {\n            return false;\n          }\n          // Assume cyclic values are equal.\n          var stacked = stack.get(object);\n          if (stacked) {\n            return stacked == other;\n          }\n          bitmask |= COMPARE_UNORDERED_FLAG;\n\n          // Recursively compare objects (susceptible to call stack limits).\n          stack.set(object, other);\n          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n          stack['delete'](object);\n          return result;\n\n        case symbolTag:\n          if (symbolValueOf) {\n            return symbolValueOf.call(object) == symbolValueOf.call(other);\n          }\n      }\n      return false;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for objects with support for\n     * partial deep comparisons.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} stack Tracks traversed `object` and `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n          objProps = getAllKeys(object),\n          objLength = objProps.length,\n          othProps = getAllKeys(other),\n          othLength = othProps.length;\n\n      if (objLength != othLength && !isPartial) {\n        return false;\n      }\n      var index = objLength;\n      while (index--) {\n        var key = objProps[index];\n        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n          return false;\n        }\n      }\n      // Assume cyclic values are equal.\n      var stacked = stack.get(object);\n      if (stacked && stack.get(other)) {\n        return stacked == other;\n      }\n      var result = true;\n      stack.set(object, other);\n      stack.set(other, object);\n\n      var skipCtor = isPartial;\n      while (++index < objLength) {\n        key = objProps[index];\n        var objValue = object[key],\n            othValue = other[key];\n\n        if (customizer) {\n          var compared = isPartial\n            ? customizer(othValue, objValue, key, other, object, stack)\n            : customizer(objValue, othValue, key, object, other, stack);\n        }\n        // Recursively compare objects (susceptible to call stack limits).\n        if (!(compared === undefined\n              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n              : compared\n            )) {\n          result = false;\n          break;\n        }\n        skipCtor || (skipCtor = key == 'constructor');\n      }\n      if (result && !skipCtor) {\n        var objCtor = object.constructor,\n            othCtor = other.constructor;\n\n        // Non `Object` object instances with different constructors are not equal.\n        if (objCtor != othCtor &&\n            ('constructor' in object && 'constructor' in other) &&\n            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n              typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n          result = false;\n        }\n      }\n      stack['delete'](object);\n      stack['delete'](other);\n      return result;\n    }\n\n    /**\n     * A specialized version of `baseRest` which flattens the rest array.\n     *\n     * @private\n     * @param {Function} func The function to apply a rest parameter to.\n     * @returns {Function} Returns the new function.\n     */\n    function flatRest(func) {\n      return setToString(overRest(func, undefined, flatten), func + '');\n    }\n\n    /**\n     * Creates an array of own enumerable property names and symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names and symbols.\n     */\n    function getAllKeys(object) {\n      return baseGetAllKeys(object, keys, getSymbols);\n    }\n\n    /**\n     * Creates an array of own and inherited enumerable property names and\n     * symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names and symbols.\n     */\n    function getAllKeysIn(object) {\n      return baseGetAllKeys(object, keysIn, getSymbolsIn);\n    }\n\n    /**\n     * Gets metadata for `func`.\n     *\n     * @private\n     * @param {Function} func The function to query.\n     * @returns {*} Returns the metadata for `func`.\n     */\n    var getData = !metaMap ? noop : function(func) {\n      return metaMap.get(func);\n    };\n\n    /**\n     * Gets the name of `func`.\n     *\n     * @private\n     * @param {Function} func The function to query.\n     * @returns {string} Returns the function name.\n     */\n    function getFuncName(func) {\n      var result = (func.name + ''),\n          array = realNames[result],\n          length = hasOwnProperty.call(realNames, result) ? array.length : 0;\n\n      while (length--) {\n        var data = array[length],\n            otherFunc = data.func;\n        if (otherFunc == null || otherFunc == func) {\n          return data.name;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Gets the argument placeholder value for `func`.\n     *\n     * @private\n     * @param {Function} func The function to inspect.\n     * @returns {*} Returns the placeholder value.\n     */\n    function getHolder(func) {\n      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;\n      return object.placeholder;\n    }\n\n    /**\n     * Gets the appropriate \"iteratee\" function. If `_.iteratee` is customized,\n     * this function returns the custom method, otherwise it returns `baseIteratee`.\n     * If arguments are provided, the chosen function is invoked with them and\n     * its result is returned.\n     *\n     * @private\n     * @param {*} [value] The value to convert to an iteratee.\n     * @param {number} [arity] The arity of the created iteratee.\n     * @returns {Function} Returns the chosen function or its result.\n     */\n    function getIteratee() {\n      var result = lodash.iteratee || iteratee;\n      result = result === iteratee ? baseIteratee : result;\n      return arguments.length ? result(arguments[0], arguments[1]) : result;\n    }\n\n    /**\n     * Gets the data for `map`.\n     *\n     * @private\n     * @param {Object} map The map to query.\n     * @param {string} key The reference key.\n     * @returns {*} Returns the map data.\n     */\n    function getMapData(map, key) {\n      var data = map.__data__;\n      return isKeyable(key)\n        ? data[typeof key == 'string' ? 'string' : 'hash']\n        : data.map;\n    }\n\n    /**\n     * Gets the property names, values, and compare flags of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the match data of `object`.\n     */\n    function getMatchData(object) {\n      var result = keys(object),\n          length = result.length;\n\n      while (length--) {\n        var key = result[length],\n            value = object[key];\n\n        result[length] = [key, value, isStrictComparable(value)];\n      }\n      return result;\n    }\n\n    /**\n     * Gets the native function at `key` of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {string} key The key of the method to get.\n     * @returns {*} Returns the function if it's native, else `undefined`.\n     */\n    function getNative(object, key) {\n      var value = getValue(object, key);\n      return baseIsNative(value) ? value : undefined;\n    }\n\n    /**\n     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the raw `toStringTag`.\n     */\n    function getRawTag(value) {\n      var isOwn = hasOwnProperty.call(value, symToStringTag),\n          tag = value[symToStringTag];\n\n      try {\n        value[symToStringTag] = undefined;\n        var unmasked = true;\n      } catch (e) {}\n\n      var result = nativeObjectToString.call(value);\n      if (unmasked) {\n        if (isOwn) {\n          value[symToStringTag] = tag;\n        } else {\n          delete value[symToStringTag];\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Creates an array of the own enumerable symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of symbols.\n     */\n    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n      if (object == null) {\n        return [];\n      }\n      object = Object(object);\n      return arrayFilter(nativeGetSymbols(object), function(symbol) {\n        return propertyIsEnumerable.call(object, symbol);\n      });\n    };\n\n    /**\n     * Creates an array of the own and inherited enumerable symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of symbols.\n     */\n    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n      var result = [];\n      while (object) {\n        arrayPush(result, getSymbols(object));\n        object = getPrototype(object);\n      }\n      return result;\n    };\n\n    /**\n     * Gets the `toStringTag` of `value`.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the `toStringTag`.\n     */\n    var getTag = baseGetTag;\n\n    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\n    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n        (Map && getTag(new Map) != mapTag) ||\n        (Promise && getTag(Promise.resolve()) != promiseTag) ||\n        (Set && getTag(new Set) != setTag) ||\n        (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n      getTag = function(value) {\n        var result = baseGetTag(value),\n            Ctor = result == objectTag ? value.constructor : undefined,\n            ctorString = Ctor ? toSource(Ctor) : '';\n\n        if (ctorString) {\n          switch (ctorString) {\n            case dataViewCtorString: return dataViewTag;\n            case mapCtorString: return mapTag;\n            case promiseCtorString: return promiseTag;\n            case setCtorString: return setTag;\n            case weakMapCtorString: return weakMapTag;\n          }\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Gets the view, applying any `transforms` to the `start` and `end` positions.\n     *\n     * @private\n     * @param {number} start The start of the view.\n     * @param {number} end The end of the view.\n     * @param {Array} transforms The transformations to apply to the view.\n     * @returns {Object} Returns an object containing the `start` and `end`\n     *  positions of the view.\n     */\n    function getView(start, end, transforms) {\n      var index = -1,\n          length = transforms.length;\n\n      while (++index < length) {\n        var data = transforms[index],\n            size = data.size;\n\n        switch (data.type) {\n          case 'drop':      start += size; break;\n          case 'dropRight': end -= size; break;\n          case 'take':      end = nativeMin(end, start + size); break;\n          case 'takeRight': start = nativeMax(start, end - size); break;\n        }\n      }\n      return { 'start': start, 'end': end };\n    }\n\n    /**\n     * Extracts wrapper details from the `source` body comment.\n     *\n     * @private\n     * @param {string} source The source to inspect.\n     * @returns {Array} Returns the wrapper details.\n     */\n    function getWrapDetails(source) {\n      var match = source.match(reWrapDetails);\n      return match ? match[1].split(reSplitDetails) : [];\n    }\n\n    /**\n     * Checks if `path` exists on `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @param {Function} hasFunc The function to check properties.\n     * @returns {boolean} Returns `true` if `path` exists, else `false`.\n     */\n    function hasPath(object, path, hasFunc) {\n      path = castPath(path, object);\n\n      var index = -1,\n          length = path.length,\n          result = false;\n\n      while (++index < length) {\n        var key = toKey(path[index]);\n        if (!(result = object != null && hasFunc(object, key))) {\n          break;\n        }\n        object = object[key];\n      }\n      if (result || ++index != length) {\n        return result;\n      }\n      length = object == null ? 0 : object.length;\n      return !!length && isLength(length) && isIndex(key, length) &&\n        (isArray(object) || isArguments(object));\n    }\n\n    /**\n     * Initializes an array clone.\n     *\n     * @private\n     * @param {Array} array The array to clone.\n     * @returns {Array} Returns the initialized clone.\n     */\n    function initCloneArray(array) {\n      var length = array.length,\n          result = array.constructor(length);\n\n      // Add properties assigned by `RegExp#exec`.\n      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n        result.index = array.index;\n        result.input = array.input;\n      }\n      return result;\n    }\n\n    /**\n     * Initializes an object clone.\n     *\n     * @private\n     * @param {Object} object The object to clone.\n     * @returns {Object} Returns the initialized clone.\n     */\n    function initCloneObject(object) {\n      return (typeof object.constructor == 'function' && !isPrototype(object))\n        ? baseCreate(getPrototype(object))\n        : {};\n    }\n\n    /**\n     * Initializes an object clone based on its `toStringTag`.\n     *\n     * **Note:** This function only supports cloning values with tags of\n     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n     *\n     * @private\n     * @param {Object} object The object to clone.\n     * @param {string} tag The `toStringTag` of the object to clone.\n     * @param {Function} cloneFunc The function to clone values.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the initialized clone.\n     */\n    function initCloneByTag(object, tag, cloneFunc, isDeep) {\n      var Ctor = object.constructor;\n      switch (tag) {\n        case arrayBufferTag:\n          return cloneArrayBuffer(object);\n\n        case boolTag:\n        case dateTag:\n          return new Ctor(+object);\n\n        case dataViewTag:\n          return cloneDataView(object, isDeep);\n\n        case float32Tag: case float64Tag:\n        case int8Tag: case int16Tag: case int32Tag:\n        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n          return cloneTypedArray(object, isDeep);\n\n        case mapTag:\n          return cloneMap(object, isDeep, cloneFunc);\n\n        case numberTag:\n        case stringTag:\n          return new Ctor(object);\n\n        case regexpTag:\n          return cloneRegExp(object);\n\n        case setTag:\n          return cloneSet(object, isDeep, cloneFunc);\n\n        case symbolTag:\n          return cloneSymbol(object);\n      }\n    }\n\n    /**\n     * Inserts wrapper `details` in a comment at the top of the `source` body.\n     *\n     * @private\n     * @param {string} source The source to modify.\n     * @returns {Array} details The details to insert.\n     * @returns {string} Returns the modified source.\n     */\n    function insertWrapDetails(source, details) {\n      var length = details.length;\n      if (!length) {\n        return source;\n      }\n      var lastIndex = length - 1;\n      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];\n      details = details.join(length > 2 ? ', ' : ' ');\n      return source.replace(reWrapComment, '{\\n/* [wrapped with ' + details + '] */\\n');\n    }\n\n    /**\n     * Checks if `value` is a flattenable `arguments` object or array.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n     */\n    function isFlattenable(value) {\n      return isArray(value) || isArguments(value) ||\n        !!(spreadableSymbol && value && value[spreadableSymbol]);\n    }\n\n    /**\n     * Checks if `value` is a valid array-like index.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n     */\n    function isIndex(value, length) {\n      length = length == null ? MAX_SAFE_INTEGER : length;\n      return !!length &&\n        (typeof value == 'number' || reIsUint.test(value)) &&\n        (value > -1 && value % 1 == 0 && value < length);\n    }\n\n    /**\n     * Checks if the given arguments are from an iteratee call.\n     *\n     * @private\n     * @param {*} value The potential iteratee value argument.\n     * @param {*} index The potential iteratee index or key argument.\n     * @param {*} object The potential iteratee object argument.\n     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n     *  else `false`.\n     */\n    function isIterateeCall(value, index, object) {\n      if (!isObject(object)) {\n        return false;\n      }\n      var type = typeof index;\n      if (type == 'number'\n            ? (isArrayLike(object) && isIndex(index, object.length))\n            : (type == 'string' && index in object)\n          ) {\n        return eq(object[index], value);\n      }\n      return false;\n    }\n\n    /**\n     * Checks if `value` is a property name and not a property path.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @param {Object} [object] The object to query keys on.\n     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n     */\n    function isKey(value, object) {\n      if (isArray(value)) {\n        return false;\n      }\n      var type = typeof value;\n      if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n          value == null || isSymbol(value)) {\n        return true;\n      }\n      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n        (object != null && value in Object(object));\n    }\n\n    /**\n     * Checks if `value` is suitable for use as unique object key.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n     */\n    function isKeyable(value) {\n      var type = typeof value;\n      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n        ? (value !== '__proto__')\n        : (value === null);\n    }\n\n    /**\n     * Checks if `func` has a lazy counterpart.\n     *\n     * @private\n     * @param {Function} func The function to check.\n     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,\n     *  else `false`.\n     */\n    function isLaziable(func) {\n      var funcName = getFuncName(func),\n          other = lodash[funcName];\n\n      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {\n        return false;\n      }\n      if (func === other) {\n        return true;\n      }\n      var data = getData(other);\n      return !!data && func === data[0];\n    }\n\n    /**\n     * Checks if `func` has its source masked.\n     *\n     * @private\n     * @param {Function} func The function to check.\n     * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n     */\n    function isMasked(func) {\n      return !!maskSrcKey && (maskSrcKey in func);\n    }\n\n    /**\n     * Checks if `func` is capable of being masked.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.\n     */\n    var isMaskable = coreJsData ? isFunction : stubFalse;\n\n    /**\n     * Checks if `value` is likely a prototype object.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n     */\n    function isPrototype(value) {\n      var Ctor = value && value.constructor,\n          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n      return value === proto;\n    }\n\n    /**\n     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` if suitable for strict\n     *  equality comparisons, else `false`.\n     */\n    function isStrictComparable(value) {\n      return value === value && !isObject(value);\n    }\n\n    /**\n     * A specialized version of `matchesProperty` for source values suitable\n     * for strict equality comparisons, i.e. `===`.\n     *\n     * @private\n     * @param {string} key The key of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new spec function.\n     */\n    function matchesStrictComparable(key, srcValue) {\n      return function(object) {\n        if (object == null) {\n          return false;\n        }\n        return object[key] === srcValue &&\n          (srcValue !== undefined || (key in Object(object)));\n      };\n    }\n\n    /**\n     * A specialized version of `_.memoize` which clears the memoized function's\n     * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n     *\n     * @private\n     * @param {Function} func The function to have its output memoized.\n     * @returns {Function} Returns the new memoized function.\n     */\n    function memoizeCapped(func) {\n      var result = memoize(func, function(key) {\n        if (cache.size === MAX_MEMOIZE_SIZE) {\n          cache.clear();\n        }\n        return key;\n      });\n\n      var cache = result.cache;\n      return result;\n    }\n\n    /**\n     * Merges the function metadata of `source` into `data`.\n     *\n     * Merging metadata reduces the number of wrappers used to invoke a function.\n     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`\n     * may be applied regardless of execution order. Methods like `_.ary` and\n     * `_.rearg` modify function arguments, making the order in which they are\n     * executed important, preventing the merging of metadata. However, we make\n     * an exception for a safe combined case where curried functions have `_.ary`\n     * and or `_.rearg` applied.\n     *\n     * @private\n     * @param {Array} data The destination metadata.\n     * @param {Array} source The source metadata.\n     * @returns {Array} Returns `data`.\n     */\n    function mergeData(data, source) {\n      var bitmask = data[1],\n          srcBitmask = source[1],\n          newBitmask = bitmask | srcBitmask,\n          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);\n\n      var isCombo =\n        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||\n        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||\n        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));\n\n      // Exit early if metadata can't be merged.\n      if (!(isCommon || isCombo)) {\n        return data;\n      }\n      // Use source `thisArg` if available.\n      if (srcBitmask & WRAP_BIND_FLAG) {\n        data[2] = source[2];\n        // Set when currying a bound function.\n        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;\n      }\n      // Compose partial arguments.\n      var value = source[3];\n      if (value) {\n        var partials = data[3];\n        data[3] = partials ? composeArgs(partials, value, source[4]) : value;\n        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];\n      }\n      // Compose partial right arguments.\n      value = source[5];\n      if (value) {\n        partials = data[5];\n        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;\n        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];\n      }\n      // Use source `argPos` if available.\n      value = source[7];\n      if (value) {\n        data[7] = value;\n      }\n      // Use source `ary` if it's smaller.\n      if (srcBitmask & WRAP_ARY_FLAG) {\n        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);\n      }\n      // Use source `arity` if one is not provided.\n      if (data[9] == null) {\n        data[9] = source[9];\n      }\n      // Use source `func` and merge bitmasks.\n      data[0] = source[0];\n      data[1] = newBitmask;\n\n      return data;\n    }\n\n    /**\n     * This function is like\n     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n     * except that it includes inherited enumerable properties.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function nativeKeysIn(object) {\n      var result = [];\n      if (object != null) {\n        for (var key in Object(object)) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Converts `value` to a string using `Object.prototype.toString`.\n     *\n     * @private\n     * @param {*} value The value to convert.\n     * @returns {string} Returns the converted string.\n     */\n    function objectToString(value) {\n      return nativeObjectToString.call(value);\n    }\n\n    /**\n     * A specialized version of `baseRest` which transforms the rest array.\n     *\n     * @private\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @param {Function} transform The rest array transform.\n     * @returns {Function} Returns the new function.\n     */\n    function overRest(func, start, transform) {\n      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n      return function() {\n        var args = arguments,\n            index = -1,\n            length = nativeMax(args.length - start, 0),\n            array = Array(length);\n\n        while (++index < length) {\n          array[index] = args[start + index];\n        }\n        index = -1;\n        var otherArgs = Array(start + 1);\n        while (++index < start) {\n          otherArgs[index] = args[index];\n        }\n        otherArgs[start] = transform(array);\n        return apply(func, this, otherArgs);\n      };\n    }\n\n    /**\n     * Gets the parent value at `path` of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array} path The path to get the parent value of.\n     * @returns {*} Returns the parent value.\n     */\n    function parent(object, path) {\n      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n    }\n\n    /**\n     * Reorder `array` according to the specified indexes where the element at\n     * the first index is assigned as the first element, the element at\n     * the second index is assigned as the second element, and so on.\n     *\n     * @private\n     * @param {Array} array The array to reorder.\n     * @param {Array} indexes The arranged array indexes.\n     * @returns {Array} Returns `array`.\n     */\n    function reorder(array, indexes) {\n      var arrLength = array.length,\n          length = nativeMin(indexes.length, arrLength),\n          oldArray = copyArray(array);\n\n      while (length--) {\n        var index = indexes[length];\n        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;\n      }\n      return array;\n    }\n\n    /**\n     * Sets metadata for `func`.\n     *\n     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short\n     * period of time, it will trip its breaker and transition to an identity\n     * function to avoid garbage collection pauses in V8. See\n     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)\n     * for more details.\n     *\n     * @private\n     * @param {Function} func The function to associate metadata with.\n     * @param {*} data The metadata.\n     * @returns {Function} Returns `func`.\n     */\n    var setData = shortOut(baseSetData);\n\n    /**\n     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).\n     *\n     * @private\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @returns {number|Object} Returns the timer id or timeout object.\n     */\n    var setTimeout = ctxSetTimeout || function(func, wait) {\n      return root.setTimeout(func, wait);\n    };\n\n    /**\n     * Sets the `toString` method of `func` to return `string`.\n     *\n     * @private\n     * @param {Function} func The function to modify.\n     * @param {Function} string The `toString` result.\n     * @returns {Function} Returns `func`.\n     */\n    var setToString = shortOut(baseSetToString);\n\n    /**\n     * Sets the `toString` method of `wrapper` to mimic the source of `reference`\n     * with wrapper details in a comment at the top of the source body.\n     *\n     * @private\n     * @param {Function} wrapper The function to modify.\n     * @param {Function} reference The reference function.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @returns {Function} Returns `wrapper`.\n     */\n    function setWrapToString(wrapper, reference, bitmask) {\n      var source = (reference + '');\n      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));\n    }\n\n    /**\n     * Creates a function that'll short out and invoke `identity` instead\n     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n     * milliseconds.\n     *\n     * @private\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new shortable function.\n     */\n    function shortOut(func) {\n      var count = 0,\n          lastCalled = 0;\n\n      return function() {\n        var stamp = nativeNow(),\n            remaining = HOT_SPAN - (stamp - lastCalled);\n\n        lastCalled = stamp;\n        if (remaining > 0) {\n          if (++count >= HOT_COUNT) {\n            return arguments[0];\n          }\n        } else {\n          count = 0;\n        }\n        return func.apply(undefined, arguments);\n      };\n    }\n\n    /**\n     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.\n     *\n     * @private\n     * @param {Array} array The array to shuffle.\n     * @param {number} [size=array.length] The size of `array`.\n     * @returns {Array} Returns `array`.\n     */\n    function shuffleSelf(array, size) {\n      var index = -1,\n          length = array.length,\n          lastIndex = length - 1;\n\n      size = size === undefined ? length : size;\n      while (++index < size) {\n        var rand = baseRandom(index, lastIndex),\n            value = array[rand];\n\n        array[rand] = array[index];\n        array[index] = value;\n      }\n      array.length = size;\n      return array;\n    }\n\n    /**\n     * Converts `string` to a property path array.\n     *\n     * @private\n     * @param {string} string The string to convert.\n     * @returns {Array} Returns the property path array.\n     */\n    var stringToPath = memoizeCapped(function(string) {\n      var result = [];\n      if (reLeadingDot.test(string)) {\n        result.push('');\n      }\n      string.replace(rePropName, function(match, number, quote, string) {\n        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));\n      });\n      return result;\n    });\n\n    /**\n     * Converts `value` to a string key if it's not a string or symbol.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @returns {string|symbol} Returns the key.\n     */\n    function toKey(value) {\n      if (typeof value == 'string' || isSymbol(value)) {\n        return value;\n      }\n      var result = (value + '');\n      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n    }\n\n    /**\n     * Converts `func` to its source code.\n     *\n     * @private\n     * @param {Function} func The function to convert.\n     * @returns {string} Returns the source code.\n     */\n    function toSource(func) {\n      if (func != null) {\n        try {\n          return funcToString.call(func);\n        } catch (e) {}\n        try {\n          return (func + '');\n        } catch (e) {}\n      }\n      return '';\n    }\n\n    /**\n     * Updates wrapper `details` based on `bitmask` flags.\n     *\n     * @private\n     * @returns {Array} details The details to modify.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @returns {Array} Returns `details`.\n     */\n    function updateWrapDetails(details, bitmask) {\n      arrayEach(wrapFlags, function(pair) {\n        var value = '_.' + pair[0];\n        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {\n          details.push(value);\n        }\n      });\n      return details.sort();\n    }\n\n    /**\n     * Creates a clone of `wrapper`.\n     *\n     * @private\n     * @param {Object} wrapper The wrapper to clone.\n     * @returns {Object} Returns the cloned wrapper.\n     */\n    function wrapperClone(wrapper) {\n      if (wrapper instanceof LazyWrapper) {\n        return wrapper.clone();\n      }\n      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);\n      result.__actions__ = copyArray(wrapper.__actions__);\n      result.__index__  = wrapper.__index__;\n      result.__values__ = wrapper.__values__;\n      return result;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an array of elements split into groups the length of `size`.\n     * If `array` can't be split evenly, the final chunk will be the remaining\n     * elements.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to process.\n     * @param {number} [size=1] The length of each chunk\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the new array of chunks.\n     * @example\n     *\n     * _.chunk(['a', 'b', 'c', 'd'], 2);\n     * // => [['a', 'b'], ['c', 'd']]\n     *\n     * _.chunk(['a', 'b', 'c', 'd'], 3);\n     * // => [['a', 'b', 'c'], ['d']]\n     */\n    function chunk(array, size, guard) {\n      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {\n        size = 1;\n      } else {\n        size = nativeMax(toInteger(size), 0);\n      }\n      var length = array == null ? 0 : array.length;\n      if (!length || size < 1) {\n        return [];\n      }\n      var index = 0,\n          resIndex = 0,\n          result = Array(nativeCeil(length / size));\n\n      while (index < length) {\n        result[resIndex++] = baseSlice(array, index, (index += size));\n      }\n      return result;\n    }\n\n    /**\n     * Creates an array with all falsey values removed. The values `false`, `null`,\n     * `0`, `\"\"`, `undefined`, and `NaN` are falsey.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to compact.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.compact([0, 1, false, 2, '', 3]);\n     * // => [1, 2, 3]\n     */\n    function compact(array) {\n      var index = -1,\n          length = array == null ? 0 : array.length,\n          resIndex = 0,\n          result = [];\n\n      while (++index < length) {\n        var value = array[index];\n        if (value) {\n          result[resIndex++] = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Creates a new array concatenating `array` with any additional arrays\n     * and/or values.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to concatenate.\n     * @param {...*} [values] The values to concatenate.\n     * @returns {Array} Returns the new concatenated array.\n     * @example\n     *\n     * var array = [1];\n     * var other = _.concat(array, 2, [3], [[4]]);\n     *\n     * console.log(other);\n     * // => [1, 2, 3, [4]]\n     *\n     * console.log(array);\n     * // => [1]\n     */\n    function concat() {\n      var length = arguments.length;\n      if (!length) {\n        return [];\n      }\n      var args = Array(length - 1),\n          array = arguments[0],\n          index = length;\n\n      while (index--) {\n        args[index - 1] = arguments[index];\n      }\n      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));\n    }\n\n    /**\n     * Creates an array of `array` values not included in the other given arrays\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons. The order and references of result values are\n     * determined by the first array.\n     *\n     * **Note:** Unlike `_.pullAll`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The values to exclude.\n     * @returns {Array} Returns the new array of filtered values.\n     * @see _.without, _.xor\n     * @example\n     *\n     * _.difference([2, 1], [2, 3]);\n     * // => [1]\n     */\n    var difference = baseRest(function(array, values) {\n      return isArrayLikeObject(array)\n        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))\n        : [];\n    });\n\n    /**\n     * This method is like `_.difference` except that it accepts `iteratee` which\n     * is invoked for each element of `array` and `values` to generate the criterion\n     * by which they're compared. The order and references of result values are\n     * determined by the first array. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The values to exclude.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n     * // => [1.2]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');\n     * // => [{ 'x': 2 }]\n     */\n    var differenceBy = baseRest(function(array, values) {\n      var iteratee = last(values);\n      if (isArrayLikeObject(iteratee)) {\n        iteratee = undefined;\n      }\n      return isArrayLikeObject(array)\n        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))\n        : [];\n    });\n\n    /**\n     * This method is like `_.difference` except that it accepts `comparator`\n     * which is invoked to compare elements of `array` to `values`. The order and\n     * references of result values are determined by the first array. The comparator\n     * is invoked with two arguments: (arrVal, othVal).\n     *\n     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The values to exclude.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     *\n     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);\n     * // => [{ 'x': 2, 'y': 1 }]\n     */\n    var differenceWith = baseRest(function(array, values) {\n      var comparator = last(values);\n      if (isArrayLikeObject(comparator)) {\n        comparator = undefined;\n      }\n      return isArrayLikeObject(array)\n        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)\n        : [];\n    });\n\n    /**\n     * Creates a slice of `array` with `n` elements dropped from the beginning.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.5.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to drop.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.drop([1, 2, 3]);\n     * // => [2, 3]\n     *\n     * _.drop([1, 2, 3], 2);\n     * // => [3]\n     *\n     * _.drop([1, 2, 3], 5);\n     * // => []\n     *\n     * _.drop([1, 2, 3], 0);\n     * // => [1, 2, 3]\n     */\n    function drop(array, n, guard) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      return baseSlice(array, n < 0 ? 0 : n, length);\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements dropped from the end.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to drop.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.dropRight([1, 2, 3]);\n     * // => [1, 2]\n     *\n     * _.dropRight([1, 2, 3], 2);\n     * // => [1]\n     *\n     * _.dropRight([1, 2, 3], 5);\n     * // => []\n     *\n     * _.dropRight([1, 2, 3], 0);\n     * // => [1, 2, 3]\n     */\n    function dropRight(array, n, guard) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      n = length - n;\n      return baseSlice(array, 0, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` excluding elements dropped from the end.\n     * Elements are dropped until `predicate` returns falsey. The predicate is\n     * invoked with three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.dropRightWhile(users, function(o) { return !o.active; });\n     * // => objects for ['barney']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });\n     * // => objects for ['barney', 'fred']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.dropRightWhile(users, ['active', false]);\n     * // => objects for ['barney']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.dropRightWhile(users, 'active');\n     * // => objects for ['barney', 'fred', 'pebbles']\n     */\n    function dropRightWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3), true, true)\n        : [];\n    }\n\n    /**\n     * Creates a slice of `array` excluding elements dropped from the beginning.\n     * Elements are dropped until `predicate` returns falsey. The predicate is\n     * invoked with three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.dropWhile(users, function(o) { return !o.active; });\n     * // => objects for ['pebbles']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.dropWhile(users, { 'user': 'barney', 'active': false });\n     * // => objects for ['fred', 'pebbles']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.dropWhile(users, ['active', false]);\n     * // => objects for ['pebbles']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.dropWhile(users, 'active');\n     * // => objects for ['barney', 'fred', 'pebbles']\n     */\n    function dropWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3), true)\n        : [];\n    }\n\n    /**\n     * Fills elements of `array` with `value` from `start` up to, but not\n     * including, `end`.\n     *\n     * **Note:** This method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.2.0\n     * @category Array\n     * @param {Array} array The array to fill.\n     * @param {*} value The value to fill `array` with.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _.fill(array, 'a');\n     * console.log(array);\n     * // => ['a', 'a', 'a']\n     *\n     * _.fill(Array(3), 2);\n     * // => [2, 2, 2]\n     *\n     * _.fill([4, 6, 8, 10], '*', 1, 3);\n     * // => [4, '*', '*', 10]\n     */\n    function fill(array, value, start, end) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {\n        start = 0;\n        end = length;\n      }\n      return baseFill(array, value, start, end);\n    }\n\n    /**\n     * This method is like `_.find` except that it returns the index of the first\n     * element `predicate` returns truthy for instead of the element itself.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @returns {number} Returns the index of the found element, else `-1`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.findIndex(users, function(o) { return o.user == 'barney'; });\n     * // => 0\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findIndex(users, { 'user': 'fred', 'active': false });\n     * // => 1\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findIndex(users, ['active', false]);\n     * // => 0\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findIndex(users, 'active');\n     * // => 2\n     */\n    function findIndex(array, predicate, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = fromIndex == null ? 0 : toInteger(fromIndex);\n      if (index < 0) {\n        index = nativeMax(length + index, 0);\n      }\n      return baseFindIndex(array, getIteratee(predicate, 3), index);\n    }\n\n    /**\n     * This method is like `_.findIndex` except that it iterates over elements\n     * of `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=array.length-1] The index to search from.\n     * @returns {number} Returns the index of the found element, else `-1`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });\n     * // => 2\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findLastIndex(users, { 'user': 'barney', 'active': true });\n     * // => 0\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findLastIndex(users, ['active', false]);\n     * // => 2\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findLastIndex(users, 'active');\n     * // => 0\n     */\n    function findLastIndex(array, predicate, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = length - 1;\n      if (fromIndex !== undefined) {\n        index = toInteger(fromIndex);\n        index = fromIndex < 0\n          ? nativeMax(length + index, 0)\n          : nativeMin(index, length - 1);\n      }\n      return baseFindIndex(array, getIteratee(predicate, 3), index, true);\n    }\n\n    /**\n     * Flattens `array` a single level deep.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * _.flatten([1, [2, [3, [4]], 5]]);\n     * // => [1, 2, [3, [4]], 5]\n     */\n    function flatten(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseFlatten(array, 1) : [];\n    }\n\n    /**\n     * Recursively flattens `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * _.flattenDeep([1, [2, [3, [4]], 5]]);\n     * // => [1, 2, 3, 4, 5]\n     */\n    function flattenDeep(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseFlatten(array, INFINITY) : [];\n    }\n\n    /**\n     * Recursively flatten `array` up to `depth` times.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.4.0\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @param {number} [depth=1] The maximum recursion depth.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * var array = [1, [2, [3, [4]], 5]];\n     *\n     * _.flattenDepth(array, 1);\n     * // => [1, 2, [3, [4]], 5]\n     *\n     * _.flattenDepth(array, 2);\n     * // => [1, 2, 3, [4], 5]\n     */\n    function flattenDepth(array, depth) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      depth = depth === undefined ? 1 : toInteger(depth);\n      return baseFlatten(array, depth);\n    }\n\n    /**\n     * The inverse of `_.toPairs`; this method returns an object composed\n     * from key-value `pairs`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} pairs The key-value pairs.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.fromPairs([['a', 1], ['b', 2]]);\n     * // => { 'a': 1, 'b': 2 }\n     */\n    function fromPairs(pairs) {\n      var index = -1,\n          length = pairs == null ? 0 : pairs.length,\n          result = {};\n\n      while (++index < length) {\n        var pair = pairs[index];\n        result[pair[0]] = pair[1];\n      }\n      return result;\n    }\n\n    /**\n     * Gets the first element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @alias first\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {*} Returns the first element of `array`.\n     * @example\n     *\n     * _.head([1, 2, 3]);\n     * // => 1\n     *\n     * _.head([]);\n     * // => undefined\n     */\n    function head(array) {\n      return (array && array.length) ? array[0] : undefined;\n    }\n\n    /**\n     * Gets the index at which the first occurrence of `value` is found in `array`\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons. If `fromIndex` is negative, it's used as the\n     * offset from the end of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.indexOf([1, 2, 1, 2], 2);\n     * // => 1\n     *\n     * // Search from the `fromIndex`.\n     * _.indexOf([1, 2, 1, 2], 2, 2);\n     * // => 3\n     */\n    function indexOf(array, value, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = fromIndex == null ? 0 : toInteger(fromIndex);\n      if (index < 0) {\n        index = nativeMax(length + index, 0);\n      }\n      return baseIndexOf(array, value, index);\n    }\n\n    /**\n     * Gets all but the last element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.initial([1, 2, 3]);\n     * // => [1, 2]\n     */\n    function initial(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseSlice(array, 0, -1) : [];\n    }\n\n    /**\n     * Creates an array of unique values that are included in all given arrays\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons. The order and references of result values are\n     * determined by the first array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of intersecting values.\n     * @example\n     *\n     * _.intersection([2, 1], [2, 3]);\n     * // => [2]\n     */\n    var intersection = baseRest(function(arrays) {\n      var mapped = arrayMap(arrays, castArrayLikeObject);\n      return (mapped.length && mapped[0] === arrays[0])\n        ? baseIntersection(mapped)\n        : [];\n    });\n\n    /**\n     * This method is like `_.intersection` except that it accepts `iteratee`\n     * which is invoked for each element of each `arrays` to generate the criterion\n     * by which they're compared. The order and references of result values are\n     * determined by the first array. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of intersecting values.\n     * @example\n     *\n     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n     * // => [2.1]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }]\n     */\n    var intersectionBy = baseRest(function(arrays) {\n      var iteratee = last(arrays),\n          mapped = arrayMap(arrays, castArrayLikeObject);\n\n      if (iteratee === last(mapped)) {\n        iteratee = undefined;\n      } else {\n        mapped.pop();\n      }\n      return (mapped.length && mapped[0] === arrays[0])\n        ? baseIntersection(mapped, getIteratee(iteratee, 2))\n        : [];\n    });\n\n    /**\n     * This method is like `_.intersection` except that it accepts `comparator`\n     * which is invoked to compare elements of `arrays`. The order and references\n     * of result values are determined by the first array. The comparator is\n     * invoked with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of intersecting values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.intersectionWith(objects, others, _.isEqual);\n     * // => [{ 'x': 1, 'y': 2 }]\n     */\n    var intersectionWith = baseRest(function(arrays) {\n      var comparator = last(arrays),\n          mapped = arrayMap(arrays, castArrayLikeObject);\n\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      if (comparator) {\n        mapped.pop();\n      }\n      return (mapped.length && mapped[0] === arrays[0])\n        ? baseIntersection(mapped, undefined, comparator)\n        : [];\n    });\n\n    /**\n     * Converts all elements in `array` into a string separated by `separator`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to convert.\n     * @param {string} [separator=','] The element separator.\n     * @returns {string} Returns the joined string.\n     * @example\n     *\n     * _.join(['a', 'b', 'c'], '~');\n     * // => 'a~b~c'\n     */\n    function join(array, separator) {\n      return array == null ? '' : nativeJoin.call(array, separator);\n    }\n\n    /**\n     * Gets the last element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {*} Returns the last element of `array`.\n     * @example\n     *\n     * _.last([1, 2, 3]);\n     * // => 3\n     */\n    function last(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? array[length - 1] : undefined;\n    }\n\n    /**\n     * This method is like `_.indexOf` except that it iterates over elements of\n     * `array` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @param {number} [fromIndex=array.length-1] The index to search from.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.lastIndexOf([1, 2, 1, 2], 2);\n     * // => 3\n     *\n     * // Search from the `fromIndex`.\n     * _.lastIndexOf([1, 2, 1, 2], 2, 2);\n     * // => 1\n     */\n    function lastIndexOf(array, value, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = length;\n      if (fromIndex !== undefined) {\n        index = toInteger(fromIndex);\n        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);\n      }\n      return value === value\n        ? strictLastIndexOf(array, value, index)\n        : baseFindIndex(array, baseIsNaN, index, true);\n    }\n\n    /**\n     * Gets the element at index `n` of `array`. If `n` is negative, the nth\n     * element from the end is returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.11.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=0] The index of the element to return.\n     * @returns {*} Returns the nth element of `array`.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'd'];\n     *\n     * _.nth(array, 1);\n     * // => 'b'\n     *\n     * _.nth(array, -2);\n     * // => 'c';\n     */\n    function nth(array, n) {\n      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;\n    }\n\n    /**\n     * Removes all given values from `array` using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`\n     * to remove elements from an array by predicate.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {...*} [values] The values to remove.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n     *\n     * _.pull(array, 'a', 'c');\n     * console.log(array);\n     * // => ['b', 'b']\n     */\n    var pull = baseRest(pullAll);\n\n    /**\n     * This method is like `_.pull` except that it accepts an array of values to remove.\n     *\n     * **Note:** Unlike `_.difference`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n     *\n     * _.pullAll(array, ['a', 'c']);\n     * console.log(array);\n     * // => ['b', 'b']\n     */\n    function pullAll(array, values) {\n      return (array && array.length && values && values.length)\n        ? basePullAll(array, values)\n        : array;\n    }\n\n    /**\n     * This method is like `_.pullAll` except that it accepts `iteratee` which is\n     * invoked for each element of `array` and `values` to generate the criterion\n     * by which they're compared. The iteratee is invoked with one argument: (value).\n     *\n     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];\n     *\n     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');\n     * console.log(array);\n     * // => [{ 'x': 2 }]\n     */\n    function pullAllBy(array, values, iteratee) {\n      return (array && array.length && values && values.length)\n        ? basePullAll(array, values, getIteratee(iteratee, 2))\n        : array;\n    }\n\n    /**\n     * This method is like `_.pullAll` except that it accepts `comparator` which\n     * is invoked to compare elements of `array` to `values`. The comparator is\n     * invoked with two arguments: (arrVal, othVal).\n     *\n     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.6.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];\n     *\n     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);\n     * console.log(array);\n     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]\n     */\n    function pullAllWith(array, values, comparator) {\n      return (array && array.length && values && values.length)\n        ? basePullAll(array, values, undefined, comparator)\n        : array;\n    }\n\n    /**\n     * Removes elements from `array` corresponding to `indexes` and returns an\n     * array of removed elements.\n     *\n     * **Note:** Unlike `_.at`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {...(number|number[])} [indexes] The indexes of elements to remove.\n     * @returns {Array} Returns the new array of removed elements.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'd'];\n     * var pulled = _.pullAt(array, [1, 3]);\n     *\n     * console.log(array);\n     * // => ['a', 'c']\n     *\n     * console.log(pulled);\n     * // => ['b', 'd']\n     */\n    var pullAt = flatRest(function(array, indexes) {\n      var length = array == null ? 0 : array.length,\n          result = baseAt(array, indexes);\n\n      basePullAt(array, arrayMap(indexes, function(index) {\n        return isIndex(index, length) ? +index : index;\n      }).sort(compareAscending));\n\n      return result;\n    });\n\n    /**\n     * Removes all elements from `array` that `predicate` returns truthy for\n     * and returns an array of the removed elements. The predicate is invoked\n     * with three arguments: (value, index, array).\n     *\n     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`\n     * to pull elements from an array by value.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new array of removed elements.\n     * @example\n     *\n     * var array = [1, 2, 3, 4];\n     * var evens = _.remove(array, function(n) {\n     *   return n % 2 == 0;\n     * });\n     *\n     * console.log(array);\n     * // => [1, 3]\n     *\n     * console.log(evens);\n     * // => [2, 4]\n     */\n    function remove(array, predicate) {\n      var result = [];\n      if (!(array && array.length)) {\n        return result;\n      }\n      var index = -1,\n          indexes = [],\n          length = array.length;\n\n      predicate = getIteratee(predicate, 3);\n      while (++index < length) {\n        var value = array[index];\n        if (predicate(value, index, array)) {\n          result.push(value);\n          indexes.push(index);\n        }\n      }\n      basePullAt(array, indexes);\n      return result;\n    }\n\n    /**\n     * Reverses `array` so that the first element becomes the last, the second\n     * element becomes the second to last, and so on.\n     *\n     * **Note:** This method mutates `array` and is based on\n     * [`Array#reverse`](https://mdn.io/Array/reverse).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _.reverse(array);\n     * // => [3, 2, 1]\n     *\n     * console.log(array);\n     * // => [3, 2, 1]\n     */\n    function reverse(array) {\n      return array == null ? array : nativeReverse.call(array);\n    }\n\n    /**\n     * Creates a slice of `array` from `start` up to, but not including, `end`.\n     *\n     * **Note:** This method is used instead of\n     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are\n     * returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to slice.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function slice(array, start, end) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {\n        start = 0;\n        end = length;\n      }\n      else {\n        start = start == null ? 0 : toInteger(start);\n        end = end === undefined ? length : toInteger(end);\n      }\n      return baseSlice(array, start, end);\n    }\n\n    /**\n     * Uses a binary search to determine the lowest index at which `value`\n     * should be inserted into `array` in order to maintain its sort order.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * _.sortedIndex([30, 50], 40);\n     * // => 1\n     */\n    function sortedIndex(array, value) {\n      return baseSortedIndex(array, value);\n    }\n\n    /**\n     * This method is like `_.sortedIndex` except that it accepts `iteratee`\n     * which is invoked for `value` and each element of `array` to compute their\n     * sort ranking. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * var objects = [{ 'x': 4 }, { 'x': 5 }];\n     *\n     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n     * // => 0\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');\n     * // => 0\n     */\n    function sortedIndexBy(array, value, iteratee) {\n      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));\n    }\n\n    /**\n     * This method is like `_.indexOf` except that it performs a binary\n     * search on a sorted `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);\n     * // => 1\n     */\n    function sortedIndexOf(array, value) {\n      var length = array == null ? 0 : array.length;\n      if (length) {\n        var index = baseSortedIndex(array, value);\n        if (index < length && eq(array[index], value)) {\n          return index;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * This method is like `_.sortedIndex` except that it returns the highest\n     * index at which `value` should be inserted into `array` in order to\n     * maintain its sort order.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);\n     * // => 4\n     */\n    function sortedLastIndex(array, value) {\n      return baseSortedIndex(array, value, true);\n    }\n\n    /**\n     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`\n     * which is invoked for `value` and each element of `array` to compute their\n     * sort ranking. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * var objects = [{ 'x': 4 }, { 'x': 5 }];\n     *\n     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n     * // => 1\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');\n     * // => 1\n     */\n    function sortedLastIndexBy(array, value, iteratee) {\n      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);\n    }\n\n    /**\n     * This method is like `_.lastIndexOf` except that it performs a binary\n     * search on a sorted `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);\n     * // => 3\n     */\n    function sortedLastIndexOf(array, value) {\n      var length = array == null ? 0 : array.length;\n      if (length) {\n        var index = baseSortedIndex(array, value, true) - 1;\n        if (eq(array[index], value)) {\n          return index;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * This method is like `_.uniq` except that it's designed and optimized\n     * for sorted arrays.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.sortedUniq([1, 1, 2]);\n     * // => [1, 2]\n     */\n    function sortedUniq(array) {\n      return (array && array.length)\n        ? baseSortedUniq(array)\n        : [];\n    }\n\n    /**\n     * This method is like `_.uniqBy` except that it's designed and optimized\n     * for sorted arrays.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);\n     * // => [1.1, 2.3]\n     */\n    function sortedUniqBy(array, iteratee) {\n      return (array && array.length)\n        ? baseSortedUniq(array, getIteratee(iteratee, 2))\n        : [];\n    }\n\n    /**\n     * Gets all but the first element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.tail([1, 2, 3]);\n     * // => [2, 3]\n     */\n    function tail(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseSlice(array, 1, length) : [];\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements taken from the beginning.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to take.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.take([1, 2, 3]);\n     * // => [1]\n     *\n     * _.take([1, 2, 3], 2);\n     * // => [1, 2]\n     *\n     * _.take([1, 2, 3], 5);\n     * // => [1, 2, 3]\n     *\n     * _.take([1, 2, 3], 0);\n     * // => []\n     */\n    function take(array, n, guard) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      return baseSlice(array, 0, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements taken from the end.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to take.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.takeRight([1, 2, 3]);\n     * // => [3]\n     *\n     * _.takeRight([1, 2, 3], 2);\n     * // => [2, 3]\n     *\n     * _.takeRight([1, 2, 3], 5);\n     * // => [1, 2, 3]\n     *\n     * _.takeRight([1, 2, 3], 0);\n     * // => []\n     */\n    function takeRight(array, n, guard) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      n = length - n;\n      return baseSlice(array, n < 0 ? 0 : n, length);\n    }\n\n    /**\n     * Creates a slice of `array` with elements taken from the end. Elements are\n     * taken until `predicate` returns falsey. The predicate is invoked with\n     * three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.takeRightWhile(users, function(o) { return !o.active; });\n     * // => objects for ['fred', 'pebbles']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });\n     * // => objects for ['pebbles']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.takeRightWhile(users, ['active', false]);\n     * // => objects for ['fred', 'pebbles']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.takeRightWhile(users, 'active');\n     * // => []\n     */\n    function takeRightWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3), false, true)\n        : [];\n    }\n\n    /**\n     * Creates a slice of `array` with elements taken from the beginning. Elements\n     * are taken until `predicate` returns falsey. The predicate is invoked with\n     * three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.takeWhile(users, function(o) { return !o.active; });\n     * // => objects for ['barney', 'fred']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.takeWhile(users, { 'user': 'barney', 'active': false });\n     * // => objects for ['barney']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.takeWhile(users, ['active', false]);\n     * // => objects for ['barney', 'fred']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.takeWhile(users, 'active');\n     * // => []\n     */\n    function takeWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3))\n        : [];\n    }\n\n    /**\n     * Creates an array of unique values, in order, from all given arrays using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * _.union([2], [1, 2]);\n     * // => [2, 1]\n     */\n    var union = baseRest(function(arrays) {\n      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));\n    });\n\n    /**\n     * This method is like `_.union` except that it accepts `iteratee` which is\n     * invoked for each element of each `arrays` to generate the criterion by\n     * which uniqueness is computed. Result values are chosen from the first\n     * array in which the value occurs. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * _.unionBy([2.1], [1.2, 2.3], Math.floor);\n     * // => [2.1, 1.2]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }, { 'x': 2 }]\n     */\n    var unionBy = baseRest(function(arrays) {\n      var iteratee = last(arrays);\n      if (isArrayLikeObject(iteratee)) {\n        iteratee = undefined;\n      }\n      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));\n    });\n\n    /**\n     * This method is like `_.union` except that it accepts `comparator` which\n     * is invoked to compare elements of `arrays`. Result values are chosen from\n     * the first array in which the value occurs. The comparator is invoked\n     * with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.unionWith(objects, others, _.isEqual);\n     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n     */\n    var unionWith = baseRest(function(arrays) {\n      var comparator = last(arrays);\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);\n    });\n\n    /**\n     * Creates a duplicate-free version of an array, using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons, in which only the first occurrence of each element\n     * is kept. The order of result values is determined by the order they occur\n     * in the array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.uniq([2, 1, 2]);\n     * // => [2, 1]\n     */\n    function uniq(array) {\n      return (array && array.length) ? baseUniq(array) : [];\n    }\n\n    /**\n     * This method is like `_.uniq` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the criterion by which\n     * uniqueness is computed. The order of result values is determined by the\n     * order they occur in the array. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);\n     * // => [2.1, 1.2]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }, { 'x': 2 }]\n     */\n    function uniqBy(array, iteratee) {\n      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];\n    }\n\n    /**\n     * This method is like `_.uniq` except that it accepts `comparator` which\n     * is invoked to compare elements of `array`. The order of result values is\n     * determined by the order they occur in the array.The comparator is invoked\n     * with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.uniqWith(objects, _.isEqual);\n     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]\n     */\n    function uniqWith(array, comparator) {\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];\n    }\n\n    /**\n     * This method is like `_.zip` except that it accepts an array of grouped\n     * elements and creates an array regrouping the elements to their pre-zip\n     * configuration.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.2.0\n     * @category Array\n     * @param {Array} array The array of grouped elements to process.\n     * @returns {Array} Returns the new array of regrouped elements.\n     * @example\n     *\n     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);\n     * // => [['a', 1, true], ['b', 2, false]]\n     *\n     * _.unzip(zipped);\n     * // => [['a', 'b'], [1, 2], [true, false]]\n     */\n    function unzip(array) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      var length = 0;\n      array = arrayFilter(array, function(group) {\n        if (isArrayLikeObject(group)) {\n          length = nativeMax(group.length, length);\n          return true;\n        }\n      });\n      return baseTimes(length, function(index) {\n        return arrayMap(array, baseProperty(index));\n      });\n    }\n\n    /**\n     * This method is like `_.unzip` except that it accepts `iteratee` to specify\n     * how regrouped values should be combined. The iteratee is invoked with the\n     * elements of each group: (...group).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.8.0\n     * @category Array\n     * @param {Array} array The array of grouped elements to process.\n     * @param {Function} [iteratee=_.identity] The function to combine\n     *  regrouped values.\n     * @returns {Array} Returns the new array of regrouped elements.\n     * @example\n     *\n     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);\n     * // => [[1, 10, 100], [2, 20, 200]]\n     *\n     * _.unzipWith(zipped, _.add);\n     * // => [3, 30, 300]\n     */\n    function unzipWith(array, iteratee) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      var result = unzip(array);\n      if (iteratee == null) {\n        return result;\n      }\n      return arrayMap(result, function(group) {\n        return apply(iteratee, undefined, group);\n      });\n    }\n\n    /**\n     * Creates an array excluding all given values using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * **Note:** Unlike `_.pull`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...*} [values] The values to exclude.\n     * @returns {Array} Returns the new array of filtered values.\n     * @see _.difference, _.xor\n     * @example\n     *\n     * _.without([2, 1, 2, 3], 1, 2);\n     * // => [3]\n     */\n    var without = baseRest(function(array, values) {\n      return isArrayLikeObject(array)\n        ? baseDifference(array, values)\n        : [];\n    });\n\n    /**\n     * Creates an array of unique values that is the\n     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)\n     * of the given arrays. The order of result values is determined by the order\n     * they occur in the arrays.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of filtered values.\n     * @see _.difference, _.without\n     * @example\n     *\n     * _.xor([2, 1], [2, 3]);\n     * // => [1, 3]\n     */\n    var xor = baseRest(function(arrays) {\n      return baseXor(arrayFilter(arrays, isArrayLikeObject));\n    });\n\n    /**\n     * This method is like `_.xor` except that it accepts `iteratee` which is\n     * invoked for each element of each `arrays` to generate the criterion by\n     * which by which they're compared. The order of result values is determined\n     * by the order they occur in the arrays. The iteratee is invoked with one\n     * argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n     * // => [1.2, 3.4]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 2 }]\n     */\n    var xorBy = baseRest(function(arrays) {\n      var iteratee = last(arrays);\n      if (isArrayLikeObject(iteratee)) {\n        iteratee = undefined;\n      }\n      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));\n    });\n\n    /**\n     * This method is like `_.xor` except that it accepts `comparator` which is\n     * invoked to compare elements of `arrays`. The order of result values is\n     * determined by the order they occur in the arrays. The comparator is invoked\n     * with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.xorWith(objects, others, _.isEqual);\n     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n     */\n    var xorWith = baseRest(function(arrays) {\n      var comparator = last(arrays);\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);\n    });\n\n    /**\n     * Creates an array of grouped elements, the first of which contains the\n     * first elements of the given arrays, the second of which contains the\n     * second elements of the given arrays, and so on.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to process.\n     * @returns {Array} Returns the new array of grouped elements.\n     * @example\n     *\n     * _.zip(['a', 'b'], [1, 2], [true, false]);\n     * // => [['a', 1, true], ['b', 2, false]]\n     */\n    var zip = baseRest(unzip);\n\n    /**\n     * This method is like `_.fromPairs` except that it accepts two arrays,\n     * one of property identifiers and one of corresponding values.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.4.0\n     * @category Array\n     * @param {Array} [props=[]] The property identifiers.\n     * @param {Array} [values=[]] The property values.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.zipObject(['a', 'b'], [1, 2]);\n     * // => { 'a': 1, 'b': 2 }\n     */\n    function zipObject(props, values) {\n      return baseZipObject(props || [], values || [], assignValue);\n    }\n\n    /**\n     * This method is like `_.zipObject` except that it supports property paths.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.1.0\n     * @category Array\n     * @param {Array} [props=[]] The property identifiers.\n     * @param {Array} [values=[]] The property values.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);\n     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }\n     */\n    function zipObjectDeep(props, values) {\n      return baseZipObject(props || [], values || [], baseSet);\n    }\n\n    /**\n     * This method is like `_.zip` except that it accepts `iteratee` to specify\n     * how grouped values should be combined. The iteratee is invoked with the\n     * elements of each group: (...group).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.8.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to process.\n     * @param {Function} [iteratee=_.identity] The function to combine\n     *  grouped values.\n     * @returns {Array} Returns the new array of grouped elements.\n     * @example\n     *\n     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {\n     *   return a + b + c;\n     * });\n     * // => [111, 222]\n     */\n    var zipWith = baseRest(function(arrays) {\n      var length = arrays.length,\n          iteratee = length > 1 ? arrays[length - 1] : undefined;\n\n      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;\n      return unzipWith(arrays, iteratee);\n    });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a `lodash` wrapper instance that wraps `value` with explicit method\n     * chain sequences enabled. The result of such sequences must be unwrapped\n     * with `_#value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.3.0\n     * @category Seq\n     * @param {*} value The value to wrap.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36 },\n     *   { 'user': 'fred',    'age': 40 },\n     *   { 'user': 'pebbles', 'age': 1 }\n     * ];\n     *\n     * var youngest = _\n     *   .chain(users)\n     *   .sortBy('age')\n     *   .map(function(o) {\n     *     return o.user + ' is ' + o.age;\n     *   })\n     *   .head()\n     *   .value();\n     * // => 'pebbles is 1'\n     */\n    function chain(value) {\n      var result = lodash(value);\n      result.__chain__ = true;\n      return result;\n    }\n\n    /**\n     * This method invokes `interceptor` and returns `value`. The interceptor\n     * is invoked with one argument; (value). The purpose of this method is to\n     * \"tap into\" a method chain sequence in order to modify intermediate results.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Seq\n     * @param {*} value The value to provide to `interceptor`.\n     * @param {Function} interceptor The function to invoke.\n     * @returns {*} Returns `value`.\n     * @example\n     *\n     * _([1, 2, 3])\n     *  .tap(function(array) {\n     *    // Mutate input array.\n     *    array.pop();\n     *  })\n     *  .reverse()\n     *  .value();\n     * // => [2, 1]\n     */\n    function tap(value, interceptor) {\n      interceptor(value);\n      return value;\n    }\n\n    /**\n     * This method is like `_.tap` except that it returns the result of `interceptor`.\n     * The purpose of this method is to \"pass thru\" values replacing intermediate\n     * results in a method chain sequence.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Seq\n     * @param {*} value The value to provide to `interceptor`.\n     * @param {Function} interceptor The function to invoke.\n     * @returns {*} Returns the result of `interceptor`.\n     * @example\n     *\n     * _('  abc  ')\n     *  .chain()\n     *  .trim()\n     *  .thru(function(value) {\n     *    return [value];\n     *  })\n     *  .value();\n     * // => ['abc']\n     */\n    function thru(value, interceptor) {\n      return interceptor(value);\n    }\n\n    /**\n     * This method is the wrapper version of `_.at`.\n     *\n     * @name at\n     * @memberOf _\n     * @since 1.0.0\n     * @category Seq\n     * @param {...(string|string[])} [paths] The property paths to pick.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n     *\n     * _(object).at(['a[0].b.c', 'a[1]']).value();\n     * // => [3, 4]\n     */\n    var wrapperAt = flatRest(function(paths) {\n      var length = paths.length,\n          start = length ? paths[0] : 0,\n          value = this.__wrapped__,\n          interceptor = function(object) { return baseAt(object, paths); };\n\n      if (length > 1 || this.__actions__.length ||\n          !(value instanceof LazyWrapper) || !isIndex(start)) {\n        return this.thru(interceptor);\n      }\n      value = value.slice(start, +start + (length ? 1 : 0));\n      value.__actions__.push({\n        'func': thru,\n        'args': [interceptor],\n        'thisArg': undefined\n      });\n      return new LodashWrapper(value, this.__chain__).thru(function(array) {\n        if (length && !array.length) {\n          array.push(undefined);\n        }\n        return array;\n      });\n    });\n\n    /**\n     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.\n     *\n     * @name chain\n     * @memberOf _\n     * @since 0.1.0\n     * @category Seq\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 }\n     * ];\n     *\n     * // A sequence without explicit chaining.\n     * _(users).head();\n     * // => { 'user': 'barney', 'age': 36 }\n     *\n     * // A sequence with explicit chaining.\n     * _(users)\n     *   .chain()\n     *   .head()\n     *   .pick('user')\n     *   .value();\n     * // => { 'user': 'barney' }\n     */\n    function wrapperChain() {\n      return chain(this);\n    }\n\n    /**\n     * Executes the chain sequence and returns the wrapped result.\n     *\n     * @name commit\n     * @memberOf _\n     * @since 3.2.0\n     * @category Seq\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var array = [1, 2];\n     * var wrapped = _(array).push(3);\n     *\n     * console.log(array);\n     * // => [1, 2]\n     *\n     * wrapped = wrapped.commit();\n     * console.log(array);\n     * // => [1, 2, 3]\n     *\n     * wrapped.last();\n     * // => 3\n     *\n     * console.log(array);\n     * // => [1, 2, 3]\n     */\n    function wrapperCommit() {\n      return new LodashWrapper(this.value(), this.__chain__);\n    }\n\n    /**\n     * Gets the next value on a wrapped object following the\n     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).\n     *\n     * @name next\n     * @memberOf _\n     * @since 4.0.0\n     * @category Seq\n     * @returns {Object} Returns the next iterator value.\n     * @example\n     *\n     * var wrapped = _([1, 2]);\n     *\n     * wrapped.next();\n     * // => { 'done': false, 'value': 1 }\n     *\n     * wrapped.next();\n     * // => { 'done': false, 'value': 2 }\n     *\n     * wrapped.next();\n     * // => { 'done': true, 'value': undefined }\n     */\n    function wrapperNext() {\n      if (this.__values__ === undefined) {\n        this.__values__ = toArray(this.value());\n      }\n      var done = this.__index__ >= this.__values__.length,\n          value = done ? undefined : this.__values__[this.__index__++];\n\n      return { 'done': done, 'value': value };\n    }\n\n    /**\n     * Enables the wrapper to be iterable.\n     *\n     * @name Symbol.iterator\n     * @memberOf _\n     * @since 4.0.0\n     * @category Seq\n     * @returns {Object} Returns the wrapper object.\n     * @example\n     *\n     * var wrapped = _([1, 2]);\n     *\n     * wrapped[Symbol.iterator]() === wrapped;\n     * // => true\n     *\n     * Array.from(wrapped);\n     * // => [1, 2]\n     */\n    function wrapperToIterator() {\n      return this;\n    }\n\n    /**\n     * Creates a clone of the chain sequence planting `value` as the wrapped value.\n     *\n     * @name plant\n     * @memberOf _\n     * @since 3.2.0\n     * @category Seq\n     * @param {*} value The value to plant.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var wrapped = _([1, 2]).map(square);\n     * var other = wrapped.plant([3, 4]);\n     *\n     * other.value();\n     * // => [9, 16]\n     *\n     * wrapped.value();\n     * // => [1, 4]\n     */\n    function wrapperPlant(value) {\n      var result,\n          parent = this;\n\n      while (parent instanceof baseLodash) {\n        var clone = wrapperClone(parent);\n        clone.__index__ = 0;\n        clone.__values__ = undefined;\n        if (result) {\n          previous.__wrapped__ = clone;\n        } else {\n          result = clone;\n        }\n        var previous = clone;\n        parent = parent.__wrapped__;\n      }\n      previous.__wrapped__ = value;\n      return result;\n    }\n\n    /**\n     * This method is the wrapper version of `_.reverse`.\n     *\n     * **Note:** This method mutates the wrapped array.\n     *\n     * @name reverse\n     * @memberOf _\n     * @since 0.1.0\n     * @category Seq\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _(array).reverse().value()\n     * // => [3, 2, 1]\n     *\n     * console.log(array);\n     * // => [3, 2, 1]\n     */\n    function wrapperReverse() {\n      var value = this.__wrapped__;\n      if (value instanceof LazyWrapper) {\n        var wrapped = value;\n        if (this.__actions__.length) {\n          wrapped = new LazyWrapper(this);\n        }\n        wrapped = wrapped.reverse();\n        wrapped.__actions__.push({\n          'func': thru,\n          'args': [reverse],\n          'thisArg': undefined\n        });\n        return new LodashWrapper(wrapped, this.__chain__);\n      }\n      return this.thru(reverse);\n    }\n\n    /**\n     * Executes the chain sequence to resolve the unwrapped value.\n     *\n     * @name value\n     * @memberOf _\n     * @since 0.1.0\n     * @alias toJSON, valueOf\n     * @category Seq\n     * @returns {*} Returns the resolved unwrapped value.\n     * @example\n     *\n     * _([1, 2, 3]).value();\n     * // => [1, 2, 3]\n     */\n    function wrapperValue() {\n      return baseWrapperValue(this.__wrapped__, this.__actions__);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` thru `iteratee`. The corresponding value of\n     * each key is the number of times the key was returned by `iteratee`. The\n     * iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.5.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * _.countBy([6.1, 4.2, 6.3], Math.floor);\n     * // => { '4': 1, '6': 2 }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.countBy(['one', 'two', 'three'], 'length');\n     * // => { '3': 2, '5': 1 }\n     */\n    var countBy = createAggregator(function(result, value, key) {\n      if (hasOwnProperty.call(result, key)) {\n        ++result[key];\n      } else {\n        baseAssignValue(result, key, 1);\n      }\n    });\n\n    /**\n     * Checks if `predicate` returns truthy for **all** elements of `collection`.\n     * Iteration is stopped once `predicate` returns falsey. The predicate is\n     * invoked with three arguments: (value, index|key, collection).\n     *\n     * **Note:** This method returns `true` for\n     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because\n     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of\n     * elements of empty collections.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {boolean} Returns `true` if all elements pass the predicate check,\n     *  else `false`.\n     * @example\n     *\n     * _.every([true, 1, null, 'yes'], Boolean);\n     * // => false\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': false },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.every(users, { 'user': 'barney', 'active': false });\n     * // => false\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.every(users, ['active', false]);\n     * // => true\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.every(users, 'active');\n     * // => false\n     */\n    function every(collection, predicate, guard) {\n      var func = isArray(collection) ? arrayEvery : baseEvery;\n      if (guard && isIterateeCall(collection, predicate, guard)) {\n        predicate = undefined;\n      }\n      return func(collection, getIteratee(predicate, 3));\n    }\n\n    /**\n     * Iterates over elements of `collection`, returning an array of all elements\n     * `predicate` returns truthy for. The predicate is invoked with three\n     * arguments: (value, index|key, collection).\n     *\n     * **Note:** Unlike `_.remove`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     * @see _.reject\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': true },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * _.filter(users, function(o) { return !o.active; });\n     * // => objects for ['fred']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.filter(users, { 'age': 36, 'active': true });\n     * // => objects for ['barney']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.filter(users, ['active', false]);\n     * // => objects for ['fred']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.filter(users, 'active');\n     * // => objects for ['barney']\n     */\n    function filter(collection, predicate) {\n      var func = isArray(collection) ? arrayFilter : baseFilter;\n      return func(collection, getIteratee(predicate, 3));\n    }\n\n    /**\n     * Iterates over elements of `collection`, returning the first element\n     * `predicate` returns truthy for. The predicate is invoked with three\n     * arguments: (value, index|key, collection).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @returns {*} Returns the matched element, else `undefined`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36, 'active': true },\n     *   { 'user': 'fred',    'age': 40, 'active': false },\n     *   { 'user': 'pebbles', 'age': 1,  'active': true }\n     * ];\n     *\n     * _.find(users, function(o) { return o.age < 40; });\n     * // => object for 'barney'\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.find(users, { 'age': 1, 'active': true });\n     * // => object for 'pebbles'\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.find(users, ['active', false]);\n     * // => object for 'fred'\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.find(users, 'active');\n     * // => object for 'barney'\n     */\n    var find = createFind(findIndex);\n\n    /**\n     * This method is like `_.find` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=collection.length-1] The index to search from.\n     * @returns {*} Returns the matched element, else `undefined`.\n     * @example\n     *\n     * _.findLast([1, 2, 3, 4], function(n) {\n     *   return n % 2 == 1;\n     * });\n     * // => 3\n     */\n    var findLast = createFind(findLastIndex);\n\n    /**\n     * Creates a flattened array of values by running each element in `collection`\n     * thru `iteratee` and flattening the mapped results. The iteratee is invoked\n     * with three arguments: (value, index|key, collection).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * function duplicate(n) {\n     *   return [n, n];\n     * }\n     *\n     * _.flatMap([1, 2], duplicate);\n     * // => [1, 1, 2, 2]\n     */\n    function flatMap(collection, iteratee) {\n      return baseFlatten(map(collection, iteratee), 1);\n    }\n\n    /**\n     * This method is like `_.flatMap` except that it recursively flattens the\n     * mapped results.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * function duplicate(n) {\n     *   return [[[n, n]]];\n     * }\n     *\n     * _.flatMapDeep([1, 2], duplicate);\n     * // => [1, 1, 2, 2]\n     */\n    function flatMapDeep(collection, iteratee) {\n      return baseFlatten(map(collection, iteratee), INFINITY);\n    }\n\n    /**\n     * This method is like `_.flatMap` except that it recursively flattens the\n     * mapped results up to `depth` times.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {number} [depth=1] The maximum recursion depth.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * function duplicate(n) {\n     *   return [[[n, n]]];\n     * }\n     *\n     * _.flatMapDepth([1, 2], duplicate, 2);\n     * // => [[1, 1], [2, 2]]\n     */\n    function flatMapDepth(collection, iteratee, depth) {\n      depth = depth === undefined ? 1 : toInteger(depth);\n      return baseFlatten(map(collection, iteratee), depth);\n    }\n\n    /**\n     * Iterates over elements of `collection` and invokes `iteratee` for each element.\n     * The iteratee is invoked with three arguments: (value, index|key, collection).\n     * Iteratee functions may exit iteration early by explicitly returning `false`.\n     *\n     * **Note:** As with other \"Collections\" methods, objects with a \"length\"\n     * property are iterated like arrays. To avoid this behavior use `_.forIn`\n     * or `_.forOwn` for object iteration.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @alias each\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     * @see _.forEachRight\n     * @example\n     *\n     * _.forEach([1, 2], function(value) {\n     *   console.log(value);\n     * });\n     * // => Logs `1` then `2`.\n     *\n     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n     */\n    function forEach(collection, iteratee) {\n      var func = isArray(collection) ? arrayEach : baseEach;\n      return func(collection, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * This method is like `_.forEach` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @alias eachRight\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     * @see _.forEach\n     * @example\n     *\n     * _.forEachRight([1, 2], function(value) {\n     *   console.log(value);\n     * });\n     * // => Logs `2` then `1`.\n     */\n    function forEachRight(collection, iteratee) {\n      var func = isArray(collection) ? arrayEachRight : baseEachRight;\n      return func(collection, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` thru `iteratee`. The order of grouped values\n     * is determined by the order they occur in `collection`. The corresponding\n     * value of each key is an array of elements responsible for generating the\n     * key. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * _.groupBy([6.1, 4.2, 6.3], Math.floor);\n     * // => { '4': [4.2], '6': [6.1, 6.3] }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.groupBy(['one', 'two', 'three'], 'length');\n     * // => { '3': ['one', 'two'], '5': ['three'] }\n     */\n    var groupBy = createAggregator(function(result, value, key) {\n      if (hasOwnProperty.call(result, key)) {\n        result[key].push(value);\n      } else {\n        baseAssignValue(result, key, [value]);\n      }\n    });\n\n    /**\n     * Checks if `value` is in `collection`. If `collection` is a string, it's\n     * checked for a substring of `value`, otherwise\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * is used for equality comparisons. If `fromIndex` is negative, it's used as\n     * the offset from the end of `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to inspect.\n     * @param {*} value The value to search for.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n     * @returns {boolean} Returns `true` if `value` is found, else `false`.\n     * @example\n     *\n     * _.includes([1, 2, 3], 1);\n     * // => true\n     *\n     * _.includes([1, 2, 3], 1, 2);\n     * // => false\n     *\n     * _.includes({ 'a': 1, 'b': 2 }, 1);\n     * // => true\n     *\n     * _.includes('abcd', 'bc');\n     * // => true\n     */\n    function includes(collection, value, fromIndex, guard) {\n      collection = isArrayLike(collection) ? collection : values(collection);\n      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;\n\n      var length = collection.length;\n      if (fromIndex < 0) {\n        fromIndex = nativeMax(length + fromIndex, 0);\n      }\n      return isString(collection)\n        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)\n        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);\n    }\n\n    /**\n     * Invokes the method at `path` of each element in `collection`, returning\n     * an array of the results of each invoked method. Any additional arguments\n     * are provided to each invoked method. If `path` is a function, it's invoked\n     * for, and `this` bound to, each element in `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Array|Function|string} path The path of the method to invoke or\n     *  the function invoked per iteration.\n     * @param {...*} [args] The arguments to invoke each method with.\n     * @returns {Array} Returns the array of results.\n     * @example\n     *\n     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');\n     * // => [[1, 5, 7], [1, 2, 3]]\n     *\n     * _.invokeMap([123, 456], String.prototype.split, '');\n     * // => [['1', '2', '3'], ['4', '5', '6']]\n     */\n    var invokeMap = baseRest(function(collection, path, args) {\n      var index = -1,\n          isFunc = typeof path == 'function',\n          result = isArrayLike(collection) ? Array(collection.length) : [];\n\n      baseEach(collection, function(value) {\n        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);\n      });\n      return result;\n    });\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` thru `iteratee`. The corresponding value of\n     * each key is the last element responsible for generating the key. The\n     * iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * var array = [\n     *   { 'dir': 'left', 'code': 97 },\n     *   { 'dir': 'right', 'code': 100 }\n     * ];\n     *\n     * _.keyBy(array, function(o) {\n     *   return String.fromCharCode(o.code);\n     * });\n     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }\n     *\n     * _.keyBy(array, 'dir');\n     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }\n     */\n    var keyBy = createAggregator(function(result, value, key) {\n      baseAssignValue(result, key, value);\n    });\n\n    /**\n     * Creates an array of values by running each element in `collection` thru\n     * `iteratee`. The iteratee is invoked with three arguments:\n     * (value, index|key, collection).\n     *\n     * Many lodash methods are guarded to work as iteratees for methods like\n     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\n     *\n     * The guarded methods are:\n     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,\n     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,\n     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,\n     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new mapped array.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * _.map([4, 8], square);\n     * // => [16, 64]\n     *\n     * _.map({ 'a': 4, 'b': 8 }, square);\n     * // => [16, 64] (iteration order is not guaranteed)\n     *\n     * var users = [\n     *   { 'user': 'barney' },\n     *   { 'user': 'fred' }\n     * ];\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.map(users, 'user');\n     * // => ['barney', 'fred']\n     */\n    function map(collection, iteratee) {\n      var func = isArray(collection) ? arrayMap : baseMap;\n      return func(collection, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * This method is like `_.sortBy` except that it allows specifying the sort\n     * orders of the iteratees to sort by. If `orders` is unspecified, all values\n     * are sorted in ascending order. Otherwise, specify an order of \"desc\" for\n     * descending or \"asc\" for ascending sort order of corresponding values.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]\n     *  The iteratees to sort by.\n     * @param {string[]} [orders] The sort orders of `iteratees`.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n     * @returns {Array} Returns the new sorted array.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'fred',   'age': 48 },\n     *   { 'user': 'barney', 'age': 34 },\n     *   { 'user': 'fred',   'age': 40 },\n     *   { 'user': 'barney', 'age': 36 }\n     * ];\n     *\n     * // Sort by `user` in ascending order and by `age` in descending order.\n     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);\n     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n     */\n    function orderBy(collection, iteratees, orders, guard) {\n      if (collection == null) {\n        return [];\n      }\n      if (!isArray(iteratees)) {\n        iteratees = iteratees == null ? [] : [iteratees];\n      }\n      orders = guard ? undefined : orders;\n      if (!isArray(orders)) {\n        orders = orders == null ? [] : [orders];\n      }\n      return baseOrderBy(collection, iteratees, orders);\n    }\n\n    /**\n     * Creates an array of elements split into two groups, the first of which\n     * contains elements `predicate` returns truthy for, the second of which\n     * contains elements `predicate` returns falsey for. The predicate is\n     * invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the array of grouped elements.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36, 'active': false },\n     *   { 'user': 'fred',    'age': 40, 'active': true },\n     *   { 'user': 'pebbles', 'age': 1,  'active': false }\n     * ];\n     *\n     * _.partition(users, function(o) { return o.active; });\n     * // => objects for [['fred'], ['barney', 'pebbles']]\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.partition(users, { 'age': 1, 'active': false });\n     * // => objects for [['pebbles'], ['barney', 'fred']]\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.partition(users, ['active', false]);\n     * // => objects for [['barney', 'pebbles'], ['fred']]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.partition(users, 'active');\n     * // => objects for [['fred'], ['barney', 'pebbles']]\n     */\n    var partition = createAggregator(function(result, value, key) {\n      result[key ? 0 : 1].push(value);\n    }, function() { return [[], []]; });\n\n    /**\n     * Reduces `collection` to a value which is the accumulated result of running\n     * each element in `collection` thru `iteratee`, where each successive\n     * invocation is supplied the return value of the previous. If `accumulator`\n     * is not given, the first element of `collection` is used as the initial\n     * value. The iteratee is invoked with four arguments:\n     * (accumulator, value, index|key, collection).\n     *\n     * Many lodash methods are guarded to work as iteratees for methods like\n     * `_.reduce`, `_.reduceRight`, and `_.transform`.\n     *\n     * The guarded methods are:\n     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,\n     * and `sortBy`\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @returns {*} Returns the accumulated value.\n     * @see _.reduceRight\n     * @example\n     *\n     * _.reduce([1, 2], function(sum, n) {\n     *   return sum + n;\n     * }, 0);\n     * // => 3\n     *\n     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n     *   (result[value] || (result[value] = [])).push(key);\n     *   return result;\n     * }, {});\n     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)\n     */\n    function reduce(collection, iteratee, accumulator) {\n      var func = isArray(collection) ? arrayReduce : baseReduce,\n          initAccum = arguments.length < 3;\n\n      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);\n    }\n\n    /**\n     * This method is like `_.reduce` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @returns {*} Returns the accumulated value.\n     * @see _.reduce\n     * @example\n     *\n     * var array = [[0, 1], [2, 3], [4, 5]];\n     *\n     * _.reduceRight(array, function(flattened, other) {\n     *   return flattened.concat(other);\n     * }, []);\n     * // => [4, 5, 2, 3, 0, 1]\n     */\n    function reduceRight(collection, iteratee, accumulator) {\n      var func = isArray(collection) ? arrayReduceRight : baseReduce,\n          initAccum = arguments.length < 3;\n\n      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);\n    }\n\n    /**\n     * The opposite of `_.filter`; this method returns the elements of `collection`\n     * that `predicate` does **not** return truthy for.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     * @see _.filter\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': false },\n     *   { 'user': 'fred',   'age': 40, 'active': true }\n     * ];\n     *\n     * _.reject(users, function(o) { return !o.active; });\n     * // => objects for ['fred']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.reject(users, { 'age': 40, 'active': true });\n     * // => objects for ['barney']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.reject(users, ['active', false]);\n     * // => objects for ['fred']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.reject(users, 'active');\n     * // => objects for ['barney']\n     */\n    function reject(collection, predicate) {\n      var func = isArray(collection) ? arrayFilter : baseFilter;\n      return func(collection, negate(getIteratee(predicate, 3)));\n    }\n\n    /**\n     * Gets a random element from `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to sample.\n     * @returns {*} Returns the random element.\n     * @example\n     *\n     * _.sample([1, 2, 3, 4]);\n     * // => 2\n     */\n    function sample(collection) {\n      var func = isArray(collection) ? arraySample : baseSample;\n      return func(collection);\n    }\n\n    /**\n     * Gets `n` random elements at unique keys from `collection` up to the\n     * size of `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to sample.\n     * @param {number} [n=1] The number of elements to sample.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the random elements.\n     * @example\n     *\n     * _.sampleSize([1, 2, 3], 2);\n     * // => [3, 1]\n     *\n     * _.sampleSize([1, 2, 3], 4);\n     * // => [2, 3, 1]\n     */\n    function sampleSize(collection, n, guard) {\n      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {\n        n = 1;\n      } else {\n        n = toInteger(n);\n      }\n      var func = isArray(collection) ? arraySampleSize : baseSampleSize;\n      return func(collection, n);\n    }\n\n    /**\n     * Creates an array of shuffled values, using a version of the\n     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     * @example\n     *\n     * _.shuffle([1, 2, 3, 4]);\n     * // => [4, 1, 3, 2]\n     */\n    function shuffle(collection) {\n      var func = isArray(collection) ? arrayShuffle : baseShuffle;\n      return func(collection);\n    }\n\n    /**\n     * Gets the size of `collection` by returning its length for array-like\n     * values or the number of own enumerable string keyed properties for objects.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to inspect.\n     * @returns {number} Returns the collection size.\n     * @example\n     *\n     * _.size([1, 2, 3]);\n     * // => 3\n     *\n     * _.size({ 'a': 1, 'b': 2 });\n     * // => 2\n     *\n     * _.size('pebbles');\n     * // => 7\n     */\n    function size(collection) {\n      if (collection == null) {\n        return 0;\n      }\n      if (isArrayLike(collection)) {\n        return isString(collection) ? stringSize(collection) : collection.length;\n      }\n      var tag = getTag(collection);\n      if (tag == mapTag || tag == setTag) {\n        return collection.size;\n      }\n      return baseKeys(collection).length;\n    }\n\n    /**\n     * Checks if `predicate` returns truthy for **any** element of `collection`.\n     * Iteration is stopped once `predicate` returns truthy. The predicate is\n     * invoked with three arguments: (value, index|key, collection).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {boolean} Returns `true` if any element passes the predicate check,\n     *  else `false`.\n     * @example\n     *\n     * _.some([null, 0, 'yes', false], Boolean);\n     * // => true\n     *\n     * var users = [\n     *   { 'user': 'barney', 'active': true },\n     *   { 'user': 'fred',   'active': false }\n     * ];\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.some(users, { 'user': 'barney', 'active': false });\n     * // => false\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.some(users, ['active', false]);\n     * // => true\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.some(users, 'active');\n     * // => true\n     */\n    function some(collection, predicate, guard) {\n      var func = isArray(collection) ? arraySome : baseSome;\n      if (guard && isIterateeCall(collection, predicate, guard)) {\n        predicate = undefined;\n      }\n      return func(collection, getIteratee(predicate, 3));\n    }\n\n    /**\n     * Creates an array of elements, sorted in ascending order by the results of\n     * running each element in a collection thru each iteratee. This method\n     * performs a stable sort, that is, it preserves the original sort order of\n     * equal elements. The iteratees are invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {...(Function|Function[])} [iteratees=[_.identity]]\n     *  The iteratees to sort by.\n     * @returns {Array} Returns the new sorted array.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'fred',   'age': 48 },\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 },\n     *   { 'user': 'barney', 'age': 34 }\n     * ];\n     *\n     * _.sortBy(users, [function(o) { return o.user; }]);\n     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n     *\n     * _.sortBy(users, ['user', 'age']);\n     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]\n     */\n    var sortBy = baseRest(function(collection, iteratees) {\n      if (collection == null) {\n        return [];\n      }\n      var length = iteratees.length;\n      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {\n        iteratees = [];\n      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {\n        iteratees = [iteratees[0]];\n      }\n      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);\n    });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Gets the timestamp of the number of milliseconds that have elapsed since\n     * the Unix epoch (1 January 1970 00:00:00 UTC).\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Date\n     * @returns {number} Returns the timestamp.\n     * @example\n     *\n     * _.defer(function(stamp) {\n     *   console.log(_.now() - stamp);\n     * }, _.now());\n     * // => Logs the number of milliseconds it took for the deferred invocation.\n     */\n    var now = ctxNow || function() {\n      return root.Date.now();\n    };\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * The opposite of `_.before`; this method creates a function that invokes\n     * `func` once it's called `n` or more times.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {number} n The number of calls before `func` is invoked.\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * var saves = ['profile', 'settings'];\n     *\n     * var done = _.after(saves.length, function() {\n     *   console.log('done saving!');\n     * });\n     *\n     * _.forEach(saves, function(type) {\n     *   asyncSave({ 'type': type, 'complete': done });\n     * });\n     * // => Logs 'done saving!' after the two async saves have completed.\n     */\n    function after(n, func) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      n = toInteger(n);\n      return function() {\n        if (--n < 1) {\n          return func.apply(this, arguments);\n        }\n      };\n    }\n\n    /**\n     * Creates a function that invokes `func`, with up to `n` arguments,\n     * ignoring any additional arguments.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} func The function to cap arguments for.\n     * @param {number} [n=func.length] The arity cap.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the new capped function.\n     * @example\n     *\n     * _.map(['6', '8', '10'], _.ary(parseInt, 1));\n     * // => [6, 8, 10]\n     */\n    function ary(func, n, guard) {\n      n = guard ? undefined : n;\n      n = (func && n == null) ? func.length : n;\n      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);\n    }\n\n    /**\n     * Creates a function that invokes `func`, with the `this` binding and arguments\n     * of the created function, while it's called less than `n` times. Subsequent\n     * calls to the created function return the result of the last `func` invocation.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {number} n The number of calls at which `func` is no longer invoked.\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * jQuery(element).on('click', _.before(5, addContactToList));\n     * // => Allows adding up to 4 contacts to the list.\n     */\n    function before(n, func) {\n      var result;\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      n = toInteger(n);\n      return function() {\n        if (--n > 0) {\n          result = func.apply(this, arguments);\n        }\n        if (n <= 1) {\n          func = undefined;\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of `thisArg`\n     * and `partials` prepended to the arguments it receives.\n     *\n     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,\n     * may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** Unlike native `Function#bind`, this method doesn't set the \"length\"\n     * property of bound functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to bind.\n     * @param {*} thisArg The `this` binding of `func`.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new bound function.\n     * @example\n     *\n     * function greet(greeting, punctuation) {\n     *   return greeting + ' ' + this.user + punctuation;\n     * }\n     *\n     * var object = { 'user': 'fred' };\n     *\n     * var bound = _.bind(greet, object, 'hi');\n     * bound('!');\n     * // => 'hi fred!'\n     *\n     * // Bound with placeholders.\n     * var bound = _.bind(greet, object, _, '!');\n     * bound('hi');\n     * // => 'hi fred!'\n     */\n    var bind = baseRest(function(func, thisArg, partials) {\n      var bitmask = WRAP_BIND_FLAG;\n      if (partials.length) {\n        var holders = replaceHolders(partials, getHolder(bind));\n        bitmask |= WRAP_PARTIAL_FLAG;\n      }\n      return createWrap(func, bitmask, thisArg, partials, holders);\n    });\n\n    /**\n     * Creates a function that invokes the method at `object[key]` with `partials`\n     * prepended to the arguments it receives.\n     *\n     * This method differs from `_.bind` by allowing bound functions to reference\n     * methods that may be redefined or don't yet exist. See\n     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)\n     * for more details.\n     *\n     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.10.0\n     * @category Function\n     * @param {Object} object The object to invoke the method on.\n     * @param {string} key The key of the method.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new bound function.\n     * @example\n     *\n     * var object = {\n     *   'user': 'fred',\n     *   'greet': function(greeting, punctuation) {\n     *     return greeting + ' ' + this.user + punctuation;\n     *   }\n     * };\n     *\n     * var bound = _.bindKey(object, 'greet', 'hi');\n     * bound('!');\n     * // => 'hi fred!'\n     *\n     * object.greet = function(greeting, punctuation) {\n     *   return greeting + 'ya ' + this.user + punctuation;\n     * };\n     *\n     * bound('!');\n     * // => 'hiya fred!'\n     *\n     * // Bound with placeholders.\n     * var bound = _.bindKey(object, 'greet', _, '!');\n     * bound('hi');\n     * // => 'hiya fred!'\n     */\n    var bindKey = baseRest(function(object, key, partials) {\n      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;\n      if (partials.length) {\n        var holders = replaceHolders(partials, getHolder(bindKey));\n        bitmask |= WRAP_PARTIAL_FLAG;\n      }\n      return createWrap(key, bitmask, object, partials, holders);\n    });\n\n    /**\n     * Creates a function that accepts arguments of `func` and either invokes\n     * `func` returning its result, if at least `arity` number of arguments have\n     * been provided, or returns a function that accepts the remaining `func`\n     * arguments, and so on. The arity of `func` may be specified if `func.length`\n     * is not sufficient.\n     *\n     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,\n     * may be used as a placeholder for provided arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of curried functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Function\n     * @param {Function} func The function to curry.\n     * @param {number} [arity=func.length] The arity of `func`.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the new curried function.\n     * @example\n     *\n     * var abc = function(a, b, c) {\n     *   return [a, b, c];\n     * };\n     *\n     * var curried = _.curry(abc);\n     *\n     * curried(1)(2)(3);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2)(3);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2, 3);\n     * // => [1, 2, 3]\n     *\n     * // Curried with placeholders.\n     * curried(1)(_, 3)(2);\n     * // => [1, 2, 3]\n     */\n    function curry(func, arity, guard) {\n      arity = guard ? undefined : arity;\n      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n      result.placeholder = curry.placeholder;\n      return result;\n    }\n\n    /**\n     * This method is like `_.curry` except that arguments are applied to `func`\n     * in the manner of `_.partialRight` instead of `_.partial`.\n     *\n     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for provided arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of curried functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} func The function to curry.\n     * @param {number} [arity=func.length] The arity of `func`.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the new curried function.\n     * @example\n     *\n     * var abc = function(a, b, c) {\n     *   return [a, b, c];\n     * };\n     *\n     * var curried = _.curryRight(abc);\n     *\n     * curried(3)(2)(1);\n     * // => [1, 2, 3]\n     *\n     * curried(2, 3)(1);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2, 3);\n     * // => [1, 2, 3]\n     *\n     * // Curried with placeholders.\n     * curried(3)(1, _)(2);\n     * // => [1, 2, 3]\n     */\n    function curryRight(func, arity, guard) {\n      arity = guard ? undefined : arity;\n      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n      result.placeholder = curryRight.placeholder;\n      return result;\n    }\n\n    /**\n     * Creates a debounced function that delays invoking `func` until after `wait`\n     * milliseconds have elapsed since the last time the debounced function was\n     * invoked. The debounced function comes with a `cancel` method to cancel\n     * delayed `func` invocations and a `flush` method to immediately invoke them.\n     * Provide `options` to indicate whether `func` should be invoked on the\n     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n     * with the last arguments provided to the debounced function. Subsequent\n     * calls to the debounced function return the result of the last `func`\n     * invocation.\n     *\n     * **Note:** If `leading` and `trailing` options are `true`, `func` is\n     * invoked on the trailing edge of the timeout only if the debounced function\n     * is invoked more than once during the `wait` timeout.\n     *\n     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n     * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n     *\n     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n     * for details over the differences between `_.debounce` and `_.throttle`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to debounce.\n     * @param {number} [wait=0] The number of milliseconds to delay.\n     * @param {Object} [options={}] The options object.\n     * @param {boolean} [options.leading=false]\n     *  Specify invoking on the leading edge of the timeout.\n     * @param {number} [options.maxWait]\n     *  The maximum time `func` is allowed to be delayed before it's invoked.\n     * @param {boolean} [options.trailing=true]\n     *  Specify invoking on the trailing edge of the timeout.\n     * @returns {Function} Returns the new debounced function.\n     * @example\n     *\n     * // Avoid costly calculations while the window size is in flux.\n     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n     *\n     * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n     * jQuery(element).on('click', _.debounce(sendMail, 300, {\n     *   'leading': true,\n     *   'trailing': false\n     * }));\n     *\n     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n     * var source = new EventSource('/stream');\n     * jQuery(source).on('message', debounced);\n     *\n     * // Cancel the trailing debounced invocation.\n     * jQuery(window).on('popstate', debounced.cancel);\n     */\n    function debounce(func, wait, options) {\n      var lastArgs,\n          lastThis,\n          maxWait,\n          result,\n          timerId,\n          lastCallTime,\n          lastInvokeTime = 0,\n          leading = false,\n          maxing = false,\n          trailing = true;\n\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      wait = toNumber(wait) || 0;\n      if (isObject(options)) {\n        leading = !!options.leading;\n        maxing = 'maxWait' in options;\n        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n        trailing = 'trailing' in options ? !!options.trailing : trailing;\n      }\n\n      function invokeFunc(time) {\n        var args = lastArgs,\n            thisArg = lastThis;\n\n        lastArgs = lastThis = undefined;\n        lastInvokeTime = time;\n        result = func.apply(thisArg, args);\n        return result;\n      }\n\n      function leadingEdge(time) {\n        // Reset any `maxWait` timer.\n        lastInvokeTime = time;\n        // Start the timer for the trailing edge.\n        timerId = setTimeout(timerExpired, wait);\n        // Invoke the leading edge.\n        return leading ? invokeFunc(time) : result;\n      }\n\n      function remainingWait(time) {\n        var timeSinceLastCall = time - lastCallTime,\n            timeSinceLastInvoke = time - lastInvokeTime,\n            result = wait - timeSinceLastCall;\n\n        return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n      }\n\n      function shouldInvoke(time) {\n        var timeSinceLastCall = time - lastCallTime,\n            timeSinceLastInvoke = time - lastInvokeTime;\n\n        // Either this is the first call, activity has stopped and we're at the\n        // trailing edge, the system time has gone backwards and we're treating\n        // it as the trailing edge, or we've hit the `maxWait` limit.\n        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n      }\n\n      function timerExpired() {\n        var time = now();\n        if (shouldInvoke(time)) {\n          return trailingEdge(time);\n        }\n        // Restart the timer.\n        timerId = setTimeout(timerExpired, remainingWait(time));\n      }\n\n      function trailingEdge(time) {\n        timerId = undefined;\n\n        // Only invoke if we have `lastArgs` which means `func` has been\n        // debounced at least once.\n        if (trailing && lastArgs) {\n          return invokeFunc(time);\n        }\n        lastArgs = lastThis = undefined;\n        return result;\n      }\n\n      function cancel() {\n        if (timerId !== undefined) {\n          clearTimeout(timerId);\n        }\n        lastInvokeTime = 0;\n        lastArgs = lastCallTime = lastThis = timerId = undefined;\n      }\n\n      function flush() {\n        return timerId === undefined ? result : trailingEdge(now());\n      }\n\n      function debounced() {\n        var time = now(),\n            isInvoking = shouldInvoke(time);\n\n        lastArgs = arguments;\n        lastThis = this;\n        lastCallTime = time;\n\n        if (isInvoking) {\n          if (timerId === undefined) {\n            return leadingEdge(lastCallTime);\n          }\n          if (maxing) {\n            // Handle invocations in a tight loop.\n            timerId = setTimeout(timerExpired, wait);\n            return invokeFunc(lastCallTime);\n          }\n        }\n        if (timerId === undefined) {\n          timerId = setTimeout(timerExpired, wait);\n        }\n        return result;\n      }\n      debounced.cancel = cancel;\n      debounced.flush = flush;\n      return debounced;\n    }\n\n    /**\n     * Defers invoking the `func` until the current call stack has cleared. Any\n     * additional arguments are provided to `func` when it's invoked.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to defer.\n     * @param {...*} [args] The arguments to invoke `func` with.\n     * @returns {number} Returns the timer id.\n     * @example\n     *\n     * _.defer(function(text) {\n     *   console.log(text);\n     * }, 'deferred');\n     * // => Logs 'deferred' after one millisecond.\n     */\n    var defer = baseRest(function(func, args) {\n      return baseDelay(func, 1, args);\n    });\n\n    /**\n     * Invokes `func` after `wait` milliseconds. Any additional arguments are\n     * provided to `func` when it's invoked.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @param {...*} [args] The arguments to invoke `func` with.\n     * @returns {number} Returns the timer id.\n     * @example\n     *\n     * _.delay(function(text) {\n     *   console.log(text);\n     * }, 1000, 'later');\n     * // => Logs 'later' after one second.\n     */\n    var delay = baseRest(function(func, wait, args) {\n      return baseDelay(func, toNumber(wait) || 0, args);\n    });\n\n    /**\n     * Creates a function that invokes `func` with arguments reversed.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Function\n     * @param {Function} func The function to flip arguments for.\n     * @returns {Function} Returns the new flipped function.\n     * @example\n     *\n     * var flipped = _.flip(function() {\n     *   return _.toArray(arguments);\n     * });\n     *\n     * flipped('a', 'b', 'c', 'd');\n     * // => ['d', 'c', 'b', 'a']\n     */\n    function flip(func) {\n      return createWrap(func, WRAP_FLIP_FLAG);\n    }\n\n    /**\n     * Creates a function that memoizes the result of `func`. If `resolver` is\n     * provided, it determines the cache key for storing the result based on the\n     * arguments provided to the memoized function. By default, the first argument\n     * provided to the memoized function is used as the map cache key. The `func`\n     * is invoked with the `this` binding of the memoized function.\n     *\n     * **Note:** The cache is exposed as the `cache` property on the memoized\n     * function. Its creation may be customized by replacing the `_.memoize.Cache`\n     * constructor with one whose instances implement the\n     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n     * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to have its output memoized.\n     * @param {Function} [resolver] The function to resolve the cache key.\n     * @returns {Function} Returns the new memoized function.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     * var other = { 'c': 3, 'd': 4 };\n     *\n     * var values = _.memoize(_.values);\n     * values(object);\n     * // => [1, 2]\n     *\n     * values(other);\n     * // => [3, 4]\n     *\n     * object.a = 2;\n     * values(object);\n     * // => [1, 2]\n     *\n     * // Modify the result cache.\n     * values.cache.set(object, ['a', 'b']);\n     * values(object);\n     * // => ['a', 'b']\n     *\n     * // Replace `_.memoize.Cache`.\n     * _.memoize.Cache = WeakMap;\n     */\n    function memoize(func, resolver) {\n      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      var memoized = function() {\n        var args = arguments,\n            key = resolver ? resolver.apply(this, args) : args[0],\n            cache = memoized.cache;\n\n        if (cache.has(key)) {\n          return cache.get(key);\n        }\n        var result = func.apply(this, args);\n        memoized.cache = cache.set(key, result) || cache;\n        return result;\n      };\n      memoized.cache = new (memoize.Cache || MapCache);\n      return memoized;\n    }\n\n    // Expose `MapCache`.\n    memoize.Cache = MapCache;\n\n    /**\n     * Creates a function that negates the result of the predicate `func`. The\n     * `func` predicate is invoked with the `this` binding and arguments of the\n     * created function.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} predicate The predicate to negate.\n     * @returns {Function} Returns the new negated function.\n     * @example\n     *\n     * function isEven(n) {\n     *   return n % 2 == 0;\n     * }\n     *\n     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n     * // => [1, 3, 5]\n     */\n    function negate(predicate) {\n      if (typeof predicate != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      return function() {\n        var args = arguments;\n        switch (args.length) {\n          case 0: return !predicate.call(this);\n          case 1: return !predicate.call(this, args[0]);\n          case 2: return !predicate.call(this, args[0], args[1]);\n          case 3: return !predicate.call(this, args[0], args[1], args[2]);\n        }\n        return !predicate.apply(this, args);\n      };\n    }\n\n    /**\n     * Creates a function that is restricted to invoking `func` once. Repeat calls\n     * to the function return the value of the first invocation. The `func` is\n     * invoked with the `this` binding and arguments of the created function.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * var initialize = _.once(createApplication);\n     * initialize();\n     * initialize();\n     * // => `createApplication` is invoked once\n     */\n    function once(func) {\n      return before(2, func);\n    }\n\n    /**\n     * Creates a function that invokes `func` with its arguments transformed.\n     *\n     * @static\n     * @since 4.0.0\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to wrap.\n     * @param {...(Function|Function[])} [transforms=[_.identity]]\n     *  The argument transforms.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * function doubled(n) {\n     *   return n * 2;\n     * }\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var func = _.overArgs(function(x, y) {\n     *   return [x, y];\n     * }, [square, doubled]);\n     *\n     * func(9, 3);\n     * // => [81, 6]\n     *\n     * func(10, 5);\n     * // => [100, 10]\n     */\n    var overArgs = castRest(function(func, transforms) {\n      transforms = (transforms.length == 1 && isArray(transforms[0]))\n        ? arrayMap(transforms[0], baseUnary(getIteratee()))\n        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));\n\n      var funcsLength = transforms.length;\n      return baseRest(function(args) {\n        var index = -1,\n            length = nativeMin(args.length, funcsLength);\n\n        while (++index < length) {\n          args[index] = transforms[index].call(this, args[index]);\n        }\n        return apply(func, this, args);\n      });\n    });\n\n    /**\n     * Creates a function that invokes `func` with `partials` prepended to the\n     * arguments it receives. This method is like `_.bind` except it does **not**\n     * alter the `this` binding.\n     *\n     * The `_.partial.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of partially\n     * applied functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.2.0\n     * @category Function\n     * @param {Function} func The function to partially apply arguments to.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new partially applied function.\n     * @example\n     *\n     * function greet(greeting, name) {\n     *   return greeting + ' ' + name;\n     * }\n     *\n     * var sayHelloTo = _.partial(greet, 'hello');\n     * sayHelloTo('fred');\n     * // => 'hello fred'\n     *\n     * // Partially applied with placeholders.\n     * var greetFred = _.partial(greet, _, 'fred');\n     * greetFred('hi');\n     * // => 'hi fred'\n     */\n    var partial = baseRest(function(func, partials) {\n      var holders = replaceHolders(partials, getHolder(partial));\n      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);\n    });\n\n    /**\n     * This method is like `_.partial` except that partially applied arguments\n     * are appended to the arguments it receives.\n     *\n     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of partially\n     * applied functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.0.0\n     * @category Function\n     * @param {Function} func The function to partially apply arguments to.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new partially applied function.\n     * @example\n     *\n     * function greet(greeting, name) {\n     *   return greeting + ' ' + name;\n     * }\n     *\n     * var greetFred = _.partialRight(greet, 'fred');\n     * greetFred('hi');\n     * // => 'hi fred'\n     *\n     * // Partially applied with placeholders.\n     * var sayHelloTo = _.partialRight(greet, 'hello', _);\n     * sayHelloTo('fred');\n     * // => 'hello fred'\n     */\n    var partialRight = baseRest(function(func, partials) {\n      var holders = replaceHolders(partials, getHolder(partialRight));\n      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);\n    });\n\n    /**\n     * Creates a function that invokes `func` with arguments arranged according\n     * to the specified `indexes` where the argument value at the first index is\n     * provided as the first argument, the argument value at the second index is\n     * provided as the second argument, and so on.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} func The function to rearrange arguments for.\n     * @param {...(number|number[])} indexes The arranged argument indexes.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var rearged = _.rearg(function(a, b, c) {\n     *   return [a, b, c];\n     * }, [2, 0, 1]);\n     *\n     * rearged('b', 'c', 'a')\n     * // => ['a', 'b', 'c']\n     */\n    var rearg = flatRest(function(func, indexes) {\n      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);\n    });\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of the\n     * created function and arguments from `start` and beyond provided as\n     * an array.\n     *\n     * **Note:** This method is based on the\n     * [rest parameter](https://mdn.io/rest_parameters).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Function\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var say = _.rest(function(what, names) {\n     *   return what + ' ' + _.initial(names).join(', ') +\n     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n     * });\n     *\n     * say('hello', 'fred', 'barney', 'pebbles');\n     * // => 'hello fred, barney, & pebbles'\n     */\n    function rest(func, start) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      start = start === undefined ? start : toInteger(start);\n      return baseRest(func, start);\n    }\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of the\n     * create function and an array of arguments much like\n     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).\n     *\n     * **Note:** This method is based on the\n     * [spread operator](https://mdn.io/spread_operator).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.2.0\n     * @category Function\n     * @param {Function} func The function to spread arguments over.\n     * @param {number} [start=0] The start position of the spread.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var say = _.spread(function(who, what) {\n     *   return who + ' says ' + what;\n     * });\n     *\n     * say(['fred', 'hello']);\n     * // => 'fred says hello'\n     *\n     * var numbers = Promise.all([\n     *   Promise.resolve(40),\n     *   Promise.resolve(36)\n     * ]);\n     *\n     * numbers.then(_.spread(function(x, y) {\n     *   return x + y;\n     * }));\n     * // => a Promise of 76\n     */\n    function spread(func, start) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      start = start == null ? 0 : nativeMax(toInteger(start), 0);\n      return baseRest(function(args) {\n        var array = args[start],\n            otherArgs = castSlice(args, 0, start);\n\n        if (array) {\n          arrayPush(otherArgs, array);\n        }\n        return apply(func, this, otherArgs);\n      });\n    }\n\n    /**\n     * Creates a throttled function that only invokes `func` at most once per\n     * every `wait` milliseconds. The throttled function comes with a `cancel`\n     * method to cancel delayed `func` invocations and a `flush` method to\n     * immediately invoke them. Provide `options` to indicate whether `func`\n     * should be invoked on the leading and/or trailing edge of the `wait`\n     * timeout. The `func` is invoked with the last arguments provided to the\n     * throttled function. Subsequent calls to the throttled function return the\n     * result of the last `func` invocation.\n     *\n     * **Note:** If `leading` and `trailing` options are `true`, `func` is\n     * invoked on the trailing edge of the timeout only if the throttled function\n     * is invoked more than once during the `wait` timeout.\n     *\n     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n     * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n     *\n     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n     * for details over the differences between `_.throttle` and `_.debounce`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to throttle.\n     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n     * @param {Object} [options={}] The options object.\n     * @param {boolean} [options.leading=true]\n     *  Specify invoking on the leading edge of the timeout.\n     * @param {boolean} [options.trailing=true]\n     *  Specify invoking on the trailing edge of the timeout.\n     * @returns {Function} Returns the new throttled function.\n     * @example\n     *\n     * // Avoid excessively updating the position while scrolling.\n     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n     *\n     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n     * jQuery(element).on('click', throttled);\n     *\n     * // Cancel the trailing throttled invocation.\n     * jQuery(window).on('popstate', throttled.cancel);\n     */\n    function throttle(func, wait, options) {\n      var leading = true,\n          trailing = true;\n\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      if (isObject(options)) {\n        leading = 'leading' in options ? !!options.leading : leading;\n        trailing = 'trailing' in options ? !!options.trailing : trailing;\n      }\n      return debounce(func, wait, {\n        'leading': leading,\n        'maxWait': wait,\n        'trailing': trailing\n      });\n    }\n\n    /**\n     * Creates a function that accepts up to one argument, ignoring any\n     * additional arguments.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Function\n     * @param {Function} func The function to cap arguments for.\n     * @returns {Function} Returns the new capped function.\n     * @example\n     *\n     * _.map(['6', '8', '10'], _.unary(parseInt));\n     * // => [6, 8, 10]\n     */\n    function unary(func) {\n      return ary(func, 1);\n    }\n\n    /**\n     * Creates a function that provides `value` to `wrapper` as its first\n     * argument. Any additional arguments provided to the function are appended\n     * to those provided to the `wrapper`. The wrapper is invoked with the `this`\n     * binding of the created function.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {*} value The value to wrap.\n     * @param {Function} [wrapper=identity] The wrapper function.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var p = _.wrap(_.escape, function(func, text) {\n     *   return '<p>' + func(text) + '</p>';\n     * });\n     *\n     * p('fred, barney, & pebbles');\n     * // => '<p>fred, barney, &amp; pebbles</p>'\n     */\n    function wrap(value, wrapper) {\n      return partial(castFunction(wrapper), value);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Casts `value` as an array if it's not one.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.4.0\n     * @category Lang\n     * @param {*} value The value to inspect.\n     * @returns {Array} Returns the cast array.\n     * @example\n     *\n     * _.castArray(1);\n     * // => [1]\n     *\n     * _.castArray({ 'a': 1 });\n     * // => [{ 'a': 1 }]\n     *\n     * _.castArray('abc');\n     * // => ['abc']\n     *\n     * _.castArray(null);\n     * // => [null]\n     *\n     * _.castArray(undefined);\n     * // => [undefined]\n     *\n     * _.castArray();\n     * // => []\n     *\n     * var array = [1, 2, 3];\n     * console.log(_.castArray(array) === array);\n     * // => true\n     */\n    function castArray() {\n      if (!arguments.length) {\n        return [];\n      }\n      var value = arguments[0];\n      return isArray(value) ? value : [value];\n    }\n\n    /**\n     * Creates a shallow clone of `value`.\n     *\n     * **Note:** This method is loosely based on the\n     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n     * and supports cloning arrays, array buffers, booleans, date objects, maps,\n     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n     * arrays. The own enumerable properties of `arguments` objects are cloned\n     * as plain objects. An empty object is returned for uncloneable values such\n     * as error objects, functions, DOM nodes, and WeakMaps.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to clone.\n     * @returns {*} Returns the cloned value.\n     * @see _.cloneDeep\n     * @example\n     *\n     * var objects = [{ 'a': 1 }, { 'b': 2 }];\n     *\n     * var shallow = _.clone(objects);\n     * console.log(shallow[0] === objects[0]);\n     * // => true\n     */\n    function clone(value) {\n      return baseClone(value, CLONE_SYMBOLS_FLAG);\n    }\n\n    /**\n     * This method is like `_.clone` except that it accepts `customizer` which\n     * is invoked to produce the cloned value. If `customizer` returns `undefined`,\n     * cloning is handled by the method instead. The `customizer` is invoked with\n     * up to four arguments; (value [, index|key, object, stack]).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to clone.\n     * @param {Function} [customizer] The function to customize cloning.\n     * @returns {*} Returns the cloned value.\n     * @see _.cloneDeepWith\n     * @example\n     *\n     * function customizer(value) {\n     *   if (_.isElement(value)) {\n     *     return value.cloneNode(false);\n     *   }\n     * }\n     *\n     * var el = _.cloneWith(document.body, customizer);\n     *\n     * console.log(el === document.body);\n     * // => false\n     * console.log(el.nodeName);\n     * // => 'BODY'\n     * console.log(el.childNodes.length);\n     * // => 0\n     */\n    function cloneWith(value, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);\n    }\n\n    /**\n     * This method is like `_.clone` except that it recursively clones `value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.0.0\n     * @category Lang\n     * @param {*} value The value to recursively clone.\n     * @returns {*} Returns the deep cloned value.\n     * @see _.clone\n     * @example\n     *\n     * var objects = [{ 'a': 1 }, { 'b': 2 }];\n     *\n     * var deep = _.cloneDeep(objects);\n     * console.log(deep[0] === objects[0]);\n     * // => false\n     */\n    function cloneDeep(value) {\n      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n    }\n\n    /**\n     * This method is like `_.cloneWith` except that it recursively clones `value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to recursively clone.\n     * @param {Function} [customizer] The function to customize cloning.\n     * @returns {*} Returns the deep cloned value.\n     * @see _.cloneWith\n     * @example\n     *\n     * function customizer(value) {\n     *   if (_.isElement(value)) {\n     *     return value.cloneNode(true);\n     *   }\n     * }\n     *\n     * var el = _.cloneDeepWith(document.body, customizer);\n     *\n     * console.log(el === document.body);\n     * // => false\n     * console.log(el.nodeName);\n     * // => 'BODY'\n     * console.log(el.childNodes.length);\n     * // => 20\n     */\n    function cloneDeepWith(value, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);\n    }\n\n    /**\n     * Checks if `object` conforms to `source` by invoking the predicate\n     * properties of `source` with the corresponding property values of `object`.\n     *\n     * **Note:** This method is equivalent to `_.conforms` when `source` is\n     * partially applied.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.14.0\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     *\n     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });\n     * // => true\n     *\n     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });\n     * // => false\n     */\n    function conformsTo(object, source) {\n      return source == null || baseConformsTo(object, source, keys(source));\n    }\n\n    /**\n     * Performs a\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * comparison between two values to determine if they are equivalent.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     * var other = { 'a': 1 };\n     *\n     * _.eq(object, object);\n     * // => true\n     *\n     * _.eq(object, other);\n     * // => false\n     *\n     * _.eq('a', 'a');\n     * // => true\n     *\n     * _.eq('a', Object('a'));\n     * // => false\n     *\n     * _.eq(NaN, NaN);\n     * // => true\n     */\n    function eq(value, other) {\n      return value === other || (value !== value && other !== other);\n    }\n\n    /**\n     * Checks if `value` is greater than `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than `other`,\n     *  else `false`.\n     * @see _.lt\n     * @example\n     *\n     * _.gt(3, 1);\n     * // => true\n     *\n     * _.gt(3, 3);\n     * // => false\n     *\n     * _.gt(1, 3);\n     * // => false\n     */\n    var gt = createRelationalOperation(baseGt);\n\n    /**\n     * Checks if `value` is greater than or equal to `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than or equal to\n     *  `other`, else `false`.\n     * @see _.lte\n     * @example\n     *\n     * _.gte(3, 1);\n     * // => true\n     *\n     * _.gte(3, 3);\n     * // => true\n     *\n     * _.gte(1, 3);\n     * // => false\n     */\n    var gte = createRelationalOperation(function(value, other) {\n      return value >= other;\n    });\n\n    /**\n     * Checks if `value` is likely an `arguments` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n     *  else `false`.\n     * @example\n     *\n     * _.isArguments(function() { return arguments; }());\n     * // => true\n     *\n     * _.isArguments([1, 2, 3]);\n     * // => false\n     */\n    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n        !propertyIsEnumerable.call(value, 'callee');\n    };\n\n    /**\n     * Checks if `value` is classified as an `Array` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n     * @example\n     *\n     * _.isArray([1, 2, 3]);\n     * // => true\n     *\n     * _.isArray(document.body.children);\n     * // => false\n     *\n     * _.isArray('abc');\n     * // => false\n     *\n     * _.isArray(_.noop);\n     * // => false\n     */\n    var isArray = Array.isArray;\n\n    /**\n     * Checks if `value` is classified as an `ArrayBuffer` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n     * @example\n     *\n     * _.isArrayBuffer(new ArrayBuffer(2));\n     * // => true\n     *\n     * _.isArrayBuffer(new Array(2));\n     * // => false\n     */\n    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;\n\n    /**\n     * Checks if `value` is array-like. A value is considered array-like if it's\n     * not a function and has a `value.length` that's an integer greater than or\n     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n     * @example\n     *\n     * _.isArrayLike([1, 2, 3]);\n     * // => true\n     *\n     * _.isArrayLike(document.body.children);\n     * // => true\n     *\n     * _.isArrayLike('abc');\n     * // => true\n     *\n     * _.isArrayLike(_.noop);\n     * // => false\n     */\n    function isArrayLike(value) {\n      return value != null && isLength(value.length) && !isFunction(value);\n    }\n\n    /**\n     * This method is like `_.isArrayLike` except that it also checks if `value`\n     * is an object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array-like object,\n     *  else `false`.\n     * @example\n     *\n     * _.isArrayLikeObject([1, 2, 3]);\n     * // => true\n     *\n     * _.isArrayLikeObject(document.body.children);\n     * // => true\n     *\n     * _.isArrayLikeObject('abc');\n     * // => false\n     *\n     * _.isArrayLikeObject(_.noop);\n     * // => false\n     */\n    function isArrayLikeObject(value) {\n      return isObjectLike(value) && isArrayLike(value);\n    }\n\n    /**\n     * Checks if `value` is classified as a boolean primitive or object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.\n     * @example\n     *\n     * _.isBoolean(false);\n     * // => true\n     *\n     * _.isBoolean(null);\n     * // => false\n     */\n    function isBoolean(value) {\n      return value === true || value === false ||\n        (isObjectLike(value) && baseGetTag(value) == boolTag);\n    }\n\n    /**\n     * Checks if `value` is a buffer.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n     * @example\n     *\n     * _.isBuffer(new Buffer(2));\n     * // => true\n     *\n     * _.isBuffer(new Uint8Array(2));\n     * // => false\n     */\n    var isBuffer = nativeIsBuffer || stubFalse;\n\n    /**\n     * Checks if `value` is classified as a `Date` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n     * @example\n     *\n     * _.isDate(new Date);\n     * // => true\n     *\n     * _.isDate('Mon April 23 2012');\n     * // => false\n     */\n    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;\n\n    /**\n     * Checks if `value` is likely a DOM element.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.\n     * @example\n     *\n     * _.isElement(document.body);\n     * // => true\n     *\n     * _.isElement('<body>');\n     * // => false\n     */\n    function isElement(value) {\n      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);\n    }\n\n    /**\n     * Checks if `value` is an empty object, collection, map, or set.\n     *\n     * Objects are considered empty if they have no own enumerable string keyed\n     * properties.\n     *\n     * Array-like values such as `arguments` objects, arrays, buffers, strings, or\n     * jQuery-like collections are considered empty if they have a `length` of `0`.\n     * Similarly, maps and sets are considered empty if they have a `size` of `0`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n     * @example\n     *\n     * _.isEmpty(null);\n     * // => true\n     *\n     * _.isEmpty(true);\n     * // => true\n     *\n     * _.isEmpty(1);\n     * // => true\n     *\n     * _.isEmpty([1, 2, 3]);\n     * // => false\n     *\n     * _.isEmpty({ 'a': 1 });\n     * // => false\n     */\n    function isEmpty(value) {\n      if (value == null) {\n        return true;\n      }\n      if (isArrayLike(value) &&\n          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||\n            isBuffer(value) || isTypedArray(value) || isArguments(value))) {\n        return !value.length;\n      }\n      var tag = getTag(value);\n      if (tag == mapTag || tag == setTag) {\n        return !value.size;\n      }\n      if (isPrototype(value)) {\n        return !baseKeys(value).length;\n      }\n      for (var key in value) {\n        if (hasOwnProperty.call(value, key)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    /**\n     * Performs a deep comparison between two values to determine if they are\n     * equivalent.\n     *\n     * **Note:** This method supports comparing arrays, array buffers, booleans,\n     * date objects, error objects, maps, numbers, `Object` objects, regexes,\n     * sets, strings, symbols, and typed arrays. `Object` objects are compared\n     * by their own, not inherited, enumerable properties. Functions and DOM\n     * nodes are compared by strict equality, i.e. `===`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     * var other = { 'a': 1 };\n     *\n     * _.isEqual(object, other);\n     * // => true\n     *\n     * object === other;\n     * // => false\n     */\n    function isEqual(value, other) {\n      return baseIsEqual(value, other);\n    }\n\n    /**\n     * This method is like `_.isEqual` except that it accepts `customizer` which\n     * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n     * are handled by the method instead. The `customizer` is invoked with up to\n     * six arguments: (objValue, othValue [, index|key, object, other, stack]).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * function isGreeting(value) {\n     *   return /^h(?:i|ello)$/.test(value);\n     * }\n     *\n     * function customizer(objValue, othValue) {\n     *   if (isGreeting(objValue) && isGreeting(othValue)) {\n     *     return true;\n     *   }\n     * }\n     *\n     * var array = ['hello', 'goodbye'];\n     * var other = ['hi', 'goodbye'];\n     *\n     * _.isEqualWith(array, other, customizer);\n     * // => true\n     */\n    function isEqualWith(value, other, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      var result = customizer ? customizer(value, other) : undefined;\n      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;\n    }\n\n    /**\n     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,\n     * `SyntaxError`, `TypeError`, or `URIError` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.\n     * @example\n     *\n     * _.isError(new Error);\n     * // => true\n     *\n     * _.isError(Error);\n     * // => false\n     */\n    function isError(value) {\n      if (!isObjectLike(value)) {\n        return false;\n      }\n      var tag = baseGetTag(value);\n      return tag == errorTag || tag == domExcTag ||\n        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));\n    }\n\n    /**\n     * Checks if `value` is a finite primitive number.\n     *\n     * **Note:** This method is based on\n     * [`Number.isFinite`](https://mdn.io/Number/isFinite).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.\n     * @example\n     *\n     * _.isFinite(3);\n     * // => true\n     *\n     * _.isFinite(Number.MIN_VALUE);\n     * // => true\n     *\n     * _.isFinite(Infinity);\n     * // => false\n     *\n     * _.isFinite('3');\n     * // => false\n     */\n    function isFinite(value) {\n      return typeof value == 'number' && nativeIsFinite(value);\n    }\n\n    /**\n     * Checks if `value` is classified as a `Function` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n     * @example\n     *\n     * _.isFunction(_);\n     * // => true\n     *\n     * _.isFunction(/abc/);\n     * // => false\n     */\n    function isFunction(value) {\n      if (!isObject(value)) {\n        return false;\n      }\n      // The use of `Object#toString` avoids issues with the `typeof` operator\n      // in Safari 9 which returns 'object' for typed arrays and other constructors.\n      var tag = baseGetTag(value);\n      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n    }\n\n    /**\n     * Checks if `value` is an integer.\n     *\n     * **Note:** This method is based on\n     * [`Number.isInteger`](https://mdn.io/Number/isInteger).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.\n     * @example\n     *\n     * _.isInteger(3);\n     * // => true\n     *\n     * _.isInteger(Number.MIN_VALUE);\n     * // => false\n     *\n     * _.isInteger(Infinity);\n     * // => false\n     *\n     * _.isInteger('3');\n     * // => false\n     */\n    function isInteger(value) {\n      return typeof value == 'number' && value == toInteger(value);\n    }\n\n    /**\n     * Checks if `value` is a valid array-like length.\n     *\n     * **Note:** This method is loosely based on\n     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n     * @example\n     *\n     * _.isLength(3);\n     * // => true\n     *\n     * _.isLength(Number.MIN_VALUE);\n     * // => false\n     *\n     * _.isLength(Infinity);\n     * // => false\n     *\n     * _.isLength('3');\n     * // => false\n     */\n    function isLength(value) {\n      return typeof value == 'number' &&\n        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n    }\n\n    /**\n     * Checks if `value` is the\n     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n     * @example\n     *\n     * _.isObject({});\n     * // => true\n     *\n     * _.isObject([1, 2, 3]);\n     * // => true\n     *\n     * _.isObject(_.noop);\n     * // => true\n     *\n     * _.isObject(null);\n     * // => false\n     */\n    function isObject(value) {\n      var type = typeof value;\n      return value != null && (type == 'object' || type == 'function');\n    }\n\n    /**\n     * Checks if `value` is object-like. A value is object-like if it's not `null`\n     * and has a `typeof` result of \"object\".\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n     * @example\n     *\n     * _.isObjectLike({});\n     * // => true\n     *\n     * _.isObjectLike([1, 2, 3]);\n     * // => true\n     *\n     * _.isObjectLike(_.noop);\n     * // => false\n     *\n     * _.isObjectLike(null);\n     * // => false\n     */\n    function isObjectLike(value) {\n      return value != null && typeof value == 'object';\n    }\n\n    /**\n     * Checks if `value` is classified as a `Map` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n     * @example\n     *\n     * _.isMap(new Map);\n     * // => true\n     *\n     * _.isMap(new WeakMap);\n     * // => false\n     */\n    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\n    /**\n     * Performs a partial deep comparison between `object` and `source` to\n     * determine if `object` contains equivalent property values.\n     *\n     * **Note:** This method is equivalent to `_.matches` when `source` is\n     * partially applied.\n     *\n     * Partial comparisons will match empty array and empty object `source`\n     * values against any array or object value, respectively. See `_.isEqual`\n     * for a list of supported value comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     *\n     * _.isMatch(object, { 'b': 2 });\n     * // => true\n     *\n     * _.isMatch(object, { 'b': 1 });\n     * // => false\n     */\n    function isMatch(object, source) {\n      return object === source || baseIsMatch(object, source, getMatchData(source));\n    }\n\n    /**\n     * This method is like `_.isMatch` except that it accepts `customizer` which\n     * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n     * are handled by the method instead. The `customizer` is invoked with five\n     * arguments: (objValue, srcValue, index|key, object, source).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     * @example\n     *\n     * function isGreeting(value) {\n     *   return /^h(?:i|ello)$/.test(value);\n     * }\n     *\n     * function customizer(objValue, srcValue) {\n     *   if (isGreeting(objValue) && isGreeting(srcValue)) {\n     *     return true;\n     *   }\n     * }\n     *\n     * var object = { 'greeting': 'hello' };\n     * var source = { 'greeting': 'hi' };\n     *\n     * _.isMatchWith(object, source, customizer);\n     * // => true\n     */\n    function isMatchWith(object, source, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return baseIsMatch(object, source, getMatchData(source), customizer);\n    }\n\n    /**\n     * Checks if `value` is `NaN`.\n     *\n     * **Note:** This method is based on\n     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as\n     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for\n     * `undefined` and other non-number values.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n     * @example\n     *\n     * _.isNaN(NaN);\n     * // => true\n     *\n     * _.isNaN(new Number(NaN));\n     * // => true\n     *\n     * isNaN(undefined);\n     * // => true\n     *\n     * _.isNaN(undefined);\n     * // => false\n     */\n    function isNaN(value) {\n      // An `NaN` primitive is the only value that is not equal to itself.\n      // Perform the `toStringTag` check first to avoid errors with some\n      // ActiveX objects in IE.\n      return isNumber(value) && value != +value;\n    }\n\n    /**\n     * Checks if `value` is a pristine native function.\n     *\n     * **Note:** This method can't reliably detect native functions in the presence\n     * of the core-js package because core-js circumvents this kind of detection.\n     * Despite multiple requests, the core-js maintainer has made it clear: any\n     * attempt to fix the detection will be obstructed. As a result, we're left\n     * with little choice but to throw an error. Unfortunately, this also affects\n     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),\n     * which rely on core-js.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a native function,\n     *  else `false`.\n     * @example\n     *\n     * _.isNative(Array.prototype.push);\n     * // => true\n     *\n     * _.isNative(_);\n     * // => false\n     */\n    function isNative(value) {\n      if (isMaskable(value)) {\n        throw new Error(CORE_ERROR_TEXT);\n      }\n      return baseIsNative(value);\n    }\n\n    /**\n     * Checks if `value` is `null`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n     * @example\n     *\n     * _.isNull(null);\n     * // => true\n     *\n     * _.isNull(void 0);\n     * // => false\n     */\n    function isNull(value) {\n      return value === null;\n    }\n\n    /**\n     * Checks if `value` is `null` or `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.\n     * @example\n     *\n     * _.isNil(null);\n     * // => true\n     *\n     * _.isNil(void 0);\n     * // => true\n     *\n     * _.isNil(NaN);\n     * // => false\n     */\n    function isNil(value) {\n      return value == null;\n    }\n\n    /**\n     * Checks if `value` is classified as a `Number` primitive or object.\n     *\n     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are\n     * classified as numbers, use the `_.isFinite` method.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a number, else `false`.\n     * @example\n     *\n     * _.isNumber(3);\n     * // => true\n     *\n     * _.isNumber(Number.MIN_VALUE);\n     * // => true\n     *\n     * _.isNumber(Infinity);\n     * // => true\n     *\n     * _.isNumber('3');\n     * // => false\n     */\n    function isNumber(value) {\n      return typeof value == 'number' ||\n        (isObjectLike(value) && baseGetTag(value) == numberTag);\n    }\n\n    /**\n     * Checks if `value` is a plain object, that is, an object created by the\n     * `Object` constructor or one with a `[[Prototype]]` of `null`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.8.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * _.isPlainObject(new Foo);\n     * // => false\n     *\n     * _.isPlainObject([1, 2, 3]);\n     * // => false\n     *\n     * _.isPlainObject({ 'x': 0, 'y': 0 });\n     * // => true\n     *\n     * _.isPlainObject(Object.create(null));\n     * // => true\n     */\n    function isPlainObject(value) {\n      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n        return false;\n      }\n      var proto = getPrototype(value);\n      if (proto === null) {\n        return true;\n      }\n      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n      return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n        funcToString.call(Ctor) == objectCtorString;\n    }\n\n    /**\n     * Checks if `value` is classified as a `RegExp` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n     * @example\n     *\n     * _.isRegExp(/abc/);\n     * // => true\n     *\n     * _.isRegExp('/abc/');\n     * // => false\n     */\n    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;\n\n    /**\n     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754\n     * double precision number which isn't the result of a rounded unsafe integer.\n     *\n     * **Note:** This method is based on\n     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.\n     * @example\n     *\n     * _.isSafeInteger(3);\n     * // => true\n     *\n     * _.isSafeInteger(Number.MIN_VALUE);\n     * // => false\n     *\n     * _.isSafeInteger(Infinity);\n     * // => false\n     *\n     * _.isSafeInteger('3');\n     * // => false\n     */\n    function isSafeInteger(value) {\n      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;\n    }\n\n    /**\n     * Checks if `value` is classified as a `Set` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n     * @example\n     *\n     * _.isSet(new Set);\n     * // => true\n     *\n     * _.isSet(new WeakSet);\n     * // => false\n     */\n    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\n    /**\n     * Checks if `value` is classified as a `String` primitive or object.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a string, else `false`.\n     * @example\n     *\n     * _.isString('abc');\n     * // => true\n     *\n     * _.isString(1);\n     * // => false\n     */\n    function isString(value) {\n      return typeof value == 'string' ||\n        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n    }\n\n    /**\n     * Checks if `value` is classified as a `Symbol` primitive or object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n     * @example\n     *\n     * _.isSymbol(Symbol.iterator);\n     * // => true\n     *\n     * _.isSymbol('abc');\n     * // => false\n     */\n    function isSymbol(value) {\n      return typeof value == 'symbol' ||\n        (isObjectLike(value) && baseGetTag(value) == symbolTag);\n    }\n\n    /**\n     * Checks if `value` is classified as a typed array.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n     * @example\n     *\n     * _.isTypedArray(new Uint8Array);\n     * // => true\n     *\n     * _.isTypedArray([]);\n     * // => false\n     */\n    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\n    /**\n     * Checks if `value` is `undefined`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n     * @example\n     *\n     * _.isUndefined(void 0);\n     * // => true\n     *\n     * _.isUndefined(null);\n     * // => false\n     */\n    function isUndefined(value) {\n      return value === undefined;\n    }\n\n    /**\n     * Checks if `value` is classified as a `WeakMap` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.\n     * @example\n     *\n     * _.isWeakMap(new WeakMap);\n     * // => true\n     *\n     * _.isWeakMap(new Map);\n     * // => false\n     */\n    function isWeakMap(value) {\n      return isObjectLike(value) && getTag(value) == weakMapTag;\n    }\n\n    /**\n     * Checks if `value` is classified as a `WeakSet` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.\n     * @example\n     *\n     * _.isWeakSet(new WeakSet);\n     * // => true\n     *\n     * _.isWeakSet(new Set);\n     * // => false\n     */\n    function isWeakSet(value) {\n      return isObjectLike(value) && baseGetTag(value) == weakSetTag;\n    }\n\n    /**\n     * Checks if `value` is less than `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than `other`,\n     *  else `false`.\n     * @see _.gt\n     * @example\n     *\n     * _.lt(1, 3);\n     * // => true\n     *\n     * _.lt(3, 3);\n     * // => false\n     *\n     * _.lt(3, 1);\n     * // => false\n     */\n    var lt = createRelationalOperation(baseLt);\n\n    /**\n     * Checks if `value` is less than or equal to `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than or equal to\n     *  `other`, else `false`.\n     * @see _.gte\n     * @example\n     *\n     * _.lte(1, 3);\n     * // => true\n     *\n     * _.lte(3, 3);\n     * // => true\n     *\n     * _.lte(3, 1);\n     * // => false\n     */\n    var lte = createRelationalOperation(function(value, other) {\n      return value <= other;\n    });\n\n    /**\n     * Converts `value` to an array.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {Array} Returns the converted array.\n     * @example\n     *\n     * _.toArray({ 'a': 1, 'b': 2 });\n     * // => [1, 2]\n     *\n     * _.toArray('abc');\n     * // => ['a', 'b', 'c']\n     *\n     * _.toArray(1);\n     * // => []\n     *\n     * _.toArray(null);\n     * // => []\n     */\n    function toArray(value) {\n      if (!value) {\n        return [];\n      }\n      if (isArrayLike(value)) {\n        return isString(value) ? stringToArray(value) : copyArray(value);\n      }\n      if (symIterator && value[symIterator]) {\n        return iteratorToArray(value[symIterator]());\n      }\n      var tag = getTag(value),\n          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);\n\n      return func(value);\n    }\n\n    /**\n     * Converts `value` to a finite number.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.12.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted number.\n     * @example\n     *\n     * _.toFinite(3.2);\n     * // => 3.2\n     *\n     * _.toFinite(Number.MIN_VALUE);\n     * // => 5e-324\n     *\n     * _.toFinite(Infinity);\n     * // => 1.7976931348623157e+308\n     *\n     * _.toFinite('3.2');\n     * // => 3.2\n     */\n    function toFinite(value) {\n      if (!value) {\n        return value === 0 ? value : 0;\n      }\n      value = toNumber(value);\n      if (value === INFINITY || value === -INFINITY) {\n        var sign = (value < 0 ? -1 : 1);\n        return sign * MAX_INTEGER;\n      }\n      return value === value ? value : 0;\n    }\n\n    /**\n     * Converts `value` to an integer.\n     *\n     * **Note:** This method is loosely based on\n     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.toInteger(3.2);\n     * // => 3\n     *\n     * _.toInteger(Number.MIN_VALUE);\n     * // => 0\n     *\n     * _.toInteger(Infinity);\n     * // => 1.7976931348623157e+308\n     *\n     * _.toInteger('3.2');\n     * // => 3\n     */\n    function toInteger(value) {\n      var result = toFinite(value),\n          remainder = result % 1;\n\n      return result === result ? (remainder ? result - remainder : result) : 0;\n    }\n\n    /**\n     * Converts `value` to an integer suitable for use as the length of an\n     * array-like object.\n     *\n     * **Note:** This method is based on\n     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.toLength(3.2);\n     * // => 3\n     *\n     * _.toLength(Number.MIN_VALUE);\n     * // => 0\n     *\n     * _.toLength(Infinity);\n     * // => 4294967295\n     *\n     * _.toLength('3.2');\n     * // => 3\n     */\n    function toLength(value) {\n      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;\n    }\n\n    /**\n     * Converts `value` to a number.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to process.\n     * @returns {number} Returns the number.\n     * @example\n     *\n     * _.toNumber(3.2);\n     * // => 3.2\n     *\n     * _.toNumber(Number.MIN_VALUE);\n     * // => 5e-324\n     *\n     * _.toNumber(Infinity);\n     * // => Infinity\n     *\n     * _.toNumber('3.2');\n     * // => 3.2\n     */\n    function toNumber(value) {\n      if (typeof value == 'number') {\n        return value;\n      }\n      if (isSymbol(value)) {\n        return NAN;\n      }\n      if (isObject(value)) {\n        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n        value = isObject(other) ? (other + '') : other;\n      }\n      if (typeof value != 'string') {\n        return value === 0 ? value : +value;\n      }\n      value = value.replace(reTrim, '');\n      var isBinary = reIsBinary.test(value);\n      return (isBinary || reIsOctal.test(value))\n        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n        : (reIsBadHex.test(value) ? NAN : +value);\n    }\n\n    /**\n     * Converts `value` to a plain object flattening inherited enumerable string\n     * keyed properties of `value` to own properties of the plain object.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {Object} Returns the converted plain object.\n     * @example\n     *\n     * function Foo() {\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.assign({ 'a': 1 }, new Foo);\n     * // => { 'a': 1, 'b': 2 }\n     *\n     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n     * // => { 'a': 1, 'b': 2, 'c': 3 }\n     */\n    function toPlainObject(value) {\n      return copyObject(value, keysIn(value));\n    }\n\n    /**\n     * Converts `value` to a safe integer. A safe integer can be compared and\n     * represented correctly.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.toSafeInteger(3.2);\n     * // => 3\n     *\n     * _.toSafeInteger(Number.MIN_VALUE);\n     * // => 0\n     *\n     * _.toSafeInteger(Infinity);\n     * // => 9007199254740991\n     *\n     * _.toSafeInteger('3.2');\n     * // => 3\n     */\n    function toSafeInteger(value) {\n      return value\n        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)\n        : (value === 0 ? value : 0);\n    }\n\n    /**\n     * Converts `value` to a string. An empty string is returned for `null`\n     * and `undefined` values. The sign of `-0` is preserved.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {string} Returns the converted string.\n     * @example\n     *\n     * _.toString(null);\n     * // => ''\n     *\n     * _.toString(-0);\n     * // => '-0'\n     *\n     * _.toString([1, 2, 3]);\n     * // => '1,2,3'\n     */\n    function toString(value) {\n      return value == null ? '' : baseToString(value);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Assigns own enumerable string keyed properties of source objects to the\n     * destination object. Source objects are applied from left to right.\n     * Subsequent sources overwrite property assignments of previous sources.\n     *\n     * **Note:** This method mutates `object` and is loosely based on\n     * [`Object.assign`](https://mdn.io/Object/assign).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.10.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.assignIn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * function Bar() {\n     *   this.c = 3;\n     * }\n     *\n     * Foo.prototype.b = 2;\n     * Bar.prototype.d = 4;\n     *\n     * _.assign({ 'a': 0 }, new Foo, new Bar);\n     * // => { 'a': 1, 'c': 3 }\n     */\n    var assign = createAssigner(function(object, source) {\n      if (isPrototype(source) || isArrayLike(source)) {\n        copyObject(source, keys(source), object);\n        return;\n      }\n      for (var key in source) {\n        if (hasOwnProperty.call(source, key)) {\n          assignValue(object, key, source[key]);\n        }\n      }\n    });\n\n    /**\n     * This method is like `_.assign` except that it iterates over own and\n     * inherited source properties.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias extend\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.assign\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * function Bar() {\n     *   this.c = 3;\n     * }\n     *\n     * Foo.prototype.b = 2;\n     * Bar.prototype.d = 4;\n     *\n     * _.assignIn({ 'a': 0 }, new Foo, new Bar);\n     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }\n     */\n    var assignIn = createAssigner(function(object, source) {\n      copyObject(source, keysIn(source), object);\n    });\n\n    /**\n     * This method is like `_.assignIn` except that it accepts `customizer`\n     * which is invoked to produce the assigned values. If `customizer` returns\n     * `undefined`, assignment is handled by the method instead. The `customizer`\n     * is invoked with five arguments: (objValue, srcValue, key, object, source).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias extendWith\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} sources The source objects.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @see _.assignWith\n     * @example\n     *\n     * function customizer(objValue, srcValue) {\n     *   return _.isUndefined(objValue) ? srcValue : objValue;\n     * }\n     *\n     * var defaults = _.partialRight(_.assignInWith, customizer);\n     *\n     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n     * // => { 'a': 1, 'b': 2 }\n     */\n    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {\n      copyObject(source, keysIn(source), object, customizer);\n    });\n\n    /**\n     * This method is like `_.assign` except that it accepts `customizer`\n     * which is invoked to produce the assigned values. If `customizer` returns\n     * `undefined`, assignment is handled by the method instead. The `customizer`\n     * is invoked with five arguments: (objValue, srcValue, key, object, source).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} sources The source objects.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @see _.assignInWith\n     * @example\n     *\n     * function customizer(objValue, srcValue) {\n     *   return _.isUndefined(objValue) ? srcValue : objValue;\n     * }\n     *\n     * var defaults = _.partialRight(_.assignWith, customizer);\n     *\n     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n     * // => { 'a': 1, 'b': 2 }\n     */\n    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {\n      copyObject(source, keys(source), object, customizer);\n    });\n\n    /**\n     * Creates an array of values corresponding to `paths` of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.0.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {...(string|string[])} [paths] The property paths to pick.\n     * @returns {Array} Returns the picked values.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n     *\n     * _.at(object, ['a[0].b.c', 'a[1]']);\n     * // => [3, 4]\n     */\n    var at = flatRest(baseAt);\n\n    /**\n     * Creates an object that inherits from the `prototype` object. If a\n     * `properties` object is given, its own enumerable string keyed properties\n     * are assigned to the created object.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.3.0\n     * @category Object\n     * @param {Object} prototype The object to inherit from.\n     * @param {Object} [properties] The properties to assign to the object.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * function Shape() {\n     *   this.x = 0;\n     *   this.y = 0;\n     * }\n     *\n     * function Circle() {\n     *   Shape.call(this);\n     * }\n     *\n     * Circle.prototype = _.create(Shape.prototype, {\n     *   'constructor': Circle\n     * });\n     *\n     * var circle = new Circle;\n     * circle instanceof Circle;\n     * // => true\n     *\n     * circle instanceof Shape;\n     * // => true\n     */\n    function create(prototype, properties) {\n      var result = baseCreate(prototype);\n      return properties == null ? result : baseAssign(result, properties);\n    }\n\n    /**\n     * Assigns own and inherited enumerable string keyed properties of source\n     * objects to the destination object for all destination properties that\n     * resolve to `undefined`. Source objects are applied from left to right.\n     * Once a property is set, additional values of the same property are ignored.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.defaultsDeep\n     * @example\n     *\n     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n     * // => { 'a': 1, 'b': 2 }\n     */\n    var defaults = baseRest(function(args) {\n      args.push(undefined, customDefaultsAssignIn);\n      return apply(assignInWith, undefined, args);\n    });\n\n    /**\n     * This method is like `_.defaults` except that it recursively assigns\n     * default properties.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.defaults\n     * @example\n     *\n     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n     * // => { 'a': { 'b': 2, 'c': 3 } }\n     */\n    var defaultsDeep = baseRest(function(args) {\n      args.push(undefined, customDefaultsMerge);\n      return apply(mergeWith, undefined, args);\n    });\n\n    /**\n     * This method is like `_.find` except that it returns the key of the first\n     * element `predicate` returns truthy for instead of the element itself.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.1.0\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {string|undefined} Returns the key of the matched element,\n     *  else `undefined`.\n     * @example\n     *\n     * var users = {\n     *   'barney':  { 'age': 36, 'active': true },\n     *   'fred':    { 'age': 40, 'active': false },\n     *   'pebbles': { 'age': 1,  'active': true }\n     * };\n     *\n     * _.findKey(users, function(o) { return o.age < 40; });\n     * // => 'barney' (iteration order is not guaranteed)\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findKey(users, { 'age': 1, 'active': true });\n     * // => 'pebbles'\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findKey(users, ['active', false]);\n     * // => 'fred'\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findKey(users, 'active');\n     * // => 'barney'\n     */\n    function findKey(object, predicate) {\n      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);\n    }\n\n    /**\n     * This method is like `_.findKey` except that it iterates over elements of\n     * a collection in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {string|undefined} Returns the key of the matched element,\n     *  else `undefined`.\n     * @example\n     *\n     * var users = {\n     *   'barney':  { 'age': 36, 'active': true },\n     *   'fred':    { 'age': 40, 'active': false },\n     *   'pebbles': { 'age': 1,  'active': true }\n     * };\n     *\n     * _.findLastKey(users, function(o) { return o.age < 40; });\n     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findLastKey(users, { 'age': 36, 'active': true });\n     * // => 'barney'\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findLastKey(users, ['active', false]);\n     * // => 'fred'\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findLastKey(users, 'active');\n     * // => 'pebbles'\n     */\n    function findLastKey(object, predicate) {\n      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);\n    }\n\n    /**\n     * Iterates over own and inherited enumerable string keyed properties of an\n     * object and invokes `iteratee` for each property. The iteratee is invoked\n     * with three arguments: (value, key, object). Iteratee functions may exit\n     * iteration early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.3.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forInRight\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forIn(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).\n     */\n    function forIn(object, iteratee) {\n      return object == null\n        ? object\n        : baseFor(object, getIteratee(iteratee, 3), keysIn);\n    }\n\n    /**\n     * This method is like `_.forIn` except that it iterates over properties of\n     * `object` in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forIn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forInRight(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.\n     */\n    function forInRight(object, iteratee) {\n      return object == null\n        ? object\n        : baseForRight(object, getIteratee(iteratee, 3), keysIn);\n    }\n\n    /**\n     * Iterates over own enumerable string keyed properties of an object and\n     * invokes `iteratee` for each property. The iteratee is invoked with three\n     * arguments: (value, key, object). Iteratee functions may exit iteration\n     * early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.3.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forOwnRight\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forOwn(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n     */\n    function forOwn(object, iteratee) {\n      return object && baseForOwn(object, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * This method is like `_.forOwn` except that it iterates over properties of\n     * `object` in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forOwn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forOwnRight(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.\n     */\n    function forOwnRight(object, iteratee) {\n      return object && baseForOwnRight(object, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * Creates an array of function property names from own enumerable properties\n     * of `object`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @returns {Array} Returns the function names.\n     * @see _.functionsIn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = _.constant('a');\n     *   this.b = _.constant('b');\n     * }\n     *\n     * Foo.prototype.c = _.constant('c');\n     *\n     * _.functions(new Foo);\n     * // => ['a', 'b']\n     */\n    function functions(object) {\n      return object == null ? [] : baseFunctions(object, keys(object));\n    }\n\n    /**\n     * Creates an array of function property names from own and inherited\n     * enumerable properties of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @returns {Array} Returns the function names.\n     * @see _.functions\n     * @example\n     *\n     * function Foo() {\n     *   this.a = _.constant('a');\n     *   this.b = _.constant('b');\n     * }\n     *\n     * Foo.prototype.c = _.constant('c');\n     *\n     * _.functionsIn(new Foo);\n     * // => ['a', 'b', 'c']\n     */\n    function functionsIn(object) {\n      return object == null ? [] : baseFunctions(object, keysIn(object));\n    }\n\n    /**\n     * Gets the value at `path` of `object`. If the resolved value is\n     * `undefined`, the `defaultValue` is returned in its place.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to get.\n     * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.get(object, 'a[0].b.c');\n     * // => 3\n     *\n     * _.get(object, ['a', '0', 'b', 'c']);\n     * // => 3\n     *\n     * _.get(object, 'a.b.c', 'default');\n     * // => 'default'\n     */\n    function get(object, path, defaultValue) {\n      var result = object == null ? undefined : baseGet(object, path);\n      return result === undefined ? defaultValue : result;\n    }\n\n    /**\n     * Checks if `path` is a direct property of `object`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @returns {boolean} Returns `true` if `path` exists, else `false`.\n     * @example\n     *\n     * var object = { 'a': { 'b': 2 } };\n     * var other = _.create({ 'a': _.create({ 'b': 2 }) });\n     *\n     * _.has(object, 'a');\n     * // => true\n     *\n     * _.has(object, 'a.b');\n     * // => true\n     *\n     * _.has(object, ['a', 'b']);\n     * // => true\n     *\n     * _.has(other, 'a');\n     * // => false\n     */\n    function has(object, path) {\n      return object != null && hasPath(object, path, baseHas);\n    }\n\n    /**\n     * Checks if `path` is a direct or inherited property of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @returns {boolean} Returns `true` if `path` exists, else `false`.\n     * @example\n     *\n     * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n     *\n     * _.hasIn(object, 'a');\n     * // => true\n     *\n     * _.hasIn(object, 'a.b');\n     * // => true\n     *\n     * _.hasIn(object, ['a', 'b']);\n     * // => true\n     *\n     * _.hasIn(object, 'b');\n     * // => false\n     */\n    function hasIn(object, path) {\n      return object != null && hasPath(object, path, baseHasIn);\n    }\n\n    /**\n     * Creates an object composed of the inverted keys and values of `object`.\n     * If `object` contains duplicate values, subsequent values overwrite\n     * property assignments of previous values.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.7.0\n     * @category Object\n     * @param {Object} object The object to invert.\n     * @returns {Object} Returns the new inverted object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2, 'c': 1 };\n     *\n     * _.invert(object);\n     * // => { '1': 'c', '2': 'b' }\n     */\n    var invert = createInverter(function(result, value, key) {\n      result[value] = key;\n    }, constant(identity));\n\n    /**\n     * This method is like `_.invert` except that the inverted object is generated\n     * from the results of running each element of `object` thru `iteratee`. The\n     * corresponding inverted value of each inverted key is an array of keys\n     * responsible for generating the inverted value. The iteratee is invoked\n     * with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.1.0\n     * @category Object\n     * @param {Object} object The object to invert.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Object} Returns the new inverted object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2, 'c': 1 };\n     *\n     * _.invertBy(object);\n     * // => { '1': ['a', 'c'], '2': ['b'] }\n     *\n     * _.invertBy(object, function(value) {\n     *   return 'group' + value;\n     * });\n     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }\n     */\n    var invertBy = createInverter(function(result, value, key) {\n      if (hasOwnProperty.call(result, value)) {\n        result[value].push(key);\n      } else {\n        result[value] = [key];\n      }\n    }, getIteratee);\n\n    /**\n     * Invokes the method at `path` of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {*} Returns the result of the invoked method.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };\n     *\n     * _.invoke(object, 'a[0].b.c.slice', 1, 3);\n     * // => [2, 3]\n     */\n    var invoke = baseRest(baseInvoke);\n\n    /**\n     * Creates an array of the own enumerable property names of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects. See the\n     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n     * for more details.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.keys(new Foo);\n     * // => ['a', 'b'] (iteration order is not guaranteed)\n     *\n     * _.keys('hi');\n     * // => ['0', '1']\n     */\n    function keys(object) {\n      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n    }\n\n    /**\n     * Creates an array of the own and inherited enumerable property names of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.keysIn(new Foo);\n     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n     */\n    function keysIn(object) {\n      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n    }\n\n    /**\n     * The opposite of `_.mapValues`; this method creates an object with the\n     * same values as `object` and keys generated by running each own enumerable\n     * string keyed property of `object` thru `iteratee`. The iteratee is invoked\n     * with three arguments: (value, key, object).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.8.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns the new mapped object.\n     * @see _.mapValues\n     * @example\n     *\n     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {\n     *   return key + value;\n     * });\n     * // => { 'a1': 1, 'b2': 2 }\n     */\n    function mapKeys(object, iteratee) {\n      var result = {};\n      iteratee = getIteratee(iteratee, 3);\n\n      baseForOwn(object, function(value, key, object) {\n        baseAssignValue(result, iteratee(value, key, object), value);\n      });\n      return result;\n    }\n\n    /**\n     * Creates an object with the same keys as `object` and values generated\n     * by running each own enumerable string keyed property of `object` thru\n     * `iteratee`. The iteratee is invoked with three arguments:\n     * (value, key, object).\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns the new mapped object.\n     * @see _.mapKeys\n     * @example\n     *\n     * var users = {\n     *   'fred':    { 'user': 'fred',    'age': 40 },\n     *   'pebbles': { 'user': 'pebbles', 'age': 1 }\n     * };\n     *\n     * _.mapValues(users, function(o) { return o.age; });\n     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.mapValues(users, 'age');\n     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n     */\n    function mapValues(object, iteratee) {\n      var result = {};\n      iteratee = getIteratee(iteratee, 3);\n\n      baseForOwn(object, function(value, key, object) {\n        baseAssignValue(result, key, iteratee(value, key, object));\n      });\n      return result;\n    }\n\n    /**\n     * This method is like `_.assign` except that it recursively merges own and\n     * inherited enumerable string keyed properties of source objects into the\n     * destination object. Source properties that resolve to `undefined` are\n     * skipped if a destination value exists. Array and plain object properties\n     * are merged recursively. Other objects and value types are overridden by\n     * assignment. Source objects are applied from left to right. Subsequent\n     * sources overwrite property assignments of previous sources.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.5.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = {\n     *   'a': [{ 'b': 2 }, { 'd': 4 }]\n     * };\n     *\n     * var other = {\n     *   'a': [{ 'c': 3 }, { 'e': 5 }]\n     * };\n     *\n     * _.merge(object, other);\n     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }\n     */\n    var merge = createAssigner(function(object, source, srcIndex) {\n      baseMerge(object, source, srcIndex);\n    });\n\n    /**\n     * This method is like `_.merge` except that it accepts `customizer` which\n     * is invoked to produce the merged values of the destination and source\n     * properties. If `customizer` returns `undefined`, merging is handled by the\n     * method instead. The `customizer` is invoked with six arguments:\n     * (objValue, srcValue, key, object, source, stack).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} sources The source objects.\n     * @param {Function} customizer The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * function customizer(objValue, srcValue) {\n     *   if (_.isArray(objValue)) {\n     *     return objValue.concat(srcValue);\n     *   }\n     * }\n     *\n     * var object = { 'a': [1], 'b': [2] };\n     * var other = { 'a': [3], 'b': [4] };\n     *\n     * _.mergeWith(object, other, customizer);\n     * // => { 'a': [1, 3], 'b': [2, 4] }\n     */\n    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n      baseMerge(object, source, srcIndex, customizer);\n    });\n\n    /**\n     * The opposite of `_.pick`; this method creates an object composed of the\n     * own and inherited enumerable property paths of `object` that are not omitted.\n     *\n     * **Note:** This method is considerably slower than `_.pick`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {...(string|string[])} [paths] The property paths to omit.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.omit(object, ['a', 'c']);\n     * // => { 'b': '2' }\n     */\n    var omit = flatRest(function(object, paths) {\n      var result = {};\n      if (object == null) {\n        return result;\n      }\n      var isDeep = false;\n      paths = arrayMap(paths, function(path) {\n        path = castPath(path, object);\n        isDeep || (isDeep = path.length > 1);\n        return path;\n      });\n      copyObject(object, getAllKeysIn(object), result);\n      if (isDeep) {\n        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);\n      }\n      var length = paths.length;\n      while (length--) {\n        baseUnset(result, paths[length]);\n      }\n      return result;\n    });\n\n    /**\n     * The opposite of `_.pickBy`; this method creates an object composed of\n     * the own and inherited enumerable string keyed properties of `object` that\n     * `predicate` doesn't return truthy for. The predicate is invoked with two\n     * arguments: (value, key).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {Function} [predicate=_.identity] The function invoked per property.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.omitBy(object, _.isNumber);\n     * // => { 'b': '2' }\n     */\n    function omitBy(object, predicate) {\n      return pickBy(object, negate(getIteratee(predicate)));\n    }\n\n    /**\n     * Creates an object composed of the picked `object` properties.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {...(string|string[])} [paths] The property paths to pick.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.pick(object, ['a', 'c']);\n     * // => { 'a': 1, 'c': 3 }\n     */\n    var pick = flatRest(function(object, paths) {\n      return object == null ? {} : basePick(object, paths);\n    });\n\n    /**\n     * Creates an object composed of the `object` properties `predicate` returns\n     * truthy for. The predicate is invoked with two arguments: (value, key).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {Function} [predicate=_.identity] The function invoked per property.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.pickBy(object, _.isNumber);\n     * // => { 'a': 1, 'c': 3 }\n     */\n    function pickBy(object, predicate) {\n      if (object == null) {\n        return {};\n      }\n      var props = arrayMap(getAllKeysIn(object), function(prop) {\n        return [prop];\n      });\n      predicate = getIteratee(predicate);\n      return basePickBy(object, props, function(value, path) {\n        return predicate(value, path[0]);\n      });\n    }\n\n    /**\n     * This method is like `_.get` except that if the resolved value is a\n     * function it's invoked with the `this` binding of its parent object and\n     * its result is returned.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to resolve.\n     * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };\n     *\n     * _.result(object, 'a[0].b.c1');\n     * // => 3\n     *\n     * _.result(object, 'a[0].b.c2');\n     * // => 4\n     *\n     * _.result(object, 'a[0].b.c3', 'default');\n     * // => 'default'\n     *\n     * _.result(object, 'a[0].b.c3', _.constant('default'));\n     * // => 'default'\n     */\n    function result(object, path, defaultValue) {\n      path = castPath(path, object);\n\n      var index = -1,\n          length = path.length;\n\n      // Ensure the loop is entered when path is empty.\n      if (!length) {\n        length = 1;\n        object = undefined;\n      }\n      while (++index < length) {\n        var value = object == null ? undefined : object[toKey(path[index])];\n        if (value === undefined) {\n          index = length;\n          value = defaultValue;\n        }\n        object = isFunction(value) ? value.call(object) : value;\n      }\n      return object;\n    }\n\n    /**\n     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n     * it's created. Arrays are created for missing index properties while objects\n     * are created for all other missing properties. Use `_.setWith` to customize\n     * `path` creation.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.set(object, 'a[0].b.c', 4);\n     * console.log(object.a[0].b.c);\n     * // => 4\n     *\n     * _.set(object, ['x', '0', 'y', 'z'], 5);\n     * console.log(object.x[0].y.z);\n     * // => 5\n     */\n    function set(object, path, value) {\n      return object == null ? object : baseSet(object, path, value);\n    }\n\n    /**\n     * This method is like `_.set` except that it accepts `customizer` which is\n     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`\n     * path creation is handled by the method instead. The `customizer` is invoked\n     * with three arguments: (nsValue, key, nsObject).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = {};\n     *\n     * _.setWith(object, '[0][1]', 'a', Object);\n     * // => { '0': { '1': 'a' } }\n     */\n    function setWith(object, path, value, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return object == null ? object : baseSet(object, path, value, customizer);\n    }\n\n    /**\n     * Creates an array of own enumerable string keyed-value pairs for `object`\n     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its\n     * entries are returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias entries\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the key-value pairs.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.toPairs(new Foo);\n     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)\n     */\n    var toPairs = createToPairs(keys);\n\n    /**\n     * Creates an array of own and inherited enumerable string keyed-value pairs\n     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map\n     * or set, its entries are returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias entriesIn\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the key-value pairs.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.toPairsIn(new Foo);\n     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)\n     */\n    var toPairsIn = createToPairs(keysIn);\n\n    /**\n     * An alternative to `_.reduce`; this method transforms `object` to a new\n     * `accumulator` object which is the result of running each of its own\n     * enumerable string keyed properties thru `iteratee`, with each invocation\n     * potentially mutating the `accumulator` object. If `accumulator` is not\n     * provided, a new object with the same `[[Prototype]]` will be used. The\n     * iteratee is invoked with four arguments: (accumulator, value, key, object).\n     * Iteratee functions may exit iteration early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.3.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The custom accumulator value.\n     * @returns {*} Returns the accumulated value.\n     * @example\n     *\n     * _.transform([2, 3, 4], function(result, n) {\n     *   result.push(n *= n);\n     *   return n % 2 == 0;\n     * }, []);\n     * // => [4, 9]\n     *\n     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n     *   (result[value] || (result[value] = [])).push(key);\n     * }, {});\n     * // => { '1': ['a', 'c'], '2': ['b'] }\n     */\n    function transform(object, iteratee, accumulator) {\n      var isArr = isArray(object),\n          isArrLike = isArr || isBuffer(object) || isTypedArray(object);\n\n      iteratee = getIteratee(iteratee, 4);\n      if (accumulator == null) {\n        var Ctor = object && object.constructor;\n        if (isArrLike) {\n          accumulator = isArr ? new Ctor : [];\n        }\n        else if (isObject(object)) {\n          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};\n        }\n        else {\n          accumulator = {};\n        }\n      }\n      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {\n        return iteratee(accumulator, value, index, object);\n      });\n      return accumulator;\n    }\n\n    /**\n     * Removes the property at `path` of `object`.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to unset.\n     * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 7 } }] };\n     * _.unset(object, 'a[0].b.c');\n     * // => true\n     *\n     * console.log(object);\n     * // => { 'a': [{ 'b': {} }] };\n     *\n     * _.unset(object, ['a', '0', 'b', 'c']);\n     * // => true\n     *\n     * console.log(object);\n     * // => { 'a': [{ 'b': {} }] };\n     */\n    function unset(object, path) {\n      return object == null ? true : baseUnset(object, path);\n    }\n\n    /**\n     * This method is like `_.set` except that accepts `updater` to produce the\n     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`\n     * is invoked with one argument: (value).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.6.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {Function} updater The function to produce the updated value.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.update(object, 'a[0].b.c', function(n) { return n * n; });\n     * console.log(object.a[0].b.c);\n     * // => 9\n     *\n     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });\n     * console.log(object.x[0].y.z);\n     * // => 0\n     */\n    function update(object, path, updater) {\n      return object == null ? object : baseUpdate(object, path, castFunction(updater));\n    }\n\n    /**\n     * This method is like `_.update` except that it accepts `customizer` which is\n     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`\n     * path creation is handled by the method instead. The `customizer` is invoked\n     * with three arguments: (nsValue, key, nsObject).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.6.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {Function} updater The function to produce the updated value.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = {};\n     *\n     * _.updateWith(object, '[0][1]', _.constant('a'), Object);\n     * // => { '0': { '1': 'a' } }\n     */\n    function updateWith(object, path, updater, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);\n    }\n\n    /**\n     * Creates an array of the own enumerable string keyed property values of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property values.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.values(new Foo);\n     * // => [1, 2] (iteration order is not guaranteed)\n     *\n     * _.values('hi');\n     * // => ['h', 'i']\n     */\n    function values(object) {\n      return object == null ? [] : baseValues(object, keys(object));\n    }\n\n    /**\n     * Creates an array of the own and inherited enumerable string keyed property\n     * values of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property values.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.valuesIn(new Foo);\n     * // => [1, 2, 3] (iteration order is not guaranteed)\n     */\n    function valuesIn(object) {\n      return object == null ? [] : baseValues(object, keysIn(object));\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Clamps `number` within the inclusive `lower` and `upper` bounds.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Number\n     * @param {number} number The number to clamp.\n     * @param {number} [lower] The lower bound.\n     * @param {number} upper The upper bound.\n     * @returns {number} Returns the clamped number.\n     * @example\n     *\n     * _.clamp(-10, -5, 5);\n     * // => -5\n     *\n     * _.clamp(10, -5, 5);\n     * // => 5\n     */\n    function clamp(number, lower, upper) {\n      if (upper === undefined) {\n        upper = lower;\n        lower = undefined;\n      }\n      if (upper !== undefined) {\n        upper = toNumber(upper);\n        upper = upper === upper ? upper : 0;\n      }\n      if (lower !== undefined) {\n        lower = toNumber(lower);\n        lower = lower === lower ? lower : 0;\n      }\n      return baseClamp(toNumber(number), lower, upper);\n    }\n\n    /**\n     * Checks if `n` is between `start` and up to, but not including, `end`. If\n     * `end` is not specified, it's set to `start` with `start` then set to `0`.\n     * If `start` is greater than `end` the params are swapped to support\n     * negative ranges.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.3.0\n     * @category Number\n     * @param {number} number The number to check.\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n     * @see _.range, _.rangeRight\n     * @example\n     *\n     * _.inRange(3, 2, 4);\n     * // => true\n     *\n     * _.inRange(4, 8);\n     * // => true\n     *\n     * _.inRange(4, 2);\n     * // => false\n     *\n     * _.inRange(2, 2);\n     * // => false\n     *\n     * _.inRange(1.2, 2);\n     * // => true\n     *\n     * _.inRange(5.2, 4);\n     * // => false\n     *\n     * _.inRange(-3, -2, -6);\n     * // => true\n     */\n    function inRange(number, start, end) {\n      start = toFinite(start);\n      if (end === undefined) {\n        end = start;\n        start = 0;\n      } else {\n        end = toFinite(end);\n      }\n      number = toNumber(number);\n      return baseInRange(number, start, end);\n    }\n\n    /**\n     * Produces a random number between the inclusive `lower` and `upper` bounds.\n     * If only one argument is provided a number between `0` and the given number\n     * is returned. If `floating` is `true`, or either `lower` or `upper` are\n     * floats, a floating-point number is returned instead of an integer.\n     *\n     * **Note:** JavaScript follows the IEEE-754 standard for resolving\n     * floating-point values which can produce unexpected results.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.7.0\n     * @category Number\n     * @param {number} [lower=0] The lower bound.\n     * @param {number} [upper=1] The upper bound.\n     * @param {boolean} [floating] Specify returning a floating-point number.\n     * @returns {number} Returns the random number.\n     * @example\n     *\n     * _.random(0, 5);\n     * // => an integer between 0 and 5\n     *\n     * _.random(5);\n     * // => also an integer between 0 and 5\n     *\n     * _.random(5, true);\n     * // => a floating-point number between 0 and 5\n     *\n     * _.random(1.2, 5.2);\n     * // => a floating-point number between 1.2 and 5.2\n     */\n    function random(lower, upper, floating) {\n      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {\n        upper = floating = undefined;\n      }\n      if (floating === undefined) {\n        if (typeof upper == 'boolean') {\n          floating = upper;\n          upper = undefined;\n        }\n        else if (typeof lower == 'boolean') {\n          floating = lower;\n          lower = undefined;\n        }\n      }\n      if (lower === undefined && upper === undefined) {\n        lower = 0;\n        upper = 1;\n      }\n      else {\n        lower = toFinite(lower);\n        if (upper === undefined) {\n          upper = lower;\n          lower = 0;\n        } else {\n          upper = toFinite(upper);\n        }\n      }\n      if (lower > upper) {\n        var temp = lower;\n        lower = upper;\n        upper = temp;\n      }\n      if (floating || lower % 1 || upper % 1) {\n        var rand = nativeRandom();\n        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);\n      }\n      return baseRandom(lower, upper);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the camel cased string.\n     * @example\n     *\n     * _.camelCase('Foo Bar');\n     * // => 'fooBar'\n     *\n     * _.camelCase('--foo-bar--');\n     * // => 'fooBar'\n     *\n     * _.camelCase('__FOO_BAR__');\n     * // => 'fooBar'\n     */\n    var camelCase = createCompounder(function(result, word, index) {\n      word = word.toLowerCase();\n      return result + (index ? capitalize(word) : word);\n    });\n\n    /**\n     * Converts the first character of `string` to upper case and the remaining\n     * to lower case.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to capitalize.\n     * @returns {string} Returns the capitalized string.\n     * @example\n     *\n     * _.capitalize('FRED');\n     * // => 'Fred'\n     */\n    function capitalize(string) {\n      return upperFirst(toString(string).toLowerCase());\n    }\n\n    /**\n     * Deburrs `string` by converting\n     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n     * letters to basic Latin letters and removing\n     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to deburr.\n     * @returns {string} Returns the deburred string.\n     * @example\n     *\n     * _.deburr('déjà vu');\n     * // => 'deja vu'\n     */\n    function deburr(string) {\n      string = toString(string);\n      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');\n    }\n\n    /**\n     * Checks if `string` ends with the given target string.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {string} [target] The string to search for.\n     * @param {number} [position=string.length] The position to search up to.\n     * @returns {boolean} Returns `true` if `string` ends with `target`,\n     *  else `false`.\n     * @example\n     *\n     * _.endsWith('abc', 'c');\n     * // => true\n     *\n     * _.endsWith('abc', 'b');\n     * // => false\n     *\n     * _.endsWith('abc', 'b', 2);\n     * // => true\n     */\n    function endsWith(string, target, position) {\n      string = toString(string);\n      target = baseToString(target);\n\n      var length = string.length;\n      position = position === undefined\n        ? length\n        : baseClamp(toInteger(position), 0, length);\n\n      var end = position;\n      position -= target.length;\n      return position >= 0 && string.slice(position, end) == target;\n    }\n\n    /**\n     * Converts the characters \"&\", \"<\", \">\", '\"', and \"'\" in `string` to their\n     * corresponding HTML entities.\n     *\n     * **Note:** No other characters are escaped. To escape additional\n     * characters use a third-party library like [_he_](https://mths.be/he).\n     *\n     * Though the \">\" character is escaped for symmetry, characters like\n     * \">\" and \"/\" don't need escaping in HTML and have no special meaning\n     * unless they're part of a tag or unquoted attribute value. See\n     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)\n     * (under \"semi-related fun fact\") for more details.\n     *\n     * When working with HTML you should always\n     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce\n     * XSS vectors.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to escape.\n     * @returns {string} Returns the escaped string.\n     * @example\n     *\n     * _.escape('fred, barney, & pebbles');\n     * // => 'fred, barney, &amp; pebbles'\n     */\n    function escape(string) {\n      string = toString(string);\n      return (string && reHasUnescapedHtml.test(string))\n        ? string.replace(reUnescapedHtml, escapeHtmlChar)\n        : string;\n    }\n\n    /**\n     * Escapes the `RegExp` special characters \"^\", \"$\", \"\\\", \".\", \"*\", \"+\",\n     * \"?\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\", and \"|\" in `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to escape.\n     * @returns {string} Returns the escaped string.\n     * @example\n     *\n     * _.escapeRegExp('[lodash](https://lodash.com/)');\n     * // => '\\[lodash\\]\\(https://lodash\\.com/\\)'\n     */\n    function escapeRegExp(string) {\n      string = toString(string);\n      return (string && reHasRegExpChar.test(string))\n        ? string.replace(reRegExpChar, '\\\\$&')\n        : string;\n    }\n\n    /**\n     * Converts `string` to\n     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the kebab cased string.\n     * @example\n     *\n     * _.kebabCase('Foo Bar');\n     * // => 'foo-bar'\n     *\n     * _.kebabCase('fooBar');\n     * // => 'foo-bar'\n     *\n     * _.kebabCase('__FOO_BAR__');\n     * // => 'foo-bar'\n     */\n    var kebabCase = createCompounder(function(result, word, index) {\n      return result + (index ? '-' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Converts `string`, as space separated words, to lower case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the lower cased string.\n     * @example\n     *\n     * _.lowerCase('--Foo-Bar--');\n     * // => 'foo bar'\n     *\n     * _.lowerCase('fooBar');\n     * // => 'foo bar'\n     *\n     * _.lowerCase('__FOO_BAR__');\n     * // => 'foo bar'\n     */\n    var lowerCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Converts the first character of `string` to lower case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the converted string.\n     * @example\n     *\n     * _.lowerFirst('Fred');\n     * // => 'fred'\n     *\n     * _.lowerFirst('FRED');\n     * // => 'fRED'\n     */\n    var lowerFirst = createCaseFirst('toLowerCase');\n\n    /**\n     * Pads `string` on the left and right sides if it's shorter than `length`.\n     * Padding characters are truncated if they can't be evenly divided by `length`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.pad('abc', 8);\n     * // => '  abc   '\n     *\n     * _.pad('abc', 8, '_-');\n     * // => '_-abc_-_'\n     *\n     * _.pad('abc', 3);\n     * // => 'abc'\n     */\n    function pad(string, length, chars) {\n      string = toString(string);\n      length = toInteger(length);\n\n      var strLength = length ? stringSize(string) : 0;\n      if (!length || strLength >= length) {\n        return string;\n      }\n      var mid = (length - strLength) / 2;\n      return (\n        createPadding(nativeFloor(mid), chars) +\n        string +\n        createPadding(nativeCeil(mid), chars)\n      );\n    }\n\n    /**\n     * Pads `string` on the right side if it's shorter than `length`. Padding\n     * characters are truncated if they exceed `length`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.padEnd('abc', 6);\n     * // => 'abc   '\n     *\n     * _.padEnd('abc', 6, '_-');\n     * // => 'abc_-_'\n     *\n     * _.padEnd('abc', 3);\n     * // => 'abc'\n     */\n    function padEnd(string, length, chars) {\n      string = toString(string);\n      length = toInteger(length);\n\n      var strLength = length ? stringSize(string) : 0;\n      return (length && strLength < length)\n        ? (string + createPadding(length - strLength, chars))\n        : string;\n    }\n\n    /**\n     * Pads `string` on the left side if it's shorter than `length`. Padding\n     * characters are truncated if they exceed `length`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.padStart('abc', 6);\n     * // => '   abc'\n     *\n     * _.padStart('abc', 6, '_-');\n     * // => '_-_abc'\n     *\n     * _.padStart('abc', 3);\n     * // => 'abc'\n     */\n    function padStart(string, length, chars) {\n      string = toString(string);\n      length = toInteger(length);\n\n      var strLength = length ? stringSize(string) : 0;\n      return (length && strLength < length)\n        ? (createPadding(length - strLength, chars) + string)\n        : string;\n    }\n\n    /**\n     * Converts `string` to an integer of the specified radix. If `radix` is\n     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a\n     * hexadecimal, in which case a `radix` of `16` is used.\n     *\n     * **Note:** This method aligns with the\n     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.1.0\n     * @category String\n     * @param {string} string The string to convert.\n     * @param {number} [radix=10] The radix to interpret `value` by.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.parseInt('08');\n     * // => 8\n     *\n     * _.map(['6', '08', '10'], _.parseInt);\n     * // => [6, 8, 10]\n     */\n    function parseInt(string, radix, guard) {\n      if (guard || radix == null) {\n        radix = 0;\n      } else if (radix) {\n        radix = +radix;\n      }\n      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);\n    }\n\n    /**\n     * Repeats the given string `n` times.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to repeat.\n     * @param {number} [n=1] The number of times to repeat the string.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the repeated string.\n     * @example\n     *\n     * _.repeat('*', 3);\n     * // => '***'\n     *\n     * _.repeat('abc', 2);\n     * // => 'abcabc'\n     *\n     * _.repeat('abc', 0);\n     * // => ''\n     */\n    function repeat(string, n, guard) {\n      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {\n        n = 1;\n      } else {\n        n = toInteger(n);\n      }\n      return baseRepeat(toString(string), n);\n    }\n\n    /**\n     * Replaces matches for `pattern` in `string` with `replacement`.\n     *\n     * **Note:** This method is based on\n     * [`String#replace`](https://mdn.io/String/replace).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to modify.\n     * @param {RegExp|string} pattern The pattern to replace.\n     * @param {Function|string} replacement The match replacement.\n     * @returns {string} Returns the modified string.\n     * @example\n     *\n     * _.replace('Hi Fred', 'Fred', 'Barney');\n     * // => 'Hi Barney'\n     */\n    function replace() {\n      var args = arguments,\n          string = toString(args[0]);\n\n      return args.length < 3 ? string : string.replace(args[1], args[2]);\n    }\n\n    /**\n     * Converts `string` to\n     * [snake case](https://en.wikipedia.org/wiki/Snake_case).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the snake cased string.\n     * @example\n     *\n     * _.snakeCase('Foo Bar');\n     * // => 'foo_bar'\n     *\n     * _.snakeCase('fooBar');\n     * // => 'foo_bar'\n     *\n     * _.snakeCase('--FOO-BAR--');\n     * // => 'foo_bar'\n     */\n    var snakeCase = createCompounder(function(result, word, index) {\n      return result + (index ? '_' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Splits `string` by `separator`.\n     *\n     * **Note:** This method is based on\n     * [`String#split`](https://mdn.io/String/split).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to split.\n     * @param {RegExp|string} separator The separator pattern to split by.\n     * @param {number} [limit] The length to truncate results to.\n     * @returns {Array} Returns the string segments.\n     * @example\n     *\n     * _.split('a-b-c', '-', 2);\n     * // => ['a', 'b']\n     */\n    function split(string, separator, limit) {\n      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {\n        separator = limit = undefined;\n      }\n      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;\n      if (!limit) {\n        return [];\n      }\n      string = toString(string);\n      if (string && (\n            typeof separator == 'string' ||\n            (separator != null && !isRegExp(separator))\n          )) {\n        separator = baseToString(separator);\n        if (!separator && hasUnicode(string)) {\n          return castSlice(stringToArray(string), 0, limit);\n        }\n      }\n      return string.split(separator, limit);\n    }\n\n    /**\n     * Converts `string` to\n     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.1.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the start cased string.\n     * @example\n     *\n     * _.startCase('--foo-bar--');\n     * // => 'Foo Bar'\n     *\n     * _.startCase('fooBar');\n     * // => 'Foo Bar'\n     *\n     * _.startCase('__FOO_BAR__');\n     * // => 'FOO BAR'\n     */\n    var startCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + upperFirst(word);\n    });\n\n    /**\n     * Checks if `string` starts with the given target string.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {string} [target] The string to search for.\n     * @param {number} [position=0] The position to search from.\n     * @returns {boolean} Returns `true` if `string` starts with `target`,\n     *  else `false`.\n     * @example\n     *\n     * _.startsWith('abc', 'a');\n     * // => true\n     *\n     * _.startsWith('abc', 'b');\n     * // => false\n     *\n     * _.startsWith('abc', 'b', 1);\n     * // => true\n     */\n    function startsWith(string, target, position) {\n      string = toString(string);\n      position = position == null\n        ? 0\n        : baseClamp(toInteger(position), 0, string.length);\n\n      target = baseToString(target);\n      return string.slice(position, position + target.length) == target;\n    }\n\n    /**\n     * Creates a compiled template function that can interpolate data properties\n     * in \"interpolate\" delimiters, HTML-escape interpolated data properties in\n     * \"escape\" delimiters, and execute JavaScript in \"evaluate\" delimiters. Data\n     * properties may be accessed as free variables in the template. If a setting\n     * object is given, it takes precedence over `_.templateSettings` values.\n     *\n     * **Note:** In the development build `_.template` utilizes\n     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)\n     * for easier debugging.\n     *\n     * For more information on precompiling templates see\n     * [lodash's custom builds documentation](https://lodash.com/custom-builds).\n     *\n     * For more information on Chrome extension sandboxes see\n     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The template string.\n     * @param {Object} [options={}] The options object.\n     * @param {RegExp} [options.escape=_.templateSettings.escape]\n     *  The HTML \"escape\" delimiter.\n     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]\n     *  The \"evaluate\" delimiter.\n     * @param {Object} [options.imports=_.templateSettings.imports]\n     *  An object to import into the template as free variables.\n     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]\n     *  The \"interpolate\" delimiter.\n     * @param {string} [options.sourceURL='lodash.templateSources[n]']\n     *  The sourceURL of the compiled template.\n     * @param {string} [options.variable='obj']\n     *  The data object variable name.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the compiled template function.\n     * @example\n     *\n     * // Use the \"interpolate\" delimiter to create a compiled template.\n     * var compiled = _.template('hello <%= user %>!');\n     * compiled({ 'user': 'fred' });\n     * // => 'hello fred!'\n     *\n     * // Use the HTML \"escape\" delimiter to escape data property values.\n     * var compiled = _.template('<b><%- value %></b>');\n     * compiled({ 'value': '<script>' });\n     * // => '<b>&lt;script&gt;</b>'\n     *\n     * // Use the \"evaluate\" delimiter to execute JavaScript and generate HTML.\n     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');\n     * compiled({ 'users': ['fred', 'barney'] });\n     * // => '<li>fred</li><li>barney</li>'\n     *\n     * // Use the internal `print` function in \"evaluate\" delimiters.\n     * var compiled = _.template('<% print(\"hello \" + user); %>!');\n     * compiled({ 'user': 'barney' });\n     * // => 'hello barney!'\n     *\n     * // Use the ES template literal delimiter as an \"interpolate\" delimiter.\n     * // Disable support by replacing the \"interpolate\" delimiter.\n     * var compiled = _.template('hello ${ user }!');\n     * compiled({ 'user': 'pebbles' });\n     * // => 'hello pebbles!'\n     *\n     * // Use backslashes to treat delimiters as plain text.\n     * var compiled = _.template('<%= \"\\\\<%- value %\\\\>\" %>');\n     * compiled({ 'value': 'ignored' });\n     * // => '<%- value %>'\n     *\n     * // Use the `imports` option to import `jQuery` as `jq`.\n     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';\n     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });\n     * compiled({ 'users': ['fred', 'barney'] });\n     * // => '<li>fred</li><li>barney</li>'\n     *\n     * // Use the `sourceURL` option to specify a custom sourceURL for the template.\n     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });\n     * compiled(data);\n     * // => Find the source of \"greeting.jst\" under the Sources tab or Resources panel of the web inspector.\n     *\n     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.\n     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });\n     * compiled.source;\n     * // => function(data) {\n     * //   var __t, __p = '';\n     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';\n     * //   return __p;\n     * // }\n     *\n     * // Use custom template delimiters.\n     * _.templateSettings.interpolate = /{{([\\s\\S]+?)}}/g;\n     * var compiled = _.template('hello {{ user }}!');\n     * compiled({ 'user': 'mustache' });\n     * // => 'hello mustache!'\n     *\n     * // Use the `source` property to inline compiled templates for meaningful\n     * // line numbers in error messages and stack traces.\n     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\\\n     *   var JST = {\\\n     *     \"main\": ' + _.template(mainText).source + '\\\n     *   };\\\n     * ');\n     */\n    function template(string, options, guard) {\n      // Based on John Resig's `tmpl` implementation\n      // (http://ejohn.org/blog/javascript-micro-templating/)\n      // and Laura Doktorova's doT.js (https://github.com/olado/doT).\n      var settings = lodash.templateSettings;\n\n      if (guard && isIterateeCall(string, options, guard)) {\n        options = undefined;\n      }\n      string = toString(string);\n      options = assignInWith({}, options, settings, customDefaultsAssignIn);\n\n      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),\n          importsKeys = keys(imports),\n          importsValues = baseValues(imports, importsKeys);\n\n      var isEscaping,\n          isEvaluating,\n          index = 0,\n          interpolate = options.interpolate || reNoMatch,\n          source = \"__p += '\";\n\n      // Compile the regexp to match each delimiter.\n      var reDelimiters = RegExp(\n        (options.escape || reNoMatch).source + '|' +\n        interpolate.source + '|' +\n        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +\n        (options.evaluate || reNoMatch).source + '|$'\n      , 'g');\n\n      // Use a sourceURL for easier debugging.\n      var sourceURL = '//# sourceURL=' +\n        ('sourceURL' in options\n          ? options.sourceURL\n          : ('lodash.templateSources[' + (++templateCounter) + ']')\n        ) + '\\n';\n\n      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {\n        interpolateValue || (interpolateValue = esTemplateValue);\n\n        // Escape characters that can't be included in string literals.\n        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);\n\n        // Replace delimiters with snippets.\n        if (escapeValue) {\n          isEscaping = true;\n          source += \"' +\\n__e(\" + escapeValue + \") +\\n'\";\n        }\n        if (evaluateValue) {\n          isEvaluating = true;\n          source += \"';\\n\" + evaluateValue + \";\\n__p += '\";\n        }\n        if (interpolateValue) {\n          source += \"' +\\n((__t = (\" + interpolateValue + \")) == null ? '' : __t) +\\n'\";\n        }\n        index = offset + match.length;\n\n        // The JS engine embedded in Adobe products needs `match` returned in\n        // order to produce the correct `offset` value.\n        return match;\n      });\n\n      source += \"';\\n\";\n\n      // If `variable` is not specified wrap a with-statement around the generated\n      // code to add the data object to the top of the scope chain.\n      var variable = options.variable;\n      if (!variable) {\n        source = 'with (obj) {\\n' + source + '\\n}\\n';\n      }\n      // Cleanup code by stripping empty strings.\n      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)\n        .replace(reEmptyStringMiddle, '$1')\n        .replace(reEmptyStringTrailing, '$1;');\n\n      // Frame code as the function body.\n      source = 'function(' + (variable || 'obj') + ') {\\n' +\n        (variable\n          ? ''\n          : 'obj || (obj = {});\\n'\n        ) +\n        \"var __t, __p = ''\" +\n        (isEscaping\n           ? ', __e = _.escape'\n           : ''\n        ) +\n        (isEvaluating\n          ? ', __j = Array.prototype.join;\\n' +\n            \"function print() { __p += __j.call(arguments, '') }\\n\"\n          : ';\\n'\n        ) +\n        source +\n        'return __p\\n}';\n\n      var result = attempt(function() {\n        return Function(importsKeys, sourceURL + 'return ' + source)\n          .apply(undefined, importsValues);\n      });\n\n      // Provide the compiled function's source by its `toString` method or\n      // the `source` property as a convenience for inlining compiled templates.\n      result.source = source;\n      if (isError(result)) {\n        throw result;\n      }\n      return result;\n    }\n\n    /**\n     * Converts `string`, as a whole, to lower case just like\n     * [String#toLowerCase](https://mdn.io/toLowerCase).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the lower cased string.\n     * @example\n     *\n     * _.toLower('--Foo-Bar--');\n     * // => '--foo-bar--'\n     *\n     * _.toLower('fooBar');\n     * // => 'foobar'\n     *\n     * _.toLower('__FOO_BAR__');\n     * // => '__foo_bar__'\n     */\n    function toLower(value) {\n      return toString(value).toLowerCase();\n    }\n\n    /**\n     * Converts `string`, as a whole, to upper case just like\n     * [String#toUpperCase](https://mdn.io/toUpperCase).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the upper cased string.\n     * @example\n     *\n     * _.toUpper('--foo-bar--');\n     * // => '--FOO-BAR--'\n     *\n     * _.toUpper('fooBar');\n     * // => 'FOOBAR'\n     *\n     * _.toUpper('__foo_bar__');\n     * // => '__FOO_BAR__'\n     */\n    function toUpper(value) {\n      return toString(value).toUpperCase();\n    }\n\n    /**\n     * Removes leading and trailing whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trim('  abc  ');\n     * // => 'abc'\n     *\n     * _.trim('-_-abc-_-', '_-');\n     * // => 'abc'\n     *\n     * _.map(['  foo  ', '  bar  '], _.trim);\n     * // => ['foo', 'bar']\n     */\n    function trim(string, chars, guard) {\n      string = toString(string);\n      if (string && (guard || chars === undefined)) {\n        return string.replace(reTrim, '');\n      }\n      if (!string || !(chars = baseToString(chars))) {\n        return string;\n      }\n      var strSymbols = stringToArray(string),\n          chrSymbols = stringToArray(chars),\n          start = charsStartIndex(strSymbols, chrSymbols),\n          end = charsEndIndex(strSymbols, chrSymbols) + 1;\n\n      return castSlice(strSymbols, start, end).join('');\n    }\n\n    /**\n     * Removes trailing whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trimEnd('  abc  ');\n     * // => '  abc'\n     *\n     * _.trimEnd('-_-abc-_-', '_-');\n     * // => '-_-abc'\n     */\n    function trimEnd(string, chars, guard) {\n      string = toString(string);\n      if (string && (guard || chars === undefined)) {\n        return string.replace(reTrimEnd, '');\n      }\n      if (!string || !(chars = baseToString(chars))) {\n        return string;\n      }\n      var strSymbols = stringToArray(string),\n          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;\n\n      return castSlice(strSymbols, 0, end).join('');\n    }\n\n    /**\n     * Removes leading whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trimStart('  abc  ');\n     * // => 'abc  '\n     *\n     * _.trimStart('-_-abc-_-', '_-');\n     * // => 'abc-_-'\n     */\n    function trimStart(string, chars, guard) {\n      string = toString(string);\n      if (string && (guard || chars === undefined)) {\n        return string.replace(reTrimStart, '');\n      }\n      if (!string || !(chars = baseToString(chars))) {\n        return string;\n      }\n      var strSymbols = stringToArray(string),\n          start = charsStartIndex(strSymbols, stringToArray(chars));\n\n      return castSlice(strSymbols, start).join('');\n    }\n\n    /**\n     * Truncates `string` if it's longer than the given maximum string length.\n     * The last characters of the truncated string are replaced with the omission\n     * string which defaults to \"...\".\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to truncate.\n     * @param {Object} [options={}] The options object.\n     * @param {number} [options.length=30] The maximum string length.\n     * @param {string} [options.omission='...'] The string to indicate text is omitted.\n     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.\n     * @returns {string} Returns the truncated string.\n     * @example\n     *\n     * _.truncate('hi-diddly-ho there, neighborino');\n     * // => 'hi-diddly-ho there, neighbo...'\n     *\n     * _.truncate('hi-diddly-ho there, neighborino', {\n     *   'length': 24,\n     *   'separator': ' '\n     * });\n     * // => 'hi-diddly-ho there,...'\n     *\n     * _.truncate('hi-diddly-ho there, neighborino', {\n     *   'length': 24,\n     *   'separator': /,? +/\n     * });\n     * // => 'hi-diddly-ho there...'\n     *\n     * _.truncate('hi-diddly-ho there, neighborino', {\n     *   'omission': ' [...]'\n     * });\n     * // => 'hi-diddly-ho there, neig [...]'\n     */\n    function truncate(string, options) {\n      var length = DEFAULT_TRUNC_LENGTH,\n          omission = DEFAULT_TRUNC_OMISSION;\n\n      if (isObject(options)) {\n        var separator = 'separator' in options ? options.separator : separator;\n        length = 'length' in options ? toInteger(options.length) : length;\n        omission = 'omission' in options ? baseToString(options.omission) : omission;\n      }\n      string = toString(string);\n\n      var strLength = string.length;\n      if (hasUnicode(string)) {\n        var strSymbols = stringToArray(string);\n        strLength = strSymbols.length;\n      }\n      if (length >= strLength) {\n        return string;\n      }\n      var end = length - stringSize(omission);\n      if (end < 1) {\n        return omission;\n      }\n      var result = strSymbols\n        ? castSlice(strSymbols, 0, end).join('')\n        : string.slice(0, end);\n\n      if (separator === undefined) {\n        return result + omission;\n      }\n      if (strSymbols) {\n        end += (result.length - end);\n      }\n      if (isRegExp(separator)) {\n        if (string.slice(end).search(separator)) {\n          var match,\n              substring = result;\n\n          if (!separator.global) {\n            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');\n          }\n          separator.lastIndex = 0;\n          while ((match = separator.exec(substring))) {\n            var newEnd = match.index;\n          }\n          result = result.slice(0, newEnd === undefined ? end : newEnd);\n        }\n      } else if (string.indexOf(baseToString(separator), end) != end) {\n        var index = result.lastIndexOf(separator);\n        if (index > -1) {\n          result = result.slice(0, index);\n        }\n      }\n      return result + omission;\n    }\n\n    /**\n     * The inverse of `_.escape`; this method converts the HTML entities\n     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to\n     * their corresponding characters.\n     *\n     * **Note:** No other HTML entities are unescaped. To unescape additional\n     * HTML entities use a third-party library like [_he_](https://mths.be/he).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.6.0\n     * @category String\n     * @param {string} [string=''] The string to unescape.\n     * @returns {string} Returns the unescaped string.\n     * @example\n     *\n     * _.unescape('fred, barney, &amp; pebbles');\n     * // => 'fred, barney, & pebbles'\n     */\n    function unescape(string) {\n      string = toString(string);\n      return (string && reHasEscapedHtml.test(string))\n        ? string.replace(reEscapedHtml, unescapeHtmlChar)\n        : string;\n    }\n\n    /**\n     * Converts `string`, as space separated words, to upper case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the upper cased string.\n     * @example\n     *\n     * _.upperCase('--foo-bar');\n     * // => 'FOO BAR'\n     *\n     * _.upperCase('fooBar');\n     * // => 'FOO BAR'\n     *\n     * _.upperCase('__foo_bar__');\n     * // => 'FOO BAR'\n     */\n    var upperCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + word.toUpperCase();\n    });\n\n    /**\n     * Converts the first character of `string` to upper case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the converted string.\n     * @example\n     *\n     * _.upperFirst('fred');\n     * // => 'Fred'\n     *\n     * _.upperFirst('FRED');\n     * // => 'FRED'\n     */\n    var upperFirst = createCaseFirst('toUpperCase');\n\n    /**\n     * Splits `string` into an array of its words.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {RegExp|string} [pattern] The pattern to match words.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the words of `string`.\n     * @example\n     *\n     * _.words('fred, barney, & pebbles');\n     * // => ['fred', 'barney', 'pebbles']\n     *\n     * _.words('fred, barney, & pebbles', /[^, ]+/g);\n     * // => ['fred', 'barney', '&', 'pebbles']\n     */\n    function words(string, pattern, guard) {\n      string = toString(string);\n      pattern = guard ? undefined : pattern;\n\n      if (pattern === undefined) {\n        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);\n      }\n      return string.match(pattern) || [];\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Attempts to invoke `func`, returning either the result or the caught error\n     * object. Any additional arguments are provided to `func` when it's invoked.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {Function} func The function to attempt.\n     * @param {...*} [args] The arguments to invoke `func` with.\n     * @returns {*} Returns the `func` result or error object.\n     * @example\n     *\n     * // Avoid throwing errors for invalid selectors.\n     * var elements = _.attempt(function(selector) {\n     *   return document.querySelectorAll(selector);\n     * }, '>_>');\n     *\n     * if (_.isError(elements)) {\n     *   elements = [];\n     * }\n     */\n    var attempt = baseRest(function(func, args) {\n      try {\n        return apply(func, undefined, args);\n      } catch (e) {\n        return isError(e) ? e : new Error(e);\n      }\n    });\n\n    /**\n     * Binds methods of an object to the object itself, overwriting the existing\n     * method.\n     *\n     * **Note:** This method doesn't set the \"length\" property of bound functions.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {Object} object The object to bind and assign the bound methods to.\n     * @param {...(string|string[])} methodNames The object method names to bind.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var view = {\n     *   'label': 'docs',\n     *   'click': function() {\n     *     console.log('clicked ' + this.label);\n     *   }\n     * };\n     *\n     * _.bindAll(view, ['click']);\n     * jQuery(element).on('click', view.click);\n     * // => Logs 'clicked docs' when clicked.\n     */\n    var bindAll = flatRest(function(object, methodNames) {\n      arrayEach(methodNames, function(key) {\n        key = toKey(key);\n        baseAssignValue(object, key, bind(object[key], object));\n      });\n      return object;\n    });\n\n    /**\n     * Creates a function that iterates over `pairs` and invokes the corresponding\n     * function of the first predicate to return truthy. The predicate-function\n     * pairs are invoked with the `this` binding and arguments of the created\n     * function.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {Array} pairs The predicate-function pairs.\n     * @returns {Function} Returns the new composite function.\n     * @example\n     *\n     * var func = _.cond([\n     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],\n     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],\n     *   [_.stubTrue,                      _.constant('no match')]\n     * ]);\n     *\n     * func({ 'a': 1, 'b': 2 });\n     * // => 'matches A'\n     *\n     * func({ 'a': 0, 'b': 1 });\n     * // => 'matches B'\n     *\n     * func({ 'a': '1', 'b': '2' });\n     * // => 'no match'\n     */\n    function cond(pairs) {\n      var length = pairs == null ? 0 : pairs.length,\n          toIteratee = getIteratee();\n\n      pairs = !length ? [] : arrayMap(pairs, function(pair) {\n        if (typeof pair[1] != 'function') {\n          throw new TypeError(FUNC_ERROR_TEXT);\n        }\n        return [toIteratee(pair[0]), pair[1]];\n      });\n\n      return baseRest(function(args) {\n        var index = -1;\n        while (++index < length) {\n          var pair = pairs[index];\n          if (apply(pair[0], this, args)) {\n            return apply(pair[1], this, args);\n          }\n        }\n      });\n    }\n\n    /**\n     * Creates a function that invokes the predicate properties of `source` with\n     * the corresponding property values of a given object, returning `true` if\n     * all predicates return truthy, else `false`.\n     *\n     * **Note:** The created function is equivalent to `_.conformsTo` with\n     * `source` partially applied.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {Function} Returns the new spec function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': 2, 'b': 1 },\n     *   { 'a': 1, 'b': 2 }\n     * ];\n     *\n     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));\n     * // => [{ 'a': 1, 'b': 2 }]\n     */\n    function conforms(source) {\n      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that returns `value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Util\n     * @param {*} value The value to return from the new function.\n     * @returns {Function} Returns the new constant function.\n     * @example\n     *\n     * var objects = _.times(2, _.constant({ 'a': 1 }));\n     *\n     * console.log(objects);\n     * // => [{ 'a': 1 }, { 'a': 1 }]\n     *\n     * console.log(objects[0] === objects[1]);\n     * // => true\n     */\n    function constant(value) {\n      return function() {\n        return value;\n      };\n    }\n\n    /**\n     * Checks `value` to determine whether a default value should be returned in\n     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,\n     * or `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.14.0\n     * @category Util\n     * @param {*} value The value to check.\n     * @param {*} defaultValue The default value.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * _.defaultTo(1, 10);\n     * // => 1\n     *\n     * _.defaultTo(undefined, 10);\n     * // => 10\n     */\n    function defaultTo(value, defaultValue) {\n      return (value == null || value !== value) ? defaultValue : value;\n    }\n\n    /**\n     * Creates a function that returns the result of invoking the given functions\n     * with the `this` binding of the created function, where each successive\n     * invocation is supplied the return value of the previous.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [funcs] The functions to invoke.\n     * @returns {Function} Returns the new composite function.\n     * @see _.flowRight\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var addSquare = _.flow([_.add, square]);\n     * addSquare(1, 2);\n     * // => 9\n     */\n    var flow = createFlow();\n\n    /**\n     * This method is like `_.flow` except that it creates a function that\n     * invokes the given functions from right to left.\n     *\n     * @static\n     * @since 3.0.0\n     * @memberOf _\n     * @category Util\n     * @param {...(Function|Function[])} [funcs] The functions to invoke.\n     * @returns {Function} Returns the new composite function.\n     * @see _.flow\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var addSquare = _.flowRight([square, _.add]);\n     * addSquare(1, 2);\n     * // => 9\n     */\n    var flowRight = createFlow(true);\n\n    /**\n     * This method returns the first argument it receives.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {*} value Any value.\n     * @returns {*} Returns `value`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     *\n     * console.log(_.identity(object) === object);\n     * // => true\n     */\n    function identity(value) {\n      return value;\n    }\n\n    /**\n     * Creates a function that invokes `func` with the arguments of the created\n     * function. If `func` is a property name, the created function returns the\n     * property value for a given element. If `func` is an array or object, the\n     * created function returns `true` for elements that contain the equivalent\n     * source properties, otherwise it returns `false`.\n     *\n     * @static\n     * @since 4.0.0\n     * @memberOf _\n     * @category Util\n     * @param {*} [func=_.identity] The value to convert to a callback.\n     * @returns {Function} Returns the callback.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': true },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));\n     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.filter(users, _.iteratee(['user', 'fred']));\n     * // => [{ 'user': 'fred', 'age': 40 }]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.map(users, _.iteratee('user'));\n     * // => ['barney', 'fred']\n     *\n     * // Create custom iteratee shorthands.\n     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {\n     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {\n     *     return func.test(string);\n     *   };\n     * });\n     *\n     * _.filter(['abc', 'def'], /ef/);\n     * // => ['def']\n     */\n    function iteratee(func) {\n      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that performs a partial deep comparison between a given\n     * object and `source`, returning `true` if the given object has equivalent\n     * property values, else `false`.\n     *\n     * **Note:** The created function is equivalent to `_.isMatch` with `source`\n     * partially applied.\n     *\n     * Partial comparisons will match empty array and empty object `source`\n     * values against any array or object value, respectively. See `_.isEqual`\n     * for a list of supported value comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {Object} source The object of property values to match.\n     * @returns {Function} Returns the new spec function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': 1, 'b': 2, 'c': 3 },\n     *   { 'a': 4, 'b': 5, 'c': 6 }\n     * ];\n     *\n     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));\n     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]\n     */\n    function matches(source) {\n      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that performs a partial deep comparison between the\n     * value at `path` of a given object to `srcValue`, returning `true` if the\n     * object value is equivalent, else `false`.\n     *\n     * **Note:** Partial comparisons will match empty array and empty object\n     * `srcValue` values against any array or object value, respectively. See\n     * `_.isEqual` for a list of supported value comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.2.0\n     * @category Util\n     * @param {Array|string} path The path of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new spec function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': 1, 'b': 2, 'c': 3 },\n     *   { 'a': 4, 'b': 5, 'c': 6 }\n     * ];\n     *\n     * _.find(objects, _.matchesProperty('a', 4));\n     * // => { 'a': 4, 'b': 5, 'c': 6 }\n     */\n    function matchesProperty(path, srcValue) {\n      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that invokes the method at `path` of a given object.\n     * Any additional arguments are provided to the invoked method.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Util\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {Function} Returns the new invoker function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': { 'b': _.constant(2) } },\n     *   { 'a': { 'b': _.constant(1) } }\n     * ];\n     *\n     * _.map(objects, _.method('a.b'));\n     * // => [2, 1]\n     *\n     * _.map(objects, _.method(['a', 'b']));\n     * // => [2, 1]\n     */\n    var method = baseRest(function(path, args) {\n      return function(object) {\n        return baseInvoke(object, path, args);\n      };\n    });\n\n    /**\n     * The opposite of `_.method`; this method creates a function that invokes\n     * the method at a given path of `object`. Any additional arguments are\n     * provided to the invoked method.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Util\n     * @param {Object} object The object to query.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {Function} Returns the new invoker function.\n     * @example\n     *\n     * var array = _.times(3, _.constant),\n     *     object = { 'a': array, 'b': array, 'c': array };\n     *\n     * _.map(['a[2]', 'c[0]'], _.methodOf(object));\n     * // => [2, 0]\n     *\n     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));\n     * // => [2, 0]\n     */\n    var methodOf = baseRest(function(object, args) {\n      return function(path) {\n        return baseInvoke(object, path, args);\n      };\n    });\n\n    /**\n     * Adds all own enumerable string keyed function properties of a source\n     * object to the destination object. If `object` is a function, then methods\n     * are added to its prototype as well.\n     *\n     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to\n     * avoid conflicts caused by modifying the original.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {Function|Object} [object=lodash] The destination object.\n     * @param {Object} source The object of functions to add.\n     * @param {Object} [options={}] The options object.\n     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.\n     * @returns {Function|Object} Returns `object`.\n     * @example\n     *\n     * function vowels(string) {\n     *   return _.filter(string, function(v) {\n     *     return /[aeiou]/i.test(v);\n     *   });\n     * }\n     *\n     * _.mixin({ 'vowels': vowels });\n     * _.vowels('fred');\n     * // => ['e']\n     *\n     * _('fred').vowels().value();\n     * // => ['e']\n     *\n     * _.mixin({ 'vowels': vowels }, { 'chain': false });\n     * _('fred').vowels();\n     * // => ['e']\n     */\n    function mixin(object, source, options) {\n      var props = keys(source),\n          methodNames = baseFunctions(source, props);\n\n      if (options == null &&\n          !(isObject(source) && (methodNames.length || !props.length))) {\n        options = source;\n        source = object;\n        object = this;\n        methodNames = baseFunctions(source, keys(source));\n      }\n      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,\n          isFunc = isFunction(object);\n\n      arrayEach(methodNames, function(methodName) {\n        var func = source[methodName];\n        object[methodName] = func;\n        if (isFunc) {\n          object.prototype[methodName] = function() {\n            var chainAll = this.__chain__;\n            if (chain || chainAll) {\n              var result = object(this.__wrapped__),\n                  actions = result.__actions__ = copyArray(this.__actions__);\n\n              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });\n              result.__chain__ = chainAll;\n              return result;\n            }\n            return func.apply(object, arrayPush([this.value()], arguments));\n          };\n        }\n      });\n\n      return object;\n    }\n\n    /**\n     * Reverts the `_` variable to its previous value and returns a reference to\n     * the `lodash` function.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @returns {Function} Returns the `lodash` function.\n     * @example\n     *\n     * var lodash = _.noConflict();\n     */\n    function noConflict() {\n      if (root._ === this) {\n        root._ = oldDash;\n      }\n      return this;\n    }\n\n    /**\n     * This method returns `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.3.0\n     * @category Util\n     * @example\n     *\n     * _.times(2, _.noop);\n     * // => [undefined, undefined]\n     */\n    function noop() {\n      // No operation performed.\n    }\n\n    /**\n     * Creates a function that gets the argument at index `n`. If `n` is negative,\n     * the nth argument from the end is returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {number} [n=0] The index of the argument to return.\n     * @returns {Function} Returns the new pass-thru function.\n     * @example\n     *\n     * var func = _.nthArg(1);\n     * func('a', 'b', 'c', 'd');\n     * // => 'b'\n     *\n     * var func = _.nthArg(-2);\n     * func('a', 'b', 'c', 'd');\n     * // => 'c'\n     */\n    function nthArg(n) {\n      n = toInteger(n);\n      return baseRest(function(args) {\n        return baseNth(args, n);\n      });\n    }\n\n    /**\n     * Creates a function that invokes `iteratees` with the arguments it receives\n     * and returns their results.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [iteratees=[_.identity]]\n     *  The iteratees to invoke.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var func = _.over([Math.max, Math.min]);\n     *\n     * func(1, 2, 3, 4);\n     * // => [4, 1]\n     */\n    var over = createOver(arrayMap);\n\n    /**\n     * Creates a function that checks if **all** of the `predicates` return\n     * truthy when invoked with the arguments it receives.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [predicates=[_.identity]]\n     *  The predicates to check.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var func = _.overEvery([Boolean, isFinite]);\n     *\n     * func('1');\n     * // => true\n     *\n     * func(null);\n     * // => false\n     *\n     * func(NaN);\n     * // => false\n     */\n    var overEvery = createOver(arrayEvery);\n\n    /**\n     * Creates a function that checks if **any** of the `predicates` return\n     * truthy when invoked with the arguments it receives.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [predicates=[_.identity]]\n     *  The predicates to check.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var func = _.overSome([Boolean, isFinite]);\n     *\n     * func('1');\n     * // => true\n     *\n     * func(null);\n     * // => true\n     *\n     * func(NaN);\n     * // => false\n     */\n    var overSome = createOver(arraySome);\n\n    /**\n     * Creates a function that returns the value at `path` of a given object.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Util\n     * @param {Array|string} path The path of the property to get.\n     * @returns {Function} Returns the new accessor function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': { 'b': 2 } },\n     *   { 'a': { 'b': 1 } }\n     * ];\n     *\n     * _.map(objects, _.property('a.b'));\n     * // => [2, 1]\n     *\n     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n     * // => [1, 2]\n     */\n    function property(path) {\n      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n    }\n\n    /**\n     * The opposite of `_.property`; this method creates a function that returns\n     * the value at a given path of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {Object} object The object to query.\n     * @returns {Function} Returns the new accessor function.\n     * @example\n     *\n     * var array = [0, 1, 2],\n     *     object = { 'a': array, 'b': array, 'c': array };\n     *\n     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));\n     * // => [2, 0]\n     *\n     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));\n     * // => [2, 0]\n     */\n    function propertyOf(object) {\n      return function(path) {\n        return object == null ? undefined : baseGet(object, path);\n      };\n    }\n\n    /**\n     * Creates an array of numbers (positive and/or negative) progressing from\n     * `start` up to, but not including, `end`. A step of `-1` is used if a negative\n     * `start` is specified without an `end` or `step`. If `end` is not specified,\n     * it's set to `start` with `start` then set to `0`.\n     *\n     * **Note:** JavaScript follows the IEEE-754 standard for resolving\n     * floating-point values which can produce unexpected results.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} [step=1] The value to increment or decrement by.\n     * @returns {Array} Returns the range of numbers.\n     * @see _.inRange, _.rangeRight\n     * @example\n     *\n     * _.range(4);\n     * // => [0, 1, 2, 3]\n     *\n     * _.range(-4);\n     * // => [0, -1, -2, -3]\n     *\n     * _.range(1, 5);\n     * // => [1, 2, 3, 4]\n     *\n     * _.range(0, 20, 5);\n     * // => [0, 5, 10, 15]\n     *\n     * _.range(0, -4, -1);\n     * // => [0, -1, -2, -3]\n     *\n     * _.range(1, 4, 0);\n     * // => [1, 1, 1]\n     *\n     * _.range(0);\n     * // => []\n     */\n    var range = createRange();\n\n    /**\n     * This method is like `_.range` except that it populates values in\n     * descending order.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} [step=1] The value to increment or decrement by.\n     * @returns {Array} Returns the range of numbers.\n     * @see _.inRange, _.range\n     * @example\n     *\n     * _.rangeRight(4);\n     * // => [3, 2, 1, 0]\n     *\n     * _.rangeRight(-4);\n     * // => [-3, -2, -1, 0]\n     *\n     * _.rangeRight(1, 5);\n     * // => [4, 3, 2, 1]\n     *\n     * _.rangeRight(0, 20, 5);\n     * // => [15, 10, 5, 0]\n     *\n     * _.rangeRight(0, -4, -1);\n     * // => [-3, -2, -1, 0]\n     *\n     * _.rangeRight(1, 4, 0);\n     * // => [1, 1, 1]\n     *\n     * _.rangeRight(0);\n     * // => []\n     */\n    var rangeRight = createRange(true);\n\n    /**\n     * This method returns a new empty array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {Array} Returns the new empty array.\n     * @example\n     *\n     * var arrays = _.times(2, _.stubArray);\n     *\n     * console.log(arrays);\n     * // => [[], []]\n     *\n     * console.log(arrays[0] === arrays[1]);\n     * // => false\n     */\n    function stubArray() {\n      return [];\n    }\n\n    /**\n     * This method returns `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {boolean} Returns `false`.\n     * @example\n     *\n     * _.times(2, _.stubFalse);\n     * // => [false, false]\n     */\n    function stubFalse() {\n      return false;\n    }\n\n    /**\n     * This method returns a new empty object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {Object} Returns the new empty object.\n     * @example\n     *\n     * var objects = _.times(2, _.stubObject);\n     *\n     * console.log(objects);\n     * // => [{}, {}]\n     *\n     * console.log(objects[0] === objects[1]);\n     * // => false\n     */\n    function stubObject() {\n      return {};\n    }\n\n    /**\n     * This method returns an empty string.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {string} Returns the empty string.\n     * @example\n     *\n     * _.times(2, _.stubString);\n     * // => ['', '']\n     */\n    function stubString() {\n      return '';\n    }\n\n    /**\n     * This method returns `true`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {boolean} Returns `true`.\n     * @example\n     *\n     * _.times(2, _.stubTrue);\n     * // => [true, true]\n     */\n    function stubTrue() {\n      return true;\n    }\n\n    /**\n     * Invokes the iteratee `n` times, returning an array of the results of\n     * each invocation. The iteratee is invoked with one argument; (index).\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {number} n The number of times to invoke `iteratee`.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the array of results.\n     * @example\n     *\n     * _.times(3, String);\n     * // => ['0', '1', '2']\n     *\n     *  _.times(4, _.constant(0));\n     * // => [0, 0, 0, 0]\n     */\n    function times(n, iteratee) {\n      n = toInteger(n);\n      if (n < 1 || n > MAX_SAFE_INTEGER) {\n        return [];\n      }\n      var index = MAX_ARRAY_LENGTH,\n          length = nativeMin(n, MAX_ARRAY_LENGTH);\n\n      iteratee = getIteratee(iteratee);\n      n -= MAX_ARRAY_LENGTH;\n\n      var result = baseTimes(length, iteratee);\n      while (++index < n) {\n        iteratee(index);\n      }\n      return result;\n    }\n\n    /**\n     * Converts `value` to a property path array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {*} value The value to convert.\n     * @returns {Array} Returns the new property path array.\n     * @example\n     *\n     * _.toPath('a.b.c');\n     * // => ['a', 'b', 'c']\n     *\n     * _.toPath('a[0].b.c');\n     * // => ['a', '0', 'b', 'c']\n     */\n    function toPath(value) {\n      if (isArray(value)) {\n        return arrayMap(value, toKey);\n      }\n      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));\n    }\n\n    /**\n     * Generates a unique ID. If `prefix` is given, the ID is appended to it.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {string} [prefix=''] The value to prefix the ID with.\n     * @returns {string} Returns the unique ID.\n     * @example\n     *\n     * _.uniqueId('contact_');\n     * // => 'contact_104'\n     *\n     * _.uniqueId();\n     * // => '105'\n     */\n    function uniqueId(prefix) {\n      var id = ++idCounter;\n      return toString(prefix) + id;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Adds two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.4.0\n     * @category Math\n     * @param {number} augend The first number in an addition.\n     * @param {number} addend The second number in an addition.\n     * @returns {number} Returns the total.\n     * @example\n     *\n     * _.add(6, 4);\n     * // => 10\n     */\n    var add = createMathOperation(function(augend, addend) {\n      return augend + addend;\n    }, 0);\n\n    /**\n     * Computes `number` rounded up to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Math\n     * @param {number} number The number to round up.\n     * @param {number} [precision=0] The precision to round up to.\n     * @returns {number} Returns the rounded up number.\n     * @example\n     *\n     * _.ceil(4.006);\n     * // => 5\n     *\n     * _.ceil(6.004, 2);\n     * // => 6.01\n     *\n     * _.ceil(6040, -2);\n     * // => 6100\n     */\n    var ceil = createRound('ceil');\n\n    /**\n     * Divide two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Math\n     * @param {number} dividend The first number in a division.\n     * @param {number} divisor The second number in a division.\n     * @returns {number} Returns the quotient.\n     * @example\n     *\n     * _.divide(6, 4);\n     * // => 1.5\n     */\n    var divide = createMathOperation(function(dividend, divisor) {\n      return dividend / divisor;\n    }, 1);\n\n    /**\n     * Computes `number` rounded down to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Math\n     * @param {number} number The number to round down.\n     * @param {number} [precision=0] The precision to round down to.\n     * @returns {number} Returns the rounded down number.\n     * @example\n     *\n     * _.floor(4.006);\n     * // => 4\n     *\n     * _.floor(0.046, 2);\n     * // => 0.04\n     *\n     * _.floor(4060, -2);\n     * // => 4000\n     */\n    var floor = createRound('floor');\n\n    /**\n     * Computes the maximum value of `array`. If `array` is empty or falsey,\n     * `undefined` is returned.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {*} Returns the maximum value.\n     * @example\n     *\n     * _.max([4, 2, 8, 6]);\n     * // => 8\n     *\n     * _.max([]);\n     * // => undefined\n     */\n    function max(array) {\n      return (array && array.length)\n        ? baseExtremum(array, identity, baseGt)\n        : undefined;\n    }\n\n    /**\n     * This method is like `_.max` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the criterion by which\n     * the value is ranked. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {*} Returns the maximum value.\n     * @example\n     *\n     * var objects = [{ 'n': 1 }, { 'n': 2 }];\n     *\n     * _.maxBy(objects, function(o) { return o.n; });\n     * // => { 'n': 2 }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.maxBy(objects, 'n');\n     * // => { 'n': 2 }\n     */\n    function maxBy(array, iteratee) {\n      return (array && array.length)\n        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)\n        : undefined;\n    }\n\n    /**\n     * Computes the mean of the values in `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {number} Returns the mean.\n     * @example\n     *\n     * _.mean([4, 2, 8, 6]);\n     * // => 5\n     */\n    function mean(array) {\n      return baseMean(array, identity);\n    }\n\n    /**\n     * This method is like `_.mean` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the value to be averaged.\n     * The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the mean.\n     * @example\n     *\n     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];\n     *\n     * _.meanBy(objects, function(o) { return o.n; });\n     * // => 5\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.meanBy(objects, 'n');\n     * // => 5\n     */\n    function meanBy(array, iteratee) {\n      return baseMean(array, getIteratee(iteratee, 2));\n    }\n\n    /**\n     * Computes the minimum value of `array`. If `array` is empty or falsey,\n     * `undefined` is returned.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {*} Returns the minimum value.\n     * @example\n     *\n     * _.min([4, 2, 8, 6]);\n     * // => 2\n     *\n     * _.min([]);\n     * // => undefined\n     */\n    function min(array) {\n      return (array && array.length)\n        ? baseExtremum(array, identity, baseLt)\n        : undefined;\n    }\n\n    /**\n     * This method is like `_.min` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the criterion by which\n     * the value is ranked. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {*} Returns the minimum value.\n     * @example\n     *\n     * var objects = [{ 'n': 1 }, { 'n': 2 }];\n     *\n     * _.minBy(objects, function(o) { return o.n; });\n     * // => { 'n': 1 }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.minBy(objects, 'n');\n     * // => { 'n': 1 }\n     */\n    function minBy(array, iteratee) {\n      return (array && array.length)\n        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)\n        : undefined;\n    }\n\n    /**\n     * Multiply two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Math\n     * @param {number} multiplier The first number in a multiplication.\n     * @param {number} multiplicand The second number in a multiplication.\n     * @returns {number} Returns the product.\n     * @example\n     *\n     * _.multiply(6, 4);\n     * // => 24\n     */\n    var multiply = createMathOperation(function(multiplier, multiplicand) {\n      return multiplier * multiplicand;\n    }, 1);\n\n    /**\n     * Computes `number` rounded to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Math\n     * @param {number} number The number to round.\n     * @param {number} [precision=0] The precision to round to.\n     * @returns {number} Returns the rounded number.\n     * @example\n     *\n     * _.round(4.006);\n     * // => 4\n     *\n     * _.round(4.006, 2);\n     * // => 4.01\n     *\n     * _.round(4060, -2);\n     * // => 4100\n     */\n    var round = createRound('round');\n\n    /**\n     * Subtract two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {number} minuend The first number in a subtraction.\n     * @param {number} subtrahend The second number in a subtraction.\n     * @returns {number} Returns the difference.\n     * @example\n     *\n     * _.subtract(6, 4);\n     * // => 2\n     */\n    var subtract = createMathOperation(function(minuend, subtrahend) {\n      return minuend - subtrahend;\n    }, 0);\n\n    /**\n     * Computes the sum of the values in `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.4.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {number} Returns the sum.\n     * @example\n     *\n     * _.sum([4, 2, 8, 6]);\n     * // => 20\n     */\n    function sum(array) {\n      return (array && array.length)\n        ? baseSum(array, identity)\n        : 0;\n    }\n\n    /**\n     * This method is like `_.sum` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the value to be summed.\n     * The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the sum.\n     * @example\n     *\n     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];\n     *\n     * _.sumBy(objects, function(o) { return o.n; });\n     * // => 20\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.sumBy(objects, 'n');\n     * // => 20\n     */\n    function sumBy(array, iteratee) {\n      return (array && array.length)\n        ? baseSum(array, getIteratee(iteratee, 2))\n        : 0;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    // Add methods that return wrapped values in chain sequences.\n    lodash.after = after;\n    lodash.ary = ary;\n    lodash.assign = assign;\n    lodash.assignIn = assignIn;\n    lodash.assignInWith = assignInWith;\n    lodash.assignWith = assignWith;\n    lodash.at = at;\n    lodash.before = before;\n    lodash.bind = bind;\n    lodash.bindAll = bindAll;\n    lodash.bindKey = bindKey;\n    lodash.castArray = castArray;\n    lodash.chain = chain;\n    lodash.chunk = chunk;\n    lodash.compact = compact;\n    lodash.concat = concat;\n    lodash.cond = cond;\n    lodash.conforms = conforms;\n    lodash.constant = constant;\n    lodash.countBy = countBy;\n    lodash.create = create;\n    lodash.curry = curry;\n    lodash.curryRight = curryRight;\n    lodash.debounce = debounce;\n    lodash.defaults = defaults;\n    lodash.defaultsDeep = defaultsDeep;\n    lodash.defer = defer;\n    lodash.delay = delay;\n    lodash.difference = difference;\n    lodash.differenceBy = differenceBy;\n    lodash.differenceWith = differenceWith;\n    lodash.drop = drop;\n    lodash.dropRight = dropRight;\n    lodash.dropRightWhile = dropRightWhile;\n    lodash.dropWhile = dropWhile;\n    lodash.fill = fill;\n    lodash.filter = filter;\n    lodash.flatMap = flatMap;\n    lodash.flatMapDeep = flatMapDeep;\n    lodash.flatMapDepth = flatMapDepth;\n    lodash.flatten = flatten;\n    lodash.flattenDeep = flattenDeep;\n    lodash.flattenDepth = flattenDepth;\n    lodash.flip = flip;\n    lodash.flow = flow;\n    lodash.flowRight = flowRight;\n    lodash.fromPairs = fromPairs;\n    lodash.functions = functions;\n    lodash.functionsIn = functionsIn;\n    lodash.groupBy = groupBy;\n    lodash.initial = initial;\n    lodash.intersection = intersection;\n    lodash.intersectionBy = intersectionBy;\n    lodash.intersectionWith = intersectionWith;\n    lodash.invert = invert;\n    lodash.invertBy = invertBy;\n    lodash.invokeMap = invokeMap;\n    lodash.iteratee = iteratee;\n    lodash.keyBy = keyBy;\n    lodash.keys = keys;\n    lodash.keysIn = keysIn;\n    lodash.map = map;\n    lodash.mapKeys = mapKeys;\n    lodash.mapValues = mapValues;\n    lodash.matches = matches;\n    lodash.matchesProperty = matchesProperty;\n    lodash.memoize = memoize;\n    lodash.merge = merge;\n    lodash.mergeWith = mergeWith;\n    lodash.method = method;\n    lodash.methodOf = methodOf;\n    lodash.mixin = mixin;\n    lodash.negate = negate;\n    lodash.nthArg = nthArg;\n    lodash.omit = omit;\n    lodash.omitBy = omitBy;\n    lodash.once = once;\n    lodash.orderBy = orderBy;\n    lodash.over = over;\n    lodash.overArgs = overArgs;\n    lodash.overEvery = overEvery;\n    lodash.overSome = overSome;\n    lodash.partial = partial;\n    lodash.partialRight = partialRight;\n    lodash.partition = partition;\n    lodash.pick = pick;\n    lodash.pickBy = pickBy;\n    lodash.property = property;\n    lodash.propertyOf = propertyOf;\n    lodash.pull = pull;\n    lodash.pullAll = pullAll;\n    lodash.pullAllBy = pullAllBy;\n    lodash.pullAllWith = pullAllWith;\n    lodash.pullAt = pullAt;\n    lodash.range = range;\n    lodash.rangeRight = rangeRight;\n    lodash.rearg = rearg;\n    lodash.reject = reject;\n    lodash.remove = remove;\n    lodash.rest = rest;\n    lodash.reverse = reverse;\n    lodash.sampleSize = sampleSize;\n    lodash.set = set;\n    lodash.setWith = setWith;\n    lodash.shuffle = shuffle;\n    lodash.slice = slice;\n    lodash.sortBy = sortBy;\n    lodash.sortedUniq = sortedUniq;\n    lodash.sortedUniqBy = sortedUniqBy;\n    lodash.split = split;\n    lodash.spread = spread;\n    lodash.tail = tail;\n    lodash.take = take;\n    lodash.takeRight = takeRight;\n    lodash.takeRightWhile = takeRightWhile;\n    lodash.takeWhile = takeWhile;\n    lodash.tap = tap;\n    lodash.throttle = throttle;\n    lodash.thru = thru;\n    lodash.toArray = toArray;\n    lodash.toPairs = toPairs;\n    lodash.toPairsIn = toPairsIn;\n    lodash.toPath = toPath;\n    lodash.toPlainObject = toPlainObject;\n    lodash.transform = transform;\n    lodash.unary = unary;\n    lodash.union = union;\n    lodash.unionBy = unionBy;\n    lodash.unionWith = unionWith;\n    lodash.uniq = uniq;\n    lodash.uniqBy = uniqBy;\n    lodash.uniqWith = uniqWith;\n    lodash.unset = unset;\n    lodash.unzip = unzip;\n    lodash.unzipWith = unzipWith;\n    lodash.update = update;\n    lodash.updateWith = updateWith;\n    lodash.values = values;\n    lodash.valuesIn = valuesIn;\n    lodash.without = without;\n    lodash.words = words;\n    lodash.wrap = wrap;\n    lodash.xor = xor;\n    lodash.xorBy = xorBy;\n    lodash.xorWith = xorWith;\n    lodash.zip = zip;\n    lodash.zipObject = zipObject;\n    lodash.zipObjectDeep = zipObjectDeep;\n    lodash.zipWith = zipWith;\n\n    // Add aliases.\n    lodash.entries = toPairs;\n    lodash.entriesIn = toPairsIn;\n    lodash.extend = assignIn;\n    lodash.extendWith = assignInWith;\n\n    // Add methods to `lodash.prototype`.\n    mixin(lodash, lodash);\n\n    /*------------------------------------------------------------------------*/\n\n    // Add methods that return unwrapped values in chain sequences.\n    lodash.add = add;\n    lodash.attempt = attempt;\n    lodash.camelCase = camelCase;\n    lodash.capitalize = capitalize;\n    lodash.ceil = ceil;\n    lodash.clamp = clamp;\n    lodash.clone = clone;\n    lodash.cloneDeep = cloneDeep;\n    lodash.cloneDeepWith = cloneDeepWith;\n    lodash.cloneWith = cloneWith;\n    lodash.conformsTo = conformsTo;\n    lodash.deburr = deburr;\n    lodash.defaultTo = defaultTo;\n    lodash.divide = divide;\n    lodash.endsWith = endsWith;\n    lodash.eq = eq;\n    lodash.escape = escape;\n    lodash.escapeRegExp = escapeRegExp;\n    lodash.every = every;\n    lodash.find = find;\n    lodash.findIndex = findIndex;\n    lodash.findKey = findKey;\n    lodash.findLast = findLast;\n    lodash.findLastIndex = findLastIndex;\n    lodash.findLastKey = findLastKey;\n    lodash.floor = floor;\n    lodash.forEach = forEach;\n    lodash.forEachRight = forEachRight;\n    lodash.forIn = forIn;\n    lodash.forInRight = forInRight;\n    lodash.forOwn = forOwn;\n    lodash.forOwnRight = forOwnRight;\n    lodash.get = get;\n    lodash.gt = gt;\n    lodash.gte = gte;\n    lodash.has = has;\n    lodash.hasIn = hasIn;\n    lodash.head = head;\n    lodash.identity = identity;\n    lodash.includes = includes;\n    lodash.indexOf = indexOf;\n    lodash.inRange = inRange;\n    lodash.invoke = invoke;\n    lodash.isArguments = isArguments;\n    lodash.isArray = isArray;\n    lodash.isArrayBuffer = isArrayBuffer;\n    lodash.isArrayLike = isArrayLike;\n    lodash.isArrayLikeObject = isArrayLikeObject;\n    lodash.isBoolean = isBoolean;\n    lodash.isBuffer = isBuffer;\n    lodash.isDate = isDate;\n    lodash.isElement = isElement;\n    lodash.isEmpty = isEmpty;\n    lodash.isEqual = isEqual;\n    lodash.isEqualWith = isEqualWith;\n    lodash.isError = isError;\n    lodash.isFinite = isFinite;\n    lodash.isFunction = isFunction;\n    lodash.isInteger = isInteger;\n    lodash.isLength = isLength;\n    lodash.isMap = isMap;\n    lodash.isMatch = isMatch;\n    lodash.isMatchWith = isMatchWith;\n    lodash.isNaN = isNaN;\n    lodash.isNative = isNative;\n    lodash.isNil = isNil;\n    lodash.isNull = isNull;\n    lodash.isNumber = isNumber;\n    lodash.isObject = isObject;\n    lodash.isObjectLike = isObjectLike;\n    lodash.isPlainObject = isPlainObject;\n    lodash.isRegExp = isRegExp;\n    lodash.isSafeInteger = isSafeInteger;\n    lodash.isSet = isSet;\n    lodash.isString = isString;\n    lodash.isSymbol = isSymbol;\n    lodash.isTypedArray = isTypedArray;\n    lodash.isUndefined = isUndefined;\n    lodash.isWeakMap = isWeakMap;\n    lodash.isWeakSet = isWeakSet;\n    lodash.join = join;\n    lodash.kebabCase = kebabCase;\n    lodash.last = last;\n    lodash.lastIndexOf = lastIndexOf;\n    lodash.lowerCase = lowerCase;\n    lodash.lowerFirst = lowerFirst;\n    lodash.lt = lt;\n    lodash.lte = lte;\n    lodash.max = max;\n    lodash.maxBy = maxBy;\n    lodash.mean = mean;\n    lodash.meanBy = meanBy;\n    lodash.min = min;\n    lodash.minBy = minBy;\n    lodash.stubArray = stubArray;\n    lodash.stubFalse = stubFalse;\n    lodash.stubObject = stubObject;\n    lodash.stubString = stubString;\n    lodash.stubTrue = stubTrue;\n    lodash.multiply = multiply;\n    lodash.nth = nth;\n    lodash.noConflict = noConflict;\n    lodash.noop = noop;\n    lodash.now = now;\n    lodash.pad = pad;\n    lodash.padEnd = padEnd;\n    lodash.padStart = padStart;\n    lodash.parseInt = parseInt;\n    lodash.random = random;\n    lodash.reduce = reduce;\n    lodash.reduceRight = reduceRight;\n    lodash.repeat = repeat;\n    lodash.replace = replace;\n    lodash.result = result;\n    lodash.round = round;\n    lodash.runInContext = runInContext;\n    lodash.sample = sample;\n    lodash.size = size;\n    lodash.snakeCase = snakeCase;\n    lodash.some = some;\n    lodash.sortedIndex = sortedIndex;\n    lodash.sortedIndexBy = sortedIndexBy;\n    lodash.sortedIndexOf = sortedIndexOf;\n    lodash.sortedLastIndex = sortedLastIndex;\n    lodash.sortedLastIndexBy = sortedLastIndexBy;\n    lodash.sortedLastIndexOf = sortedLastIndexOf;\n    lodash.startCase = startCase;\n    lodash.startsWith = startsWith;\n    lodash.subtract = subtract;\n    lodash.sum = sum;\n    lodash.sumBy = sumBy;\n    lodash.template = template;\n    lodash.times = times;\n    lodash.toFinite = toFinite;\n    lodash.toInteger = toInteger;\n    lodash.toLength = toLength;\n    lodash.toLower = toLower;\n    lodash.toNumber = toNumber;\n    lodash.toSafeInteger = toSafeInteger;\n    lodash.toString = toString;\n    lodash.toUpper = toUpper;\n    lodash.trim = trim;\n    lodash.trimEnd = trimEnd;\n    lodash.trimStart = trimStart;\n    lodash.truncate = truncate;\n    lodash.unescape = unescape;\n    lodash.uniqueId = uniqueId;\n    lodash.upperCase = upperCase;\n    lodash.upperFirst = upperFirst;\n\n    // Add aliases.\n    lodash.each = forEach;\n    lodash.eachRight = forEachRight;\n    lodash.first = head;\n\n    mixin(lodash, (function() {\n      var source = {};\n      baseForOwn(lodash, function(func, methodName) {\n        if (!hasOwnProperty.call(lodash.prototype, methodName)) {\n          source[methodName] = func;\n        }\n      });\n      return source;\n    }()), { 'chain': false });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * The semantic version number.\n     *\n     * @static\n     * @memberOf _\n     * @type {string}\n     */\n    lodash.VERSION = VERSION;\n\n    // Assign default placeholders.\n    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {\n      lodash[methodName].placeholder = lodash;\n    });\n\n    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.\n    arrayEach(['drop', 'take'], function(methodName, index) {\n      LazyWrapper.prototype[methodName] = function(n) {\n        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);\n\n        var result = (this.__filtered__ && !index)\n          ? new LazyWrapper(this)\n          : this.clone();\n\n        if (result.__filtered__) {\n          result.__takeCount__ = nativeMin(n, result.__takeCount__);\n        } else {\n          result.__views__.push({\n            'size': nativeMin(n, MAX_ARRAY_LENGTH),\n            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')\n          });\n        }\n        return result;\n      };\n\n      LazyWrapper.prototype[methodName + 'Right'] = function(n) {\n        return this.reverse()[methodName](n).reverse();\n      };\n    });\n\n    // Add `LazyWrapper` methods that accept an `iteratee` value.\n    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {\n      var type = index + 1,\n          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;\n\n      LazyWrapper.prototype[methodName] = function(iteratee) {\n        var result = this.clone();\n        result.__iteratees__.push({\n          'iteratee': getIteratee(iteratee, 3),\n          'type': type\n        });\n        result.__filtered__ = result.__filtered__ || isFilter;\n        return result;\n      };\n    });\n\n    // Add `LazyWrapper` methods for `_.head` and `_.last`.\n    arrayEach(['head', 'last'], function(methodName, index) {\n      var takeName = 'take' + (index ? 'Right' : '');\n\n      LazyWrapper.prototype[methodName] = function() {\n        return this[takeName](1).value()[0];\n      };\n    });\n\n    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.\n    arrayEach(['initial', 'tail'], function(methodName, index) {\n      var dropName = 'drop' + (index ? '' : 'Right');\n\n      LazyWrapper.prototype[methodName] = function() {\n        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);\n      };\n    });\n\n    LazyWrapper.prototype.compact = function() {\n      return this.filter(identity);\n    };\n\n    LazyWrapper.prototype.find = function(predicate) {\n      return this.filter(predicate).head();\n    };\n\n    LazyWrapper.prototype.findLast = function(predicate) {\n      return this.reverse().find(predicate);\n    };\n\n    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {\n      if (typeof path == 'function') {\n        return new LazyWrapper(this);\n      }\n      return this.map(function(value) {\n        return baseInvoke(value, path, args);\n      });\n    });\n\n    LazyWrapper.prototype.reject = function(predicate) {\n      return this.filter(negate(getIteratee(predicate)));\n    };\n\n    LazyWrapper.prototype.slice = function(start, end) {\n      start = toInteger(start);\n\n      var result = this;\n      if (result.__filtered__ && (start > 0 || end < 0)) {\n        return new LazyWrapper(result);\n      }\n      if (start < 0) {\n        result = result.takeRight(-start);\n      } else if (start) {\n        result = result.drop(start);\n      }\n      if (end !== undefined) {\n        end = toInteger(end);\n        result = end < 0 ? result.dropRight(-end) : result.take(end - start);\n      }\n      return result;\n    };\n\n    LazyWrapper.prototype.takeRightWhile = function(predicate) {\n      return this.reverse().takeWhile(predicate).reverse();\n    };\n\n    LazyWrapper.prototype.toArray = function() {\n      return this.take(MAX_ARRAY_LENGTH);\n    };\n\n    // Add `LazyWrapper` methods to `lodash.prototype`.\n    baseForOwn(LazyWrapper.prototype, function(func, methodName) {\n      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),\n          isTaker = /^(?:head|last)$/.test(methodName),\n          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],\n          retUnwrapped = isTaker || /^find/.test(methodName);\n\n      if (!lodashFunc) {\n        return;\n      }\n      lodash.prototype[methodName] = function() {\n        var value = this.__wrapped__,\n            args = isTaker ? [1] : arguments,\n            isLazy = value instanceof LazyWrapper,\n            iteratee = args[0],\n            useLazy = isLazy || isArray(value);\n\n        var interceptor = function(value) {\n          var result = lodashFunc.apply(lodash, arrayPush([value], args));\n          return (isTaker && chainAll) ? result[0] : result;\n        };\n\n        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {\n          // Avoid lazy use if the iteratee has a \"length\" value other than `1`.\n          isLazy = useLazy = false;\n        }\n        var chainAll = this.__chain__,\n            isHybrid = !!this.__actions__.length,\n            isUnwrapped = retUnwrapped && !chainAll,\n            onlyLazy = isLazy && !isHybrid;\n\n        if (!retUnwrapped && useLazy) {\n          value = onlyLazy ? value : new LazyWrapper(this);\n          var result = func.apply(value, args);\n          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });\n          return new LodashWrapper(result, chainAll);\n        }\n        if (isUnwrapped && onlyLazy) {\n          return func.apply(this, args);\n        }\n        result = this.thru(interceptor);\n        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;\n      };\n    });\n\n    // Add `Array` methods to `lodash.prototype`.\n    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {\n      var func = arrayProto[methodName],\n          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',\n          retUnwrapped = /^(?:pop|shift)$/.test(methodName);\n\n      lodash.prototype[methodName] = function() {\n        var args = arguments;\n        if (retUnwrapped && !this.__chain__) {\n          var value = this.value();\n          return func.apply(isArray(value) ? value : [], args);\n        }\n        return this[chainName](function(value) {\n          return func.apply(isArray(value) ? value : [], args);\n        });\n      };\n    });\n\n    // Map minified method names to their real names.\n    baseForOwn(LazyWrapper.prototype, function(func, methodName) {\n      var lodashFunc = lodash[methodName];\n      if (lodashFunc) {\n        var key = (lodashFunc.name + ''),\n            names = realNames[key] || (realNames[key] = []);\n\n        names.push({ 'name': methodName, 'func': lodashFunc });\n      }\n    });\n\n    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{\n      'name': 'wrapper',\n      'func': undefined\n    }];\n\n    // Add methods to `LazyWrapper`.\n    LazyWrapper.prototype.clone = lazyClone;\n    LazyWrapper.prototype.reverse = lazyReverse;\n    LazyWrapper.prototype.value = lazyValue;\n\n    // Add chain sequence methods to the `lodash` wrapper.\n    lodash.prototype.at = wrapperAt;\n    lodash.prototype.chain = wrapperChain;\n    lodash.prototype.commit = wrapperCommit;\n    lodash.prototype.next = wrapperNext;\n    lodash.prototype.plant = wrapperPlant;\n    lodash.prototype.reverse = wrapperReverse;\n    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;\n\n    // Add lazy aliases.\n    lodash.prototype.first = lodash.prototype.head;\n\n    if (symIterator) {\n      lodash.prototype[symIterator] = wrapperToIterator;\n    }\n    return lodash;\n  });\n\n  /*--------------------------------------------------------------------------*/\n\n  // Export lodash.\n  var _ = runInContext();\n\n  // Some AMD build optimizers, like r.js, check for condition patterns like:\n  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {\n    // Expose Lodash on the global object to prevent errors when Lodash is\n    // loaded by a script tag in the presence of an AMD loader.\n    // See http://requirejs.org/docs/errors.html#mismatch for more details.\n    // Use `_.noConflict` to remove Lodash from the global object.\n    root._ = _;\n\n    // Define as an anonymous module so, through path mapping, it can be\n    // referenced as the \"underscore\" module.\n    define(function() {\n      return _;\n    });\n  }\n  // Check for `exports` after `define` in case a build optimizer adds it.\n  else if (freeModule) {\n    // Export for Node.js.\n    (freeModule.exports = _)._ = _;\n    // Export for CommonJS support.\n    freeExports._ = _;\n  }\n  else {\n    // Export to the global object.\n    root._ = _;\n  }\n}.call(this));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/lodash.js\n// module id = 13\n// module chunks = 0","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() { return this; })();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 14\n// module chunks = 0","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tif(!module.children) module.children = [];\r\n\t\tObject.defineProperty(module, \"loaded\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tconfigurable: false,\r\n\t\t\tget: function() { return module.l; }\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"id\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tconfigurable: false,\r\n\t\t\tget: function() { return module.i; }\r\n\t\t});\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/module.js\n// module id = 15\n// module chunks = 0","\n/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/// <reference path=\"../typings/index.d.ts\" />\nimport * as angular from 'angular';\n\nimport 'angular-ui-router';\nimport 'angular-resource';\nimport 'angular-cookies';\n\nimport 'ngmap';\n\nimport routesConfig from './routes';\nimport {engMap} from './app/components/engMap.component';\nimport {elineSide} from './app/components/eline-side.component';\n\nangular.module('vnaasgui', [\n    'ui.router',\n    'app',\n    'ngMap'\n  ])\n  .config(routesConfig)\n  .component('engMap', engMap)\n  .component('elineSide', elineSide)\n  .run(function(\n    $log: ng.ILogService,\n    $state: ng.ui.IStateService,\n    XosNavigationService: any,\n    XosComponentInjector: any) {\n    $log.info('[vnaasgui] App is running');\n\n    XosNavigationService.add({\n      label: 'vNaaS GUI',\n      state: 'xos.vnaasgui',\n    });\n\n  });\n\n\n\n// WEBPACK FOOTER //\n// ./~/tslint-loader!./src/index.ts","/*\n * Copyright 2017-present Open Networking Foundation\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n\n * http://www.apache.org/licenses/LICENSE-2.0\n\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\"use strict\";\nexports.__esModule = true;\n/// <reference path=\"../typings/index.d.ts\" />\nvar angular = require(\"angular\");\nrequire(\"angular-ui-router\");\nrequire(\"angular-resource\");\nrequire(\"angular-cookies\");\nrequire(\"ngmap\");\nvar routes_1 = require(\"./routes\");\nvar engMap_component_1 = require(\"./app/components/engMap.component\");\nvar eline_side_component_1 = require(\"./app/components/eline-side.component\");\nangular.module('vnaasgui', [\n    'ui.router',\n    'app',\n    'ngMap'\n])\n    .config(routes_1[\"default\"])\n    .component('engMap', engMap_component_1.engMap)\n    .component('elineSide', eline_side_component_1.elineSide)\n    .run(function ($log, $state, XosNavigationService, XosComponentInjector) {\n    $log.info('[vnaasgui] App is running');\n    XosNavigationService.add({\n        label: 'vNaaS GUI',\n        state: 'xos.vnaasgui'\n    });\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.ts"],"sourceRoot":""}
\ No newline at end of file
diff --git a/xos/gui/.tmp/mapconstants.js b/xos/gui/.tmp/mapconstants.js
new file mode 100755
index 0000000..217b8c0
--- /dev/null
+++ b/xos/gui/.tmp/mapconstants.js
@@ -0,0 +1,22 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('app')
+  .constant('MapConfig', {
+    marker: './xos/extensions/vnaasgui/app/img/co.png',
+  });
diff --git a/xos/gui/.tmp/style.config.js b/xos/gui/.tmp/style.config.js
new file mode 100755
index 0000000..022938b
--- /dev/null
+++ b/xos/gui/.tmp/style.config.js
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('app')
+  .constant('StyleConfig', {
+    projectName: 'CORD',
+    favicon: 'cord-favicon.png',
+    background: 'cord-bg.jpg',
+    payoff: 'Your VNF orchestrator',
+    logo: 'cord-logo.png',
+    routes: [
+        {
+            label: 'Slices',
+            state: 'xos.core.slices'
+        },
+        {
+            label: 'Instances',
+            state: 'xos.core.instances'
+        },
+        {
+            label: 'Nodes',
+            state: 'xos.core.nodes'
+        }
+    ]
+});
diff --git a/xos/gui/Dockerfile b/xos/gui/Dockerfile
new file mode 100755
index 0000000..911bd15
--- /dev/null
+++ b/xos/gui/Dockerfile
@@ -0,0 +1,24 @@
+FROM xosproject/xos-gui-extension-builder:candidate
+
+# Set environment vars
+ENV CODE_SOURCE .
+ENV CODE_DEST /var/www
+ENV VHOST /var/www/dist
+
+# Add the app deps
+COPY ${CODE_SOURCE}/package.json ${CODE_DEST}/package.json
+COPY ${CODE_SOURCE}/typings.json ${CODE_DEST}/typings.json
+
+# Install Deps
+WORKDIR ${CODE_DEST}
+RUN npm install
+RUN npm run typings
+
+# Build the app
+COPY ${CODE_SOURCE}/conf ${CODE_DEST}/conf
+COPY ${CODE_SOURCE}/gulp_tasks ${CODE_DEST}/gulp_tasks
+COPY ${CODE_SOURCE}/src ${CODE_DEST}/src
+COPY ${CODE_SOURCE}/gulpfile.js ${CODE_DEST}/gulpfile.js
+COPY ${CODE_SOURCE}/tsconfig.json ${CODE_DEST}/tsconfig.json
+COPY ${CODE_SOURCE}/tslint.json ${CODE_DEST}/tslint.json
+RUN npm run build
diff --git a/xos/gui/README.md b/xos/gui/README.md
new file mode 100755
index 0000000..73a894c
--- /dev/null
+++ b/xos/gui/README.md
@@ -0,0 +1,24 @@
+# vnaasgui
+
+## Installation
+
+Having a profile deployed via Ansible is required. To use the GUI, include the following in the profile manifest
+being used in `cord/build/platform-install/profile_manifests`.
+
+```
+enabled_gui_extensions:
+  - name: vnaasgui
+    path: orchestration/vnaas/xos/gui
+    extra-files:
+        - app/style/style.css
+        - mapconstants.js
+```
+
+## Features
+
+ - Maps all UserNetworkInterface locations, and displays the status of created ELine connections
+ - Allows for the creation of new and modification of exisiting ELine connections using the map
+ 
+## Interface
+
+![vnaasgui Screenshot](http://i.imgur.com/f4YxuyV.png)
\ No newline at end of file
diff --git a/xos/gui/_DS_Store b/xos/gui/_DS_Store
new file mode 100755
index 0000000..4894909
--- /dev/null
+++ b/xos/gui/_DS_Store
Binary files differ
diff --git a/xos/gui/_dockerignore b/xos/gui/_dockerignore
new file mode 100755
index 0000000..de807ff
--- /dev/null
+++ b/xos/gui/_dockerignore
@@ -0,0 +1,3 @@
+node_modules
+typings
+npm-debug.log
\ No newline at end of file
diff --git a/xos/gui/_gitignore b/xos/gui/_gitignore
new file mode 100755
index 0000000..9b7d448
--- /dev/null
+++ b/xos/gui/_gitignore
@@ -0,0 +1,8 @@
+node_modules/
+dist/
+.tmp/
+.idea/
+.DS_Store
+src/.DS_Store
+typings/
+*.log
\ No newline at end of file
diff --git a/xos/gui/conf/app/README.md b/xos/gui/conf/app/README.md
new file mode 100755
index 0000000..0cfab6e
--- /dev/null
+++ b/xos/gui/conf/app/README.md
@@ -0,0 +1,47 @@
+# XOS-GUI Config
+
+### Note that the configurations defined in this folder are for development only, they are most likely to be overrided by a volume mount defined in `service-profile`
+
+## App Config
+
+This configuration will specifiy the rest API base url and the Websocket address.
+Here is it's structure:
+
+```
+angular.module('app')
+  .constant('AppConfig', {
+    apiEndpoint: '/xos/api',
+    websocketClient: '/'
+  });
+
+```
+
+## Style Config
+
+This configuration will contain branding information, such as title, logo and navigation items.
+Here is it's structure:
+
+```
+angular.module('app')
+  .constant('StyleConfig', {
+    projectName: 'CORD',
+    favicon: 'cord-favicon.png',
+    background: 'cord-bg.jpg',
+    payoff: 'Your VNF orchestrator',
+    logo: 'cord-logo.png',
+    routes: [
+        {
+            label: 'Slices',
+            state: 'xos.core.slices'
+        },
+        {
+            label: 'Instances',
+            state: 'xos.core.instances'
+        },
+        {
+            label: 'Nodes',
+            state: 'xos.core.nodes'
+        }
+    ]
+});
+```
\ No newline at end of file
diff --git a/xos/gui/conf/app/app.config.dev.js b/xos/gui/conf/app/app.config.dev.js
new file mode 100755
index 0000000..1cc2975
--- /dev/null
+++ b/xos/gui/conf/app/app.config.dev.js
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('app')
+  .constant('AppConfig', {
+    apiEndpoint: 'http://xos.dev:3000/api',
+    websocketClient: 'http://xos.dev:3000',
+  });
diff --git a/xos/gui/conf/app/app.config.production.js b/xos/gui/conf/app/app.config.production.js
new file mode 100755
index 0000000..64a2ea1
--- /dev/null
+++ b/xos/gui/conf/app/app.config.production.js
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('vnaasgui')
+  .constant('AppConfig', {
+    apiEndpoint: '/xos/api',
+    websocketClient: '/',
+  });
diff --git a/xos/gui/conf/app/app.config.test.js b/xos/gui/conf/app/app.config.test.js
new file mode 100755
index 0000000..37034fb
--- /dev/null
+++ b/xos/gui/conf/app/app.config.test.js
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('app')
+  .constant('AppConfig', {
+      apiEndpoint: 'http://xos-test:3000/api',
+      websocketClient: 'http://xos-test:3000'
+  });
diff --git a/xos/gui/conf/app/mapconstants.local.js b/xos/gui/conf/app/mapconstants.local.js
new file mode 100755
index 0000000..217b8c0
--- /dev/null
+++ b/xos/gui/conf/app/mapconstants.local.js
@@ -0,0 +1,22 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('app')
+  .constant('MapConfig', {
+    marker: './xos/extensions/vnaasgui/app/img/co.png',
+  });
diff --git a/xos/gui/conf/app/mapconstants.production.js b/xos/gui/conf/app/mapconstants.production.js
new file mode 100755
index 0000000..12c3498
--- /dev/null
+++ b/xos/gui/conf/app/mapconstants.production.js
@@ -0,0 +1,22 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('vnaasgui')
+  .constant('MapConfig', {
+    marker: './extensions/vnaasgui/app/img/co.png',
+  });
diff --git a/xos/gui/conf/app/style.config.cord.js b/xos/gui/conf/app/style.config.cord.js
new file mode 100755
index 0000000..022938b
--- /dev/null
+++ b/xos/gui/conf/app/style.config.cord.js
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('app')
+  .constant('StyleConfig', {
+    projectName: 'CORD',
+    favicon: 'cord-favicon.png',
+    background: 'cord-bg.jpg',
+    payoff: 'Your VNF orchestrator',
+    logo: 'cord-logo.png',
+    routes: [
+        {
+            label: 'Slices',
+            state: 'xos.core.slices'
+        },
+        {
+            label: 'Instances',
+            state: 'xos.core.instances'
+        },
+        {
+            label: 'Nodes',
+            state: 'xos.core.nodes'
+        }
+    ]
+});
diff --git a/xos/gui/conf/app/style.config.opencloud.js b/xos/gui/conf/app/style.config.opencloud.js
new file mode 100755
index 0000000..2c1776e
--- /dev/null
+++ b/xos/gui/conf/app/style.config.opencloud.js
@@ -0,0 +1,32 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+angular.module('app')
+  .constant('StyleConfig', {
+    projectName: 'OpenCloud',
+    favicon: 'opencloud-favicon.png',
+    background: 'opencloud-bg.jpg',
+    payoff: 'Your OS resource manager',
+    logo: 'opencloud-logo.png',
+    routes: [
+        {
+            label: 'Slices',
+            state: 'xos.core.slices'
+        }
+    ]
+});
diff --git a/xos/gui/conf/browsersync-dist.conf.js b/xos/gui/conf/browsersync-dist.conf.js
new file mode 100755
index 0000000..704b46c
--- /dev/null
+++ b/xos/gui/conf/browsersync-dist.conf.js
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const conf = require('./gulp.conf');
+
+module.exports = function () {
+  return {
+    server: {
+      baseDir: [
+        conf.paths.dist
+      ]
+    },
+    open: false
+  };
+};
diff --git a/xos/gui/conf/browsersync.conf.js b/xos/gui/conf/browsersync.conf.js
new file mode 100755
index 0000000..f780a21
--- /dev/null
+++ b/xos/gui/conf/browsersync.conf.js
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const conf = require('./gulp.conf');
+const proxy = require('./proxy');
+
+module.exports = function () {
+    return {
+        server: {
+            baseDir: [
+                conf.paths.tmp,
+                conf.paths.src
+            ],
+            middleware: function (req, res, next) {
+                if (req.url.indexOf('xosapi') !== -1 || req.url.indexOf('xos') !== -1 || req.url.indexOf('socket') !== -1) {
+                    proxy.api.web(req, res);
+                }
+                else {
+                    next();
+                }
+            }
+        },
+        open: false
+    };
+};
\ No newline at end of file
diff --git a/xos/gui/conf/gulp.conf.js b/xos/gui/conf/gulp.conf.js
new file mode 100755
index 0000000..f5e4f2a
--- /dev/null
+++ b/xos/gui/conf/gulp.conf.js
@@ -0,0 +1,56 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+'use strict';
+
+const path = require('path');
+const gutil = require('gulp-util');
+
+exports.ngModule = 'app';
+
+exports.paths = {
+  src: 'src',
+  dist: 'dist/extensions/vnaasgui',
+  appConfig: 'conf/app',
+  tmp: '.tmp',
+  e2e: 'e2e',
+  tasks: 'gulp_tasks'
+
+};
+
+exports.path = {};
+for (const pathName in exports.paths) {
+  if (exports.paths.hasOwnProperty(pathName)) {
+    exports.path[pathName] = function pathJoin() {
+      const pathValue = exports.paths[pathName];
+      const funcArgs = Array.prototype.slice.call(arguments);
+      const joinArgs = [pathValue].concat(funcArgs);
+      return path.join.apply(this, joinArgs);
+    };
+  }
+}
+
+/**
+ *  Common implementation for an error handler of a Gulp plugin
+ */
+exports.errorHandler = function (title) {
+  return function (err) {
+    gutil.log(gutil.colors.red(`[${title}]`), err.toString());
+    this.emit('end');
+  };
+};
diff --git a/xos/gui/conf/karma-auto.conf.js b/xos/gui/conf/karma-auto.conf.js
new file mode 100755
index 0000000..f4ce829
--- /dev/null
+++ b/xos/gui/conf/karma-auto.conf.js
@@ -0,0 +1,79 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const conf = require('./gulp.conf');
+const pkg = require('../package.json');
+
+module.exports = function (config) {
+  const configuration = {
+    basePath: '../',
+    singleRun: false,
+    autoWatch: true,
+    logLevel: 'INFO',
+    junitReporter: {
+      outputDir: 'test-reports'
+    },
+    browsers: [
+      'PhantomJS',
+      // 'Chrome'
+    ],
+    frameworks: [
+      'jasmine',
+      'es6-shim'
+    ],
+    files: [
+      'node_modules/es6-shim/es6-shim.js',
+      conf.path.src('index.spec.js'),
+      conf.path.src('**/*.html')
+    ],
+    preprocessors: {
+      [conf.path.src('index.spec.js')]: [
+        'webpack'
+      ],
+      [conf.path.src('**/*.html')]: [
+        'ng-html2js'
+      ]
+    },
+    ngHtml2JsPreprocessor: {
+      stripPrefix: `${conf.paths.src}/`
+    },
+    reporters: ['mocha', 'coverage'],
+    coverageReporter: {
+      type: 'html',
+      dir: 'coverage/'
+    },
+    webpack: require('./webpack-test.conf'),
+    webpackMiddleware: {
+      noInfo: true
+    },
+    plugins: [
+      require('karma-jasmine'),
+      require('karma-junit-reporter'),
+      require('karma-coverage'),
+      require('karma-phantomjs-launcher'),
+      require('karma-chrome-launcher'),
+      require('karma-phantomjs-shim'),
+      require('karma-ng-html2js-preprocessor'),
+      require('karma-webpack'),
+      require('karma-es6-shim'),
+      require('karma-mocha-reporter')
+    ]
+  };
+
+  config.set(configuration);
+};
diff --git a/xos/gui/conf/karma.conf.js b/xos/gui/conf/karma.conf.js
new file mode 100755
index 0000000..c8bc5f5
--- /dev/null
+++ b/xos/gui/conf/karma.conf.js
@@ -0,0 +1,75 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const conf = require('./gulp.conf');
+
+module.exports = function (config) {
+  const configuration = {
+    basePath: '../',
+    singleRun: true,
+    autoWatch: false,
+    logLevel: 'INFO',
+    junitReporter: {
+      outputDir: 'test-reports'
+    },
+    browsers: [
+      'PhantomJS'
+    ],
+    frameworks: [
+      'jasmine',
+      'es6-shim'
+    ],
+    files: [
+      'node_modules/es6-shim/es6-shim.js',
+      conf.path.src('index.spec.js'),
+      conf.path.src('**/*.html')
+    ],
+    preprocessors: {
+      [conf.path.src('index.spec.js')]: [
+        'webpack'
+      ],
+      [conf.path.src('**/*.html')]: [
+        'ng-html2js'
+      ]
+    },
+    ngHtml2JsPreprocessor: {
+      stripPrefix: `${conf.paths.src}/`
+    },
+    reporters: ['progress', 'coverage'],
+    coverageReporter: {
+      type: 'html',
+      dir: 'coverage/'
+    },
+    webpack: require('./webpack-test.conf'),
+    webpackMiddleware: {
+      noInfo: true
+    },
+    plugins: [
+      require('karma-jasmine'),
+      require('karma-junit-reporter'),
+      require('karma-coverage'),
+      require('karma-phantomjs-launcher'),
+      require('karma-phantomjs-shim'),
+      require('karma-ng-html2js-preprocessor'),
+      require('karma-webpack'),
+      require('karma-es6-shim')
+    ]
+  };
+
+  config.set(configuration);
+};
diff --git a/xos/gui/conf/proxy.js b/xos/gui/conf/proxy.js
new file mode 100755
index 0000000..6e4c84f
--- /dev/null
+++ b/xos/gui/conf/proxy.js
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const httpProxy = require('http-proxy');
+
+const target = process.env.PROXY || '192.168.46.100';
+
+const apiProxy = httpProxy.createProxyServer({
+    target: `http://${target}`
+});
+
+apiProxy.on('error', (error, req, res) => {
+    res.writeHead(500, {
+        'Content-Type': 'text/plain'
+    });
+    console.error('[Proxy]', error);
+});
+
+module.exports = {
+    api: apiProxy
+};
\ No newline at end of file
diff --git a/xos/gui/conf/webpack-dist.conf.js b/xos/gui/conf/webpack-dist.conf.js
new file mode 100755
index 0000000..df5b493
--- /dev/null
+++ b/xos/gui/conf/webpack-dist.conf.js
@@ -0,0 +1,125 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const webpack = require('webpack');
+const conf = require('./gulp.conf');
+const path = require('path');
+
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const pkg = require('../package.json');
+const autoprefixer = require('autoprefixer');
+const BaseHrefWebpackPlugin = require('base-href-webpack-plugin').BaseHrefWebpackPlugin;
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const env = process.env.NODE_ENV || 'production';
+const brand = process.env.BRAND || 'cord';
+
+module.exports = {
+  module: {
+    loaders: [
+      {
+        test: /.json$/,
+        loaders: [
+          'json'
+        ]
+      },
+      {
+        test: /\.(css|scss)$/,
+        loaders: ExtractTextPlugin.extract({
+          fallbackLoader: 'style',
+          loader: 'css?minimize!sass!postcss'
+        })
+      },
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loaders: [
+          'ng-annotate',
+          'ts'
+        ]
+      },
+      {
+        test: /.html$/,
+        loaders: [
+          'html?' + JSON.stringify({
+            attrs: ["img:src", "img:ng-src"]
+          })
+        ]
+      },
+      {
+        test: /\.(png|woff|woff2|eot|ttf|svg|jpg|gif|jpeg)$/,
+        loader: 'url-loader?limit=100000'
+      }
+    ]
+  },
+  plugins: [
+    new CopyWebpackPlugin([
+      { from: `./conf/app/app.config.${env}.js`, to: `app.config.js` },
+      { from: `./conf/app/style.config.${brand}.js`, to: `style.config.js` },
+      { from: `./conf/app/mapconstants.production.js`, to: `mapconstants.js`}
+    ]),
+    new webpack.optimize.OccurrenceOrderPlugin(),
+    new webpack.NoErrorsPlugin(),
+    new HtmlWebpackPlugin({
+      inject: true,
+      template: conf.path.src('index.html')
+    }),
+    new webpack.optimize.UglifyJsPlugin({
+      compress: {unused: true, dead_code: true, warnings: false}, // eslint-disable-line camelcase
+      mangle: false // NOTE mangling was breaking the build
+    }),
+    new ExtractTextPlugin('index-[contenthash].css'),
+    new webpack.optimize.CommonsChunkPlugin({name: 'vendor'}),
+    new webpack.ProvidePlugin({
+      $: "jquery",
+      jQuery: "jquery"
+    }),
+    new BaseHrefWebpackPlugin({
+      baseHref: '/xos/'
+    }),
+  ],
+  postcss: () => [autoprefixer],
+  output: {
+    path: path.join(process.cwd(), conf.paths.dist),
+    publicPath: "/xos/", // enable apache proxying on the head node
+    filename: '[name].js'
+  },
+  resolve: {
+    extensions: [
+      '',
+      '.webpack.js',
+      '.web.js',
+      '.js',
+      '.ts'
+    ],
+      alias: {
+          "ngprogress": path.resolve(__dirname, '../node_modules/ngprogress/build/ngProgress.js')
+      }
+  },
+  entry: {
+    app: `./${conf.path.src('index')}`,
+    vendor: Object.keys(pkg.dependencies)
+  },
+  ts: {
+    configFileName: 'tsconfig.json'
+  },
+  tslint: {
+    configuration: require('../tslint.json')
+  }
+};
+
diff --git a/xos/gui/conf/webpack-test.conf.js b/xos/gui/conf/webpack-test.conf.js
new file mode 100755
index 0000000..c0115ab
--- /dev/null
+++ b/xos/gui/conf/webpack-test.conf.js
@@ -0,0 +1,84 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+module.exports = {
+  module: {
+    preLoaders: [
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loader: 'tslint'
+      }
+    ],
+    loaders: [
+      {
+        test: /.json$/,
+        loaders: [
+          'json'
+        ]
+      },
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loaders: [
+          'ng-annotate',
+          'ts'
+        ]
+      },
+      {
+        test: /.html$/,
+        loaders: [
+          'html?' + JSON.stringify({
+            attrs: ["img:src", "img:ng-src"]
+          })
+        ]
+      },
+      {
+        test: /\.(css|scss)$/,
+        loaders: [
+          'style',
+          'css',
+          'sass',
+          'postcss'
+        ]
+      },
+      {
+        test: /\.(png|woff|woff2|eot|ttf|svg|jpg|gif|jpeg)$/,
+        loader: 'url-loader?limit=100000'
+      }
+    ]
+  },
+  plugins: [],
+  debug: true,
+  devtool: 'source-map',
+  resolve: {
+    extensions: [
+      '',
+      '.webpack.js',
+      '.web.js',
+      '.js',
+      '.ts'
+    ]
+  },
+  ts: {
+    configFileName: 'tsconfig.json'
+  },
+  tslint: {
+    configuration: require('../tslint.json')
+  }
+};
diff --git a/xos/gui/conf/webpack.conf.js b/xos/gui/conf/webpack.conf.js
new file mode 100755
index 0000000..1073ee4
--- /dev/null
+++ b/xos/gui/conf/webpack.conf.js
@@ -0,0 +1,118 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const webpack = require('webpack');
+const conf = require('./gulp.conf');
+const path = require('path');
+
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const autoprefixer = require('autoprefixer');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const env = process.env.NODE_ENV || 'production';
+const brand = process.env.BRAND || 'cord';
+
+module.exports = {
+  module: {
+    preLoaders: [
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loader: 'tslint'
+      }
+    ],
+
+    loaders: [
+      {
+        test: /.json$/,
+        loaders: [
+          'json'
+        ]
+      },
+      {
+        test: /\.(css|scss)$/,
+        loaders: [
+          'style',
+          'css',
+          'sass',
+          'postcss'
+        ]
+      },
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loaders: [
+          'ng-annotate',
+          'ts'
+        ]
+      },
+      {
+        test: /.html$/,
+        loaders: [
+          'html?' + JSON.stringify({
+            attrs: ["img:src", "img:ng-src"]
+          })
+        ]
+      },
+      {
+        test: /\.(png|woff|woff2|eot|ttf|svg|jpg|gif|jpeg)$/,
+        loader: 'url-loader?limit=100000'
+      }
+    ]
+  },
+  plugins: [
+    new CopyWebpackPlugin([
+      { from: `./conf/app/app.config.${env}.js`, to: `app.config.js` },
+      { from: `./conf/app/style.config.${brand}.js`, to: `style.config.js` },
+      { from: `./conf/app/mapconstants.local.js`, to: `mapconstants.js`}
+    ]),
+    new webpack.optimize.OccurrenceOrderPlugin(),
+    new webpack.NoErrorsPlugin(),
+    new HtmlWebpackPlugin({
+      template: conf.path.src('index.html')
+    })
+  ],
+  postcss: () => [autoprefixer],
+  debug: true,
+  devtool: 'source-map',
+  output: {
+    path: path.join(process.cwd(), conf.paths.tmp),
+    filename: 'index.js'
+  },
+  resolve: {
+    extensions: [
+      '',
+      '.webpack.js',
+      '.web.js',
+      '.js',
+      '.ts'
+    ]
+  },
+  entry: `./${conf.path.src('index')}`,
+  ts: {
+    configFileName: 'tsconfig.json'
+  },
+  tslint: {
+    configuration: require('../tslint.json')
+  },
+  stats: {
+    colors: true,
+    modules: true,
+    reasons: true,
+    errorDetails: true
+  }
+};
diff --git a/xos/gui/gulp_tasks/browsersync.js b/xos/gui/gulp_tasks/browsersync.js
new file mode 100755
index 0000000..0e4ada2
--- /dev/null
+++ b/xos/gui/gulp_tasks/browsersync.js
@@ -0,0 +1,39 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const gulp = require('gulp');
+const browserSync = require('browser-sync');
+const spa = require('browser-sync-spa');
+
+const browserSyncConf = require('../conf/browsersync.conf');
+const browserSyncDistConf = require('../conf/browsersync-dist.conf');
+
+browserSync.use(spa());
+
+gulp.task('browsersync', browserSyncServe);
+gulp.task('browsersync:dist', browserSyncDist);
+
+function browserSyncServe(done) {
+  browserSync.init(browserSyncConf());
+  done();
+}
+
+function browserSyncDist(done) {
+  browserSync.init(browserSyncDistConf());
+  done();
+}
diff --git a/xos/gui/gulp_tasks/karma.js b/xos/gui/gulp_tasks/karma.js
new file mode 100755
index 0000000..9955d1a
--- /dev/null
+++ b/xos/gui/gulp_tasks/karma.js
@@ -0,0 +1,45 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const path = require('path');
+
+const gulp = require('gulp');
+const karma = require('karma');
+
+gulp.task('karma:single-run', karmaSingleRun);
+gulp.task('karma:auto-run', karmaAutoRun);
+
+function karmaFinishHandler(done) {
+  return failCount => {
+    done(failCount ? new Error(`Failed ${failCount} tests.`) : null);
+  };
+}
+
+function karmaSingleRun(done) {
+  process.env.NODE_ENV = 'test';
+  const configFile = path.join(process.cwd(), 'conf', 'karma.conf.js');
+  const karmaServer = new karma.Server({configFile}, karmaFinishHandler(done));
+  karmaServer.start();
+}
+
+function karmaAutoRun(done) {
+  process.env.NODE_ENV = 'test';
+  const configFile = path.join(process.cwd(), 'conf', 'karma-auto.conf.js');
+  const karmaServer = new karma.Server({configFile}, karmaFinishHandler(done));
+  karmaServer.start();
+}
diff --git a/xos/gui/gulp_tasks/misc.js b/xos/gui/gulp_tasks/misc.js
new file mode 100755
index 0000000..2c9fbb0
--- /dev/null
+++ b/xos/gui/gulp_tasks/misc.js
@@ -0,0 +1,56 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const path = require('path');
+
+const gulp = require('gulp');
+const del = require('del');
+const filter = require('gulp-filter');
+const rename = require('gulp-rename');
+const replace = require('gulp-replace');
+
+const conf = require('../conf/gulp.conf');
+
+gulp.task('clean', clean);
+gulp.task('other', other);
+
+function clean() {
+  return del([`${conf.paths.dist}/*`, conf.paths.tmp]);
+}
+
+function other() {
+  const fileFilter = filter(file => file.stat.isFile());
+
+  return gulp.src([
+    path.join(conf.paths.src, '/**/*'),
+    path.join(`!${conf.paths.src}`, '/**/*.{scss,ts,html}')
+  ])
+    .pipe(fileFilter)
+    .pipe(gulp.dest(conf.paths.dist));
+}
+
+function other() {
+  const fileFilter = filter(file => file.stat.isFile());
+
+  return gulp.src([
+    path.join(conf.paths.src, '/**/*'),
+    path.join(`!${conf.paths.src}`, '/**/*.{scss,ts,html}')
+  ])
+    .pipe(fileFilter)
+    .pipe(gulp.dest(conf.paths.dist));
+}
diff --git a/xos/gui/gulp_tasks/webpack.js b/xos/gui/gulp_tasks/webpack.js
new file mode 100755
index 0000000..ccb64c0
--- /dev/null
+++ b/xos/gui/gulp_tasks/webpack.js
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const gulp = require('gulp');
+const gutil = require('gulp-util');
+
+const webpack = require('webpack');
+const webpackConf = require('../conf/webpack.conf');
+const webpackDistConf = require('../conf/webpack-dist.conf');
+const gulpConf = require('../conf/gulp.conf');
+const browsersync = require('browser-sync');
+
+gulp.task('webpack:dev', done => {
+  webpackWrapper(false, webpackConf, done);
+});
+
+gulp.task('webpack:watch', done => {
+  webpackWrapper(true, webpackConf, done);
+});
+
+gulp.task('webpack:dist', done => {
+  process.env.NODE_ENV = 'production';
+  webpackWrapper(false, webpackDistConf, done);
+});
+
+function webpackWrapper(watch, conf, done) {
+  const webpackBundler = webpack(conf);
+
+  const webpackChangeHandler = (err, stats) => {
+    if (err) {
+      gulpConf.errorHandler('Webpack')(err);
+    }
+    gutil.log(stats.toString({
+      colors: true,
+      chunks: false,
+      hash: false,
+      version: false
+    }));
+    if (done) {
+      done();
+      done = null;
+    } else {
+      browsersync.reload();
+    }
+  };
+
+  if (watch) {
+    webpackBundler.watch(200, webpackChangeHandler);
+  } else {
+    webpackBundler.run(webpackChangeHandler);
+  }
+}
diff --git a/xos/gui/gulpfile.js b/xos/gui/gulpfile.js
new file mode 100755
index 0000000..7c07882
--- /dev/null
+++ b/xos/gui/gulpfile.js
@@ -0,0 +1,48 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+const gulp = require('gulp');
+const HubRegistry = require('gulp-hub');
+const browserSync = require('browser-sync');
+
+const conf = require('./conf/gulp.conf');
+// const ngConstant = require('gulp-ng-constant');
+
+// Load some files into the registry
+const hub = new HubRegistry([conf.path.tasks('*.js')]);
+
+// Tell gulp to use the tasks just loaded
+gulp.registry(hub);
+
+gulp.task('build', gulp.series(gulp.parallel('other', 'webpack:dist')));
+gulp.task('test', gulp.series('karma:single-run'));
+gulp.task('test:auto', gulp.series('karma:auto-run'));
+gulp.task('serve', gulp.series('webpack:watch', 'watch', 'browsersync'));
+gulp.task('serve:dist', gulp.series('default', 'browsersync:dist'));
+gulp.task('default', gulp.series('clean', 'build'));
+gulp.task('watch', watch);
+
+function reloadBrowserSync(cb) {
+  browserSync.reload();
+  cb();
+}
+
+function watch(done) {
+  gulp.watch(conf.path.tmp('index.html'), reloadBrowserSync);
+  done();
+}
diff --git a/xos/gui/package.json b/xos/gui/package.json
new file mode 100755
index 0000000..1800dfd
--- /dev/null
+++ b/xos/gui/package.json
@@ -0,0 +1,120 @@
+{
+  "version": "3.0.0",
+  "dependencies": {
+    "angular": "1.6.3",
+    "angular-animate": "1.6.3",
+    "angular-cookies": "1.6.3",
+    "angular-resource": "1.6.3",
+    "angular-toastr": "2.1.1",
+    "angular-ui-bootstrap": "2.5.0",
+    "angular-ui-router": "1.0.0-beta.1",
+    "bootstrap": "3.3.7",
+    "bootstrap-sass": "3.3.7",
+    "d3": "3.5.17",
+    "jquery": "3.1.1",
+    "lodash": "4.17.4",
+    "ngmap": "^1.18.4",
+    "ngprogress": "1.1.1",
+    "oclazyload": "1.1.0",
+    "pluralize": "3.1.0",
+    "rxjs": "5.2.0",
+    "socket.io-client": "1.7.3"
+  },
+  "devDependencies": {
+    "angular-mocks": "1.6.4",
+    "autoprefixer": "6.7.7",
+    "babel-eslint": "6.1.2",
+    "babel-loader": "6.4.1",
+    "babel-plugin-istanbul": "2.0.3",
+    "base-href-webpack-plugin": "1.0.0",
+    "bluebird": "^3.5.0",
+    "browser-sync": "2.18.8",
+    "browser-sync-spa": "1.0.3",
+    "copy-webpack-plugin": "4.0.1",
+    "css-loader": "0.23.1",
+    "del": "2.2.2",
+    "es6-shim": "0.35.3",
+    "eslint": "3.19.0",
+    "eslint-config-angular": "0.5.0",
+    "eslint-config-xo-space": "0.12.0",
+    "eslint-loader": "1.7.1",
+    "eslint-plugin-angular": "1.6.4",
+    "eslint-plugin-babel": "3.3.0",
+    "extract-text-webpack-plugin": "2.0.0-beta.3",
+    "file-loader": "0.9.0",
+    "gitbook-cli": "^2.3.0",
+    "gulp": "gulpjs/gulp#4ed9a4a3275559c73a396eff7e1fde3824951ebb",
+    "gulp-angular-filesort": "1.1.1",
+    "gulp-angular-templatecache": "1.9.1",
+    "gulp-filter": "4.0.0",
+    "gulp-htmlmin": "1.3.0",
+    "gulp-hub": "frankwallis/gulp-hub#d461b9c700df9010d0a8694e4af1fb96d9f38bf4",
+    "gulp-insert": "0.5.0",
+    "gulp-ng-annotate": "1.1.0",
+    "gulp-rename": "1.2.2",
+    "gulp-replace": "0.5.4",
+    "gulp-sass": "2.3.2",
+    "gulp-util": "3.0.8",
+    "html-loader": "0.4.5",
+    "html-webpack-plugin": "2.28.0",
+    "http-proxy": "1.16.2",
+    "istanbul-instrumenter-loader": "2.0.0",
+    "jasmine": "2.5.3",
+    "jasmine-jquery": "2.1.1",
+    "jasmine-spec-reporter": "^4.0.0",
+    "json-loader": "0.5.4",
+    "karma": "1.6.0",
+    "karma-angular-filesort": "1.0.2",
+    "karma-chrome-launcher": "2.0.0",
+    "karma-coverage": "1.1.1",
+    "karma-es6-shim": "1.0.0",
+    "karma-jasmine": "1.1.0",
+    "karma-junit-reporter": "1.2.0",
+    "karma-mocha-reporter": "2.2.3",
+    "karma-ng-html2js-preprocessor": "0.2.2",
+    "karma-phantomjs-launcher": "1.0.4",
+    "karma-phantomjs-shim": "1.4.0",
+    "karma-webpack": "1.8.1",
+    "ng-annotate-loader": "0.0.10",
+    "node-sass": "3.13.1",
+    "phantomjs-prebuilt": "2.1.14",
+    "postcss-loader": "0.8.2",
+    "remap-istanbul": "0.9.5",
+    "resolve-url-loader": "1.6.1",
+    "sass-loader": "3.2.3",
+    "style-loader": "0.13.2",
+    "ts-loader": "0.8.2",
+    "tslint": "3.15.1",
+    "tslint-loader": "2.1.5",
+    "typescript": "2.2.2",
+    "typings": "1.5.0",
+    "url-loader": "0.5.8",
+    "webpack": "2.1.0-beta.20"
+  },
+  "scripts": {
+    "postinstall": "npm run typings",
+    "build": "gulp",
+    "start": "gulp serve",
+    "typings": "typings install",
+    "serve:dist": "gulp serve:dist",
+    "serve:dist:watch": "gulp serve:dist:watch",
+    "test": "gulp test",
+    "test:auto": "gulp test:auto",
+    "test:e2e": "protractor conf/protractor.conf.js",
+    "config": "gulp config",
+    "lint": "tslint -c ./tslint.json 'src/**/*.ts'"
+  },
+  "eslintConfig": {
+    "globals": {
+      "expect": true
+    },
+    "root": true,
+    "env": {
+      "browser": true,
+      "jasmine": true
+    },
+    "extends": [
+      "xo-space/esnext"
+    ]
+  }
+}
diff --git a/xos/gui/src/app/components/eline-side.component.html b/xos/gui/src/app/components/eline-side.component.html
new file mode 100755
index 0000000..e0c19f0
--- /dev/null
+++ b/xos/gui/src/app/components/eline-side.component.html
@@ -0,0 +1,64 @@
+
+<!--
+Copyright 2017-present Open Networking Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<div class = "elinepanel">
+  <h1>ELine Overview</h1>
+  <form ng-submit="vm.saveEline(vm.eng.eline)">
+    <div class="form-group" ng-hide="vm.eng.createMode">
+      <label>ID</label><br/>
+      <p>{{vm.eng.eline.id}}</p>
+    </div>
+    <div class="form-group">
+      <label for="name">Name</label>
+      <input required class="form-control" id="name" type="text" ng-value="vm.eng.eline.name" ng-model="vm.eng.eline.name">
+    </div>
+    <div class="form-group" ng-hide="vm.eng.createMode">
+      <label>Backend Status</label><br/>
+      <p>{{vm.eng.eline.backend_status}}</p>
+    </div>
+    <div class="form-group">
+      <label for="cpi1">Connect point 1 ID</label>
+      <input required class="form-control" id="cpi1" type="text" ng-value="vm.eng.eline.connect_point_1_id" ng-model="vm.eng.eline.connect_point_1_id">
+    </div>
+    <div class="form-group">
+      <label for="cpi2">Connect point 2 ID</label>
+      <input required class="form-control" id="cpi2" type="text" ng-value="vm.eng.eline.connect_point_2_id" ng-model="vm.eng.eline.connect_point_2_id">
+    </div>
+    <div class="form-group">
+      <label for="bwps">Bandwidth Profile</label>
+      <select required class="form-control"
+              id="bwps"
+              ng-model="vm.eng.eline.bwp"
+              ng-options="bwp.name as bwp.name for bwp in vm.eng.bwps | orderBy:'name'"
+      >
+      </select>
+    </div>
+    <div class="form-group">
+      <label for="sitename">CORD Site Name</label>
+      <input required class="form-control" id="sitename" type="text" ng-value="vm.eng.eline.cord_site_name" ng-model="vm.eng.eline.cord_site_name">
+    </div>
+    <div class="form-group">
+      <label for="vlanids">Vlan IDs</label>
+      <input required class="form-control" id="vlanids" type="text" ng-value="vm.eng.eline.vlanids" ng-model="vm.eng.eline.vlanids">
+    </div>
+    <div class="form-group" style="text-align: center">
+      <button type="submit" class="btn btn-success btn-block">Save Changes</button>
+    </div>
+  </form>
+  <button type="button" class="btn btn-danger btn-block" ng-click="vm.eng.elinePanel({}, vm.eng.eline, false)">Close</button>
+  <button type="button" class="btn btn-danger delete-eline" ng-click="vm.deleteEline(vm.eng.eline)">Delete Eline</button>
+</div>
\ No newline at end of file
diff --git a/xos/gui/src/app/components/eline-side.component.ts b/xos/gui/src/app/components/eline-side.component.ts
new file mode 100755
index 0000000..fb8a2f1
--- /dev/null
+++ b/xos/gui/src/app/components/eline-side.component.ts
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+let self;
+
+class ElineSide {
+
+  static $inject = ['XosSidePanel', 'XosModelStore', '$http', '$log', 'toastr'];
+
+  constructor(
+    private XosSidePanel: any,
+    private XosModelStore: any,
+    private $http: any,
+    private $log: any,
+    private toastr: any,
+  ) {
+    self = this;
+  }
+
+  public saveEline(item: any) {
+    let path = item.path;
+    delete item.path;
+    item.$save().then((res) => {
+      item.path = path;
+      this.toastr.success(`${item.name} successfully saved!`);
+    })
+      .catch((error) => {
+        this.toastr.error(`Error while saving ${item.name}: ${error.specific_error}`);
+      });
+  }
+
+  public deleteEline(item: any) {
+    let name = item.name;
+    item.$delete().then((res) => {
+      this.toastr.success(`${name} successfully deleted!`);
+    })
+    .catch((error) => {
+        this.toastr.error(`Error while deleting ${name}: ${error.specific_error}`);
+      });
+  }
+
+
+}
+
+export const elineSide: angular.IComponentOptions = {
+  template: require('./eline-side.component.html'),
+  controllerAs: 'vm',
+  controller: ElineSide,
+  bindings: {
+    eng: '='
+  }
+};
diff --git a/xos/gui/src/app/components/engMap.component.html b/xos/gui/src/app/components/engMap.component.html
new file mode 100755
index 0000000..cf85835
--- /dev/null
+++ b/xos/gui/src/app/components/engMap.component.html
@@ -0,0 +1,78 @@
+
+<!--
+Copyright 2017-present Open Networking Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+
+<div class = "row">
+  <div class = "col-xs-12">
+    <h1>Enterprise Network Map</h1>
+    <div map-lazy-load="https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4">
+      <ng-map
+        default-style="false"
+        id="foobar"
+        center="0,0"
+        disable-default-u-i="true"
+        map-type-id="ROADMAP"
+        zoom-control="true"
+        min-zoom="2"
+        styles="{{vm.mapStyles}}"
+      >
+        <!--Markers-->
+        <marker
+          ng-repeat="uni in vm.unis"
+          id="marker-{{uni.id}}"
+          position="{{uni.latlng.toString()}}"
+          icon="{{vm.MapConfig.marker}}"
+          on-click="vm.showUni(uni)"
+        >
+        </marker>
+
+        <!--Marker Info Window-->
+
+        <info-window id = "uni-info">
+          <div class = "marker-info">
+            <h4>{{vm.current_uni.name}}</h4>
+            <p>
+              <b>LatLng: </b>{{vm.current_uni.latlng.toString()}}<br/>
+              <b>Cpe id: </b>{{vm.current_uni.cpe_id}}<br/>
+              <b>Tenant: </b>{{vm.current_uni.tenant}}<br/>
+            </p>
+            <button ng-show="vm.canCreateEline" ng-click="vm.createConnection(vm.current_uni)()">Create connection</button>
+            <button ng-show="!vm.canCreateEline && !uni.eline_start" ng-click="vm.finishConnection(vm.current_uni)">Finish connection</button>
+          </div>
+        </info-window>
+
+        <!--Connections-->
+
+        <shape
+          ng-repeat="eline in vm.elines"
+          name="polyline"
+          id="eline-{{eline.id}}"
+          path="{{eline.path}}"
+          stroke-color="{{vm.colorLine(eline.backend_status)}}"
+          stroke-opacity="1.0"
+          stroke-weight="5"
+          on-click="vm.elinePanel({{eline}}, true)"
+        >
+        </shape>
+
+      </ng-map>
+
+    </div>
+    Changes may not display until page refresh.
+  </div>
+</div>
+<!--"https://maps.googleapis.com/maps/api/js?key=AIzaSyA3rQOp26I5a21VQhwLal8Z1x3XGHjXfm4"-->
\ No newline at end of file
diff --git a/xos/gui/src/app/components/engMap.component.ts b/xos/gui/src/app/components/engMap.component.ts
new file mode 100755
index 0000000..1f726c8
--- /dev/null
+++ b/xos/gui/src/app/components/engMap.component.ts
@@ -0,0 +1,198 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import {NgMap} from 'ngmap';
+import {Subscription} from 'rxjs/Subscription';
+import * as _ from 'lodash';
+
+declare var google;
+
+let self;
+
+export class EngMap {
+
+  static $inject = [
+    'NgMap',
+    'XosModelStore',
+    'AppConfig',
+    '$resource',
+    'XosSidePanel',
+    'XosModelDiscoverer',
+    'ModelRest',
+    'MapConfig',
+  ];
+
+  public unis = [];
+  public elines = [];
+  public cpilatlng = new Map();
+  public paths = [];
+  public bwps = [];
+  public map;
+  public panelOpen = false;
+  public createMode = false;
+  public canCreateEline = true;
+  public eline;
+  public current_uni;
+  public mapStyles = [{'featureType': 'administrative', 'elementType': 'labels.text.fill', 'stylers': [{'color': '#444444'}]}, {'featureType': 'landscape', 'elementType': 'all', 'stylers': [{'color': '#f2f2f2'}]}, {'featureType': 'poi', 'elementType': 'all', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'road', 'elementType': 'all', 'stylers': [{'saturation': -100}, {'lightness': 45}]}, {'featureType': 'road.highway', 'elementType': 'all', 'stylers': [{'visibility': 'simplified'}]}, {'featureType': 'road.arterial', 'elementType': 'labels.icon', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'transit', 'elementType': 'all', 'stylers': [{'visibility': 'off'}]}, {'featureType': 'water', 'elementType': 'all', 'stylers': [{'color': '#9ce1fc'}, {'visibility': 'on'}]}];
+
+  private uniSubscription: Subscription;
+  private elineSubscription: Subscription;
+  private bwpSubscription: Subscription;
+
+  constructor(
+    private NgMap: any,
+    private XosModelStore: any,
+    private AppConfig: any,
+    private $resource: any,
+    private XosSidePanel: any,
+    private XosModelDiscoverer: any,
+    private ModelRest: any,
+    private MapConfig: any,
+  ) {
+    self = this;
+  }
+
+  $onInit() {
+    this.NgMap.getMap().then(map => {
+      this.map = map;
+      this.uniSubscription = this.XosModelStore.query('UserNetworkInterface', '/vnaas/usernetworkinterfaces/').subscribe(
+        res => {
+          this.unis = res;
+          this.renderMap(map);
+        }
+      );
+      this.elineSubscription = this.XosModelStore.query('ELine', '/vnaas/elines/').subscribe(
+        res => {
+          this.elines = res;
+          this.createPaths();
+          this.renderMap(map);
+        }
+      );
+      this.bwpSubscription = this.XosModelStore.query('BandwidthProfile', '/vnaas/bandwidthprofiles/').subscribe(
+        res => {
+          this.bwps = res;
+        }
+      );
+    });
+  }
+
+  $onDestroy() {
+    if (this.uniSubscription) {
+      this.uniSubscription.unsubscribe();
+    }
+  }
+
+  public renderMap(map: NgMap) {
+
+    let bounds = new google.maps.LatLngBounds();
+
+    for (let i = 0; i < self.unis.length; i++) {
+      self.unis[i].eline_start = false;
+      let curr = JSON.parse(self.unis[i].latlng);
+      this.cpilatlng.set(self.unis[i].cpe_id, curr);
+      let latlng = new google.maps.LatLng(curr[0], curr[1]);
+      bounds.extend(latlng);
+    }
+    map.setCenter(bounds.getCenter());
+    map.fitBounds(bounds);
+
+  }
+
+  public createPaths() {
+    this.elines.forEach((eline: any) => {
+      let latlng_start = this.cpilatlng.get(eline.connect_point_1_id);
+      let latlng_end = this.cpilatlng.get(eline.connect_point_2_id);
+      eline.path = [latlng_start, latlng_end];
+    });
+
+  }
+
+  public colorLine(eline_status : any) {
+    let status = parseInt(eline_status, 10);
+    switch (status) {
+      case 0:
+        return '#f39c12';
+      case 1:
+        return '#2ecc71';
+      default:
+        return '#e74c3c';
+    }
+
+  }
+
+  public showUni(e: any, uni: any) {
+    self.current_uni = uni;
+    self.map.showInfoWindow('uni-info', this);
+  }
+
+  // do not display backend status or ID in create mode
+
+  public elinePanel(e: any, eline: any, exists: boolean) {
+    self.panelOpen = !self.panelOpen;
+    if (exists) {
+      self.eline = _.find(self.elines, {id: eline.id});
+    }
+    self.XosSidePanel.toggleComponent('elineSide', {eline: self.eline, bwplist: self.bwps, eng: self}, false);
+    if (!self.panelOpen && self.createMode) {
+      self.createMode = false;
+      self.canCreateEline = true;
+      self.current_uni.eline_start = false;
+    }
+
+  }
+
+  public createConnection(uni: any) {
+    return () => {
+      self.canCreateEline = false;
+      self.createMode = true;
+      uni.eline_start = true;
+      self.current_uni = uni;
+      self.eline = {
+        name: uni.name,
+        uni1name: uni.name,
+        connect_point_1_id: uni.cpe_id,
+      };
+      self.elinePanel({}, self.eline, false);
+    };
+
+  }
+
+  public finishConnection(uni: any) {
+    self.eline.connect_point_2_id = uni.cpe_id;
+    if (self.eline.name === self.eline.uni1name) {
+      self.eline.name = self.eline.name + uni.name;
+    }
+    delete self.eline.uni1name;
+    const resource = this.ModelRest.getResource('/vnaas/elines/');
+    let res = new resource({});
+    for (let attr in self.eline) {
+      if (true) {
+        res[attr] = self.eline[attr];
+      }
+
+    }
+    self.eline = res;
+  }
+
+}
+
+export const engMap: angular.IComponentOptions = {
+  template: require('./engMap.component.html'),
+  controllerAs: 'vm',
+  controller: EngMap,
+};
diff --git a/xos/gui/src/app/img/co.png b/xos/gui/src/app/img/co.png
new file mode 100755
index 0000000..3f07a6a
--- /dev/null
+++ b/xos/gui/src/app/img/co.png
Binary files differ
diff --git a/xos/gui/src/app/style/style.css b/xos/gui/src/app/style/style.css
new file mode 100755
index 0000000..44f2f1b
--- /dev/null
+++ b/xos/gui/src/app/style/style.css
@@ -0,0 +1,41 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+ng-map, [map-lazy-load]{
+    height: 600px;
+    width: 100%;
+}
+
+.marker-info > *{
+    color: #000000;
+}
+
+body > ui-view > xos > div > xos-side-panel > section > div:nth-child(1) {
+    display: none;
+}
+
+.elinepanel{
+    height: 100%;
+}
+
+.delete-eline{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    margin: 10px;
+}
\ No newline at end of file
diff --git a/xos/gui/src/index.html b/xos/gui/src/index.html
new file mode 100755
index 0000000..5d7e99c
--- /dev/null
+++ b/xos/gui/src/index.html
@@ -0,0 +1,37 @@
+
+<!--
+Copyright 2017-present Open Networking Foundation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+
+<!DOCTYPE html>
+<html lang="en" ng-app="vnaasgui">
+<head>
+  <meta charset="UTF-8">
+  <title>vNaaS GUI</title>
+  <link href="/xos/loader.css" rel="stylesheet">
+  <link href="/xos/app.css" rel="stylesheet">
+  <link href="./app/style/style.css" rel="stylesheet">
+</head>
+<body>
+  <div ui-view></div>
+  <script src="/xos/vendor.js"></script>
+  <script src="/xos/app.js"></script>
+  <script src="/xos/loader.js"></script>
+  <script src="/xos/app.config.js"></script>
+  <script src="/xos/style.config.js"></script>
+  <script src="/mapconstants.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/xos/gui/src/index.ts b/xos/gui/src/index.ts
new file mode 100755
index 0000000..5dd1151
--- /dev/null
+++ b/xos/gui/src/index.ts
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/// <reference path="../typings/index.d.ts" />
+import * as angular from 'angular';
+
+import 'angular-ui-router';
+import 'angular-resource';
+import 'angular-cookies';
+
+import 'ngmap';
+
+import routesConfig from './routes';
+import {engMap} from './app/components/engMap.component';
+import {elineSide} from './app/components/eline-side.component';
+
+angular.module('vnaasgui', [
+    'ui.router',
+    'app',
+    'ngMap'
+  ])
+  .config(routesConfig)
+  .component('engMap', engMap)
+  .component('elineSide', elineSide)
+  .run(function(
+    $log: ng.ILogService,
+    $state: ng.ui.IStateService,
+    XosNavigationService: any,
+    XosComponentInjector: any) {
+    $log.info('[vnaasgui] App is running');
+
+    XosNavigationService.add({
+      label: 'vNaaS GUI',
+      state: 'xos.vnaasgui',
+    });
+
+  });
diff --git a/xos/gui/src/routes.ts b/xos/gui/src/routes.ts
new file mode 100755
index 0000000..eb1f5ad
--- /dev/null
+++ b/xos/gui/src/routes.ts
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+export default routesConfig;
+
+function routesConfig($stateProvider: angular.ui.IStateProvider, $locationProvider: angular.ILocationProvider) {
+  $locationProvider.html5Mode(false).hashPrefix('');
+
+  $stateProvider
+    .state('xos.vnaasgui', {
+      url: 'vnaasgui',
+      parent: 'xos',
+      component: 'engMap'
+    });
+}
diff --git a/xos/gui/tsconfig.json b/xos/gui/tsconfig.json
new file mode 100755
index 0000000..c516fb7
--- /dev/null
+++ b/xos/gui/tsconfig.json
@@ -0,0 +1,19 @@
+{
+  "compilerOptions": {
+    "sourceMap": true,
+    "emitDecoratorMetadata": true,
+    "experimentalDecorators": true,
+    "removeComments": false,
+    "noImplicitAny": false
+  },
+  "compileOnSave": false,
+  "include": [
+    "src/**/*.ts",
+    "src/**/*.tsx"
+  ],
+  "exclude": [
+    "typings/**",
+    "conf/app/**",
+    "node_modules"
+  ]
+}
diff --git a/xos/gui/tslint.json b/xos/gui/tslint.json
new file mode 100755
index 0000000..04d33e1
--- /dev/null
+++ b/xos/gui/tslint.json
@@ -0,0 +1,84 @@
+{
+  "rules": {
+    "ban": [true,
+      ["_", "extend"],
+      ["_", "isNull"],
+      ["_", "isDefined"]
+    ],
+    "class-name": true,
+    "comment-format": [true,
+      "check-space"
+    ],
+    "curly": true,
+    "eofline": true,
+    "forin": true,
+    "indent": [true, "spaces"],
+    "interface-name": true,
+    "jsdoc-format": true,
+    "label-position": true,
+    "label-undefined": true,
+    "max-line-length": [false, 140],
+    "member-ordering": [true,
+      "public-before-private",
+      "static-before-instance",
+      "variables-before-functions"
+    ],
+    "no-arg": true,
+    "no-bitwise": true,
+    "no-console": [true,
+      "debug",
+      "info",
+      "time",
+      "timeEnd",
+      "trace",
+      "log",
+      "error"
+    ],
+    "no-construct": true,
+    "no-constructor-vars": false,
+    "no-debugger": true,
+    "no-duplicate-key": true,
+    "no-duplicate-variable": true,
+    "no-empty": true,
+    "no-eval": true,
+    "no-string-literal": false,
+    "no-switch-case-fall-through": true,
+    "trailing-comma": true,
+    "no-trailing-whitespace": true,
+    "no-unused-expression": true,
+    "no-unused-variable": true,
+    "no-unreachable": true,
+    "no-use-before-declare": true,
+    "no-var-requires": true,
+    "one-line": [true,
+      "check-open-brace",
+      "check-catch",
+      "check-whitespace"
+    ],
+    "quotemark": [true, "single"],
+    "radix": true,
+    "semicolon": true,
+    "triple-equals": [true, "allow-null-check"],
+    "typedef": [true,
+      "callSignature",
+      "indexSignature",
+      "parameter",
+      "propertySignature",
+      "variableDeclarator"
+    ],
+    "typedef-whitespace": [true,
+      ["callSignature", "noSpace"],
+      ["catchClause", "noSpace"],
+      ["indexSignature", "space"]
+    ],
+    "use-strict": false,
+    "variable-name": false,
+    "whitespace": [true,
+      "check-branch",
+      "check-decl",
+      "check-operator",
+      "check-separator",
+      "check-type"
+    ]
+  }
+}
diff --git a/xos/gui/typings.json b/xos/gui/typings.json
new file mode 100755
index 0000000..a830275
--- /dev/null
+++ b/xos/gui/typings.json
@@ -0,0 +1,18 @@
+{
+  "globalDependencies": {
+    "angular": "registry:dt/angular#1.5.0+20161208205636",
+    "angular-cookies": "registry:dt/angular-cookies#1.4.0+20160317120654",
+    "angular-mocks": "github:DefinitelyTyped/DefinitelyTyped/angularjs/angular-mocks.d.ts#dc9dabe74a5be62613b17a3605309783a12ff28a",
+    "angular-resource": "registry:dt/angular-resource#1.5.0+20161114123626",
+    "angular-ui-router": "registry:dt/angular-ui-router#1.1.5+20160707113237",
+    "es6-shim": "registry:dt/es6-shim#0.31.2+20160602141504",
+    "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dc9dabe74a5be62613b17a3605309783a12ff28a",
+    "jasmine-jquery": "registry:dt/jasmine-jquery#1.5.8+20161128184045",
+    "jquery": "registry:dt/jquery#1.10.0+20161119044246",
+    "require": "registry:dt/require#2.1.20+20160316155526",
+    "socket.io-client": "registry:dt/socket.io-client#1.4.4+20160317120654"
+  },
+  "dependencies": {
+    "angular-toastr": "registry:dt/angular-toastr#1.6.0+20160708003927"
+  }
+}
diff --git a/xos/macros.m4 b/xos/macros.m4
new file mode 100755
index 0000000..391aafd
--- /dev/null
+++ b/xos/macros.m4
@@ -0,0 +1,100 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Note: Tosca derived_from isn't working the way I think it should, it's not
+#    inheriting from the parent template. Until we get that figured out, use
+#    m4 macros do our inheritance
+
+define(xos_base_props,
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object)
+# Service
+define(xos_base_service_caps,
+            scalable:
+                type: tosca.capabilities.Scalable
+            service:
+                type: tosca.capabilities.xos.Service)
+define(xos_base_service_props,
+            kind:
+                type: string
+                default: generic
+                description: Type of service.
+            view_url:
+                type: string
+                required: false
+                description: URL to follow when icon is clicked in the Service Directory.
+            icon_url:
+                type: string
+                required: false
+                description: ICON to display in the Service Directory.
+            enabled:
+                type: boolean
+                default: true
+            published:
+                type: boolean
+                default: true
+                description: If True then display this Service in the Service Directory.
+            public_key:
+                type: string
+                required: false
+                description: Public key to install into Instances to allows Services to SSH into them.
+            private_key_fn:
+                type: string
+                required: false
+                description: Location of private key file
+            versionNumber:
+                type: string
+                required: false
+                description: Version number of Service.)
+# Subscriber
+define(xos_base_subscriber_caps,
+            subscriber:
+                type: tosca.capabilities.xos.Subscriber)
+define(xos_base_subscriber_props,
+            kind:
+                type: string
+                default: generic
+                description: Kind of subscriber
+            service_specific_id:
+                type: string
+                required: false
+                description: Service specific ID opaque to XOS but meaningful to service)
+define(xos_base_tenant_props,
+            kind:
+                type: string
+                default: generic
+                description: Kind of tenant
+            service_specific_id:
+                type: string
+                required: false
+                description: Service specific ID opaque to XOS but meaningful to service)
+
+# end m4 macros
+
diff --git a/xos/make_synchronizer_manifest.sh b/xos/make_synchronizer_manifest.sh
new file mode 100755
index 0000000..0b16750
--- /dev/null
+++ b/xos/make_synchronizer_manifest.sh
@@ -0,0 +1,18 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+#! /bin/bash
+find synchronizer -type f | cut -b 14- > synchronizer/manifest 
diff --git a/xos/models.py b/xos/models.py
new file mode 100755
index 0000000..f537adc
--- /dev/null
+++ b/xos/models.py
@@ -0,0 +1,158 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from core.models import Tenant
+
+
+class EnterpriseLocation(Tenant):
+
+  KIND = "vnaas"
+
+  class Meta:
+      app_label = "vnaas"
+      name = "vnaas"
+      verbose_name = "Enterprise Location"
+
+  # Primitive Fields (Not Relations)
+  name = CharField( blank = False, max_length = 256, null = False, db_index = False )
+  cord_site_ip = CharField( help_text = "IP of the local site", max_length = 64, null = False, db_index = False, blank = False )
+  cord_site_port = IntegerField( help_text = "Port of the local site", max_length = 256, null = False, db_index = False, blank = False )
+  cord_site_username = CharField( help_text = "Username of the local site", max_length = 64, null = False, db_index = False, blank = False )
+  cord_site_password = CharField( help_text = "Password of the local site", max_length = 64, null = False, db_index = False, blank = False )
+  cord_site_type = CharField( default = "xos", choices = "(('onos', 'ONOS'), ('xos', 'XOS')", max_length = 64, blank = False, null = False, db_index = False )
+
+
+  # Relations
+
+  pass
+
+
+class OnosModel(XOSBase):
+
+  KIND = "vnaas"
+
+  class Meta:
+      app_label = "vnaas"
+      name = "vnaas"
+      verbose_name = "Open Network Operating System"
+
+  # Primitive Fields (Not Relations)
+  name = CharField( blank = False, max_length = 256, null = False, db_index = False )
+  onos_ip = CharField( help_text = "IP of the transport manager", max_length = 64, null = False, db_index = False, blank = False )
+  onos_port = IntegerField( help_text = "Port of the transport manager", max_length = 256, null = False, db_index = False, blank = False )
+  onos_username = CharField( help_text = "Username of the transport manager", max_length = 64, null = False, db_index = False, blank = False )
+  onos_password = CharField( help_text = "Password of the transport manager", max_length = 64, null = False, db_index = False, blank = False )
+  onos_type = CharField( default = "local", choices = "(('local', 'Local'), ('global', 'Global')", max_length = 64, blank = False, null = False, db_index = False )
+
+
+  # Relations
+
+
+  pass
+
+
+class UserNetworkInterface(XOSBase):
+
+  KIND = "vnaas"
+
+  class Meta:
+      app_label = "vnaas"
+      name = "vnaas"
+      verbose_name = "User Network Interface"
+
+  # Primitive Fields (Not Relations)
+  tenant = CharField( help_text = "Tenant name", max_length = 256, null = False, db_index = False, blank = False )
+  cpe_id = CharField( blank = False, max_length = 1024, null = False, db_index = False )
+  latlng = CharField( help_text = "Location, i.e. [37.773972, -122.431297]", max_length = 256, null = False, db_index = False, blank = False )
+  name = CharField( blank = False, max_length = 256, null = False, db_index = False )
+
+
+  # Relations
+
+
+  def __unicode__(self):  return u'%s' % (self.name)
+
+  def save(self, *args, **kwargs):
+
+      if self.latlng:
+          try:
+              latlng_value = getattr(self, 'latlng').strip()
+              if (latlng_value.startswith('[') and latlng_value.endswith(']') and latlng_value.index(',') > 0):
+                  lat = latlng_value[1: latlng_value.index(',')].strip()
+                  lng = latlng_value[latlng_value.index(',') + 1: len(latlng_value) - 1].strip()
+
+                  # If lat and lng are not floats, the code below should result in an error.
+                  lat_validation = float(lat)
+                  lng_validation = float(lng)
+              else:
+                  raise ValueError("The lat/lng value is not formatted correctly.")
+          except:
+              raise ValueError("The lat/lng value is not formatted correctly.")
+
+      super(UserNetworkInterface, self).save(*args, **kwargs)
+  pass
+
+
+
+
+class BandwidthProfile(XOSBase):
+
+  KIND = "vnaas"
+
+  class Meta:
+      app_label = "vnaas"
+      name = "vnaas"
+      verbose_name = "Bandwidth Profile"
+
+  # Primitive Fields (Not Relations)
+  name = CharField( blank = False, max_length = 256, null = False, db_index = False )
+  cbs = IntegerField( help_text = "Committed burst size", null = False, blank = False, db_index = False )
+  ebs = IntegerField( help_text = "Expected burst size", null = False, blank = False, db_index = False )
+  cir = IntegerField( help_text = "Committed information rate", null = False, blank = False, db_index = False )
+  eir = IntegerField( help_text = "Expected information rate", null = False, blank = False, db_index = False )
+
+
+  # Relations
+
+
+  def __unicode__(self):  return u'%s' % (self.name)
+  pass
+
+
+
+class ELine(XOSBase):
+
+  KIND = "vnaas"
+
+  class Meta:
+      app_label = "vnaas"
+      name = "vnaas"
+      verbose_name = "Ethernet Virtual Private Line"
+
+  # Primitive Fields (Not Relations)
+  name = CharField( blank = False, max_length = 256, null = False, db_index = False )
+  connect_point_1_id = CharField( blank = False, max_length = 256, null = False, db_index = False )
+  connect_point_2_id = CharField( blank = False, max_length = 64, null = False, db_index = False )
+  vlanids = TextField( help_text = "comma separated list of vlanIds", null = False, blank = False, db_index = False )
+  cord_site_username = CharField( blank = False, max_length = 64, null = False, db_index = False )
+  bwp = CharField( help_text = "bandwidth profile name", max_length = 256, null = False, db_index = False, blank = False )
+
+
+  # Relations
+
+
+  def __unicode__(self):  return u'%s' % (self.name)
+  pass
+
diff --git a/xos/synchronizer/Dockerfile.synchronizer b/xos/synchronizer/Dockerfile.synchronizer
new file mode 100755
index 0000000..fcbe0ef
--- /dev/null
+++ b/xos/synchronizer/Dockerfile.synchronizer
@@ -0,0 +1,25 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+FROM xosproject/xos-synchronizer-base:candidate
+
+ADD . /opt/xos/synchronizers/vnaas
+
+ENTRYPOINT []
+
+WORKDIR "/opt/xos/synchronizers/vnaas"
+
+CMD bash -c "cd /opt/xos/synchronizers/vnaas; ./run-from-api.sh"
diff --git a/xos/synchronizer/Makefile b/xos/synchronizer/Makefile
new file mode 100755
index 0000000..1c0258d
--- /dev/null
+++ b/xos/synchronizer/Makefile
@@ -0,0 +1,5 @@
+synchronizer:
+	sudo docker build --rm -f Dockerfile.synchronizer -t xosproject/vnaas-synchronizer .
+
+up:
+	docker-compose -p vnaas up -d
\ No newline at end of file
diff --git a/xos/synchronizer/_DS_Store b/xos/synchronizer/_DS_Store
new file mode 100755
index 0000000..719edcd
--- /dev/null
+++ b/xos/synchronizer/_DS_Store
Binary files differ
diff --git a/xos/synchronizer/__init__.py b/xos/synchronizer/__init__.py
new file mode 100755
index 0000000..65fdf5b
--- /dev/null
+++ b/xos/synchronizer/__init__.py
@@ -0,0 +1,17 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+
diff --git a/xos/synchronizer/docker-compose.yml b/xos/synchronizer/docker-compose.yml
new file mode 100755
index 0000000..d24b7b6
--- /dev/null
+++ b/xos/synchronizer/docker-compose.yml
@@ -0,0 +1,38 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+version: '2'
+
+networks:
+  xos:
+    external: true
+
+services:
+  synchronizer:
+    image: xosproject/vnaas-synchronizer
+    networks:
+      - xos
+    #command: bash -c "sleep 86400"
+    volumes:
+        - /opt/cord_profile/node_key:/opt/cord_profile/node_key:ro
+        - /opt/cord/build/platform-install/credentials/xosadmin@opencord.org:/opt/xos/services/vnaas/credentials/xosadmin@opencord.org
+    external_links:
+        - rcordbs_xos_redis_1:redis
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "1000k"
+        max-file: "5"
\ No newline at end of file
diff --git a/xos/synchronizer/manifest b/xos/synchronizer/manifest
new file mode 100755
index 0000000..59df872
--- /dev/null
+++ b/xos/synchronizer/manifest
@@ -0,0 +1,7 @@
+vnaas-synchronizer.py
+__init__.py
+model-deps
+manifest
+steps/sync_vnaaseline.py
+run-from-api.sh
+vnaas_synchronizer_config
diff --git a/xos/synchronizer/model-deps b/xos/synchronizer/model-deps
new file mode 100755
index 0000000..0967ef4
--- /dev/null
+++ b/xos/synchronizer/model-deps
@@ -0,0 +1 @@
+{}
diff --git a/xos/synchronizer/run-from-api.sh b/xos/synchronizer/run-from-api.sh
new file mode 100755
index 0000000..1d69d4f
--- /dev/null
+++ b/xos/synchronizer/run-from-api.sh
@@ -0,0 +1,15 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+python vnaas-synchronizer.py
diff --git a/xos/synchronizer/run_devel.sh b/xos/synchronizer/run_devel.sh
new file mode 100755
index 0000000..bbdf1b6
--- /dev/null
+++ b/xos/synchronizer/run_devel.sh
@@ -0,0 +1,18 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+export XOS_DIR=/opt/xos
+python vnaas-synchronizer-devel.py  -C $XOS_DIR/synchronizers/vnaas/vnaas_synchronizer_config
diff --git a/xos/synchronizer/steps/__init__.py b/xos/synchronizer/steps/__init__.py
new file mode 100755
index 0000000..d4e8062
--- /dev/null
+++ b/xos/synchronizer/steps/__init__.py
@@ -0,0 +1,16 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
diff --git a/xos/synchronizer/steps/sync_vnaaseline.py b/xos/synchronizer/steps/sync_vnaaseline.py
new file mode 100755
index 0000000..4be994b
--- /dev/null
+++ b/xos/synchronizer/steps/sync_vnaaseline.py
@@ -0,0 +1,105 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+import sys
+import requests
+import json
+from synchronizers.new_base.syncstep import SyncStep
+from synchronizers.new_base.modelaccessor import *
+#from xos.logger import Logger, logging
+
+from requests.auth import HTTPBasicAuth
+#logger = Logger(level=logging.INFO)
+
+parentdir = os.path.join(os.path.dirname(__file__), "..")
+sys.path.insert(0, parentdir)
+
+
+class SyncvNaaSEline(SyncStep):
+    provides = [ELine]
+
+    observes = ELine
+
+    requested_interval = 0
+
+    def __init__(self, *args, **kwargs):
+        super(SyncvNaaSEline, self).__init__(*args, **kwargs)
+
+    def get_onos_global_addr(self, onos):
+        #Fetching ip and port from the Global ONOS, append the CE specif API
+
+        onos_url = "http://%s:%s/onos/" % (onos.onos_ip, onos.onos_port)
+        evc_endpoint = "carrierethernet/evc"
+        return onos_url + evc_endpoint
+
+    def get_onos_global_auth(self, onos):
+        #Fetching username and password from the Global ONOS
+
+        return HTTPBasicAuth(onos.onos_username, onos.onos_password)
+
+    def sync_record(self, evc):
+        print "POST %s " % (evc)
+        #logger.info("Syncing Edited EVC: %s" % evc.name)
+        # Fetch the bwp from the DB
+        bwp = BandwidthProfile.objects.get(name=evc.bwp)
+
+        # json to configure ONOS to start the EVC.
+        # {
+        #     "evcId": "evc1",
+        #     "evcCfgId": "evpl1",
+        #     "uniList": [
+        #         "netconf:192.168.56.10:830/0",
+        #         "netconf:192.168.56.20:830/0"
+        #     ],
+        #     "evcType": "POINT_TO_POINT",
+        #     "vlanId": 100,
+        #     "cir": "400",
+        #     "eir": "200",
+        #     "cbs": "3000",
+        #     "ebs": "2000"
+        # }
+
+        data = {}
+        data["evcId"] = evc.name
+        data["evcCfgId"] = evc.name
+        data["uniList"] = [evc.connect_point_1_id, evc.connect_point_2_id]
+        data["evcType"] = "POINT_TO_POINT"
+        data["vlanId"] = evc.vlanids.split(",")
+        data["cbs"] = bwp.cbs
+        data["ebs"] = bwp.ebs
+        data["cir"] = bwp.cir
+        data["eir"] = bwp.eir
+        print "data %s" % data
+        # assuming that the CPEs are controller by the fabric ONOS
+        onos = OnosModel.objects.get(onos_type="global")
+        onos_addr = self.get_onos_global_addr(onos)
+
+        # FIXME - hardcoded auth
+        auth = self.get_onos_global_auth(onos)
+
+        print "POST %s for app %s, data = %s" % (onos_addr, evc.name, data)
+
+        r = requests.post(onos_addr, data=json.dumps(data), auth=auth)
+        #TODO XOS might fail to connect to ONOS.
+        if (r.status_code != 200):
+            print r
+            raise Exception("Received error from EVC Installation update (%d)" % r.status_code)
+
+    def delete_record(self, evc):
+        # TODO evaluate what to in this case.
+        print "Syncing delete EVC: %s" % evc.name
+        #logger.info("Syncing delete EVC: %s" % evc.name)
diff --git a/xos/synchronizer/vnaas-synchronizer.py b/xos/synchronizer/vnaas-synchronizer.py
new file mode 100755
index 0000000..4ced1aa
--- /dev/null
+++ b/xos/synchronizer/vnaas-synchronizer.py
@@ -0,0 +1,32 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+#!/usr/bin/env python
+
+# This imports and runs ../../xos-observer.py
+
+import importlib
+import os
+import sys
+from xosconfig import Config
+
+config_file = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + '/vnaas_config.yaml')
+Config.init(config_file, 'synchronizer-config-schema.yaml')
+
+observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../synchronizers/new_base")
+sys.path.append(observer_path)
+mod = importlib.import_module("xos-synchronizer")
+mod.main()
diff --git a/xos/synchronizer/vnaas_config.yaml b/xos/synchronizer/vnaas_config.yaml
new file mode 100755
index 0000000..0c8fb1e
--- /dev/null
+++ b/xos/synchronizer/vnaas_config.yaml
@@ -0,0 +1,21 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: vnaas-synchronizer
+accessor:
+  username: xosadmin@opencord.org
+  password: "@/opt/xos/services/vnaas/credentials/xosadmin@opencord.org"
+dependency_graph: "/opt/xos/synchronizers/vnaas/model-deps"
+steps_dir: "/opt/xos/synchronizers/vnaas/steps"
+sys_dir: "/opt/xos/synchronizers/vnaas/sys"
diff --git a/xos/tosca/resources/vnaasservice.py b/xos/tosca/resources/vnaasservice.py
new file mode 100755
index 0000000..2799702
--- /dev/null
+++ b/xos/tosca/resources/vnaasservice.py
@@ -0,0 +1,44 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from xosresource import XOSResource
+from service import XOSService
+from services.vnaas.models import *
+
+class XOSvNaaSUNI(XOSResource):
+    provides = "tosca.nodes.UserNetworkInterface"
+    xos_model = UserNetworkInterface
+    copyin_props = ['tenant','vlanIds', 'cpe_id', 'latlng', 'name']
+
+class XOSvNaaSEnterpriseLocation(XOSResource):
+    provides = "tosca.nodes.EnterpriseLocation"
+    xos_model = EnterpriseLocation
+    copyin_props = ['name', 'cord_site_ip', 'cord_site_port', 'cord_site_username', 'cord_site_password', 'cord_site_type']
+
+class XOSvNaaSOnosModel(XOSResource):
+    provides = "tosca.nodes.OnosModel"
+    xos_model = OnosModel
+    copyin_props = ['name', 'onos_ip', 'onos_port', 'onos_username', 'onos_password', 'onos_type']
+
+class XOSvNaaSBandwithProfile(XOSResource):
+    provides = "tosca.nodes.BandwidthProfile"
+    xos_model = BandwidthProfile
+    copyin_props = ['cbs', 'ebs', 'cir', 'eir', 'name']
+
+class XOSvNaaSELine(XOSResource):
+    provides = "tosca.nodes.ELine"
+    xos_model = ELine
+    copyin_props = ['name', 'connect_point_1_id', 'connect_point_2_id', 'vlanids', 'cord_site_name', 'bwp']
\ No newline at end of file
diff --git a/xos/vnaas-onboard.yaml b/xos/vnaas-onboard.yaml
new file mode 100755
index 0000000..28eda72
--- /dev/null
+++ b/xos/vnaas-onboard.yaml
@@ -0,0 +1,37 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard the vNaaS service
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+     vnaas:
+      type: tosca.nodes.ServiceController
+      properties:
+          base_url: file:///opt/xos_services/vnaas/xos/
+          # The following will concatenate with base_url automatically, if
+          # base_url is non-null.
+          xproto: ./
+          synchronizer: synchronizer/manifest
+          synchronizer_run: vnaas-synchronizer.py
+          tosca_resource: tosca/resources/vnaasservice.py
+          tosca_custom_types: vnaas.yaml
+          
\ No newline at end of file
diff --git a/xos/vnaas.m4 b/xos/vnaas.m4
new file mode 100755
index 0000000..aa51536
--- /dev/null
+++ b/xos/vnaas.m4
@@ -0,0 +1,220 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+# compile this with "m4 vnaas.m4 > vnaas.yaml"
+
+# include macros
+include(macros.m4)
+
+node_types:
+
+    tosca.nodes.BandwidthProfile:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The E-CORD bandwidth profile.
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            cbs:
+                type: integer
+                required: false
+            ebs:
+                type: integer
+                required: false
+            cir:
+                type: integer
+                required: false
+            eir:
+                type: integer
+                required: false
+            name:
+                type: string
+                required: true
+
+    tosca.nodes.UserNetworkInterface:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The ecord user netowrk interface
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            cpe_id:
+                type: string
+                required: false
+            tenant:
+                type: string
+                required: true
+            name:
+                type: string
+                required: true
+            latlng:
+                type: string
+                required: false
+
+    tosca.nodes.OnosModel:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The ecord ONOS model
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            name:
+                type: string
+                required: false
+            onos_ip:
+                type: string
+                required: false
+            onos_port:
+                type: integer
+                required: false
+            onos_username:
+                type: string
+                required: false
+            onos_password:
+                type: string
+                required: false
+            onos_type:
+                type: string
+                required: false
+
+    tosca.nodes.EnterpriseLocation:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The ecord enterprise location
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            name:
+                type: string
+                required: false
+            cord_site_ip:
+                type: string
+                required: false
+            cord_site_port:
+                type: integer
+                required: false
+            cord_site_username:
+                type: string
+                required: false
+            cord_site_password:
+                type: string
+                required: false
+            cord_site_type:
+                type: string
+                required: false
+
+    tosca.nodes.ELine:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The ecord Ethernet Virtual Private Line
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            name:
+                type: string
+                required: false
+            connect_point_1_id:
+                type: string
+                required: false
+            connect_point_2_id:
+                type: string
+                required: false
+            vlanids:
+                type: string
+                required: false
+            cord_site_name:
+                type: string
+                required: false
+            bwp:
+                type: string
+                required: false
\ No newline at end of file
diff --git a/xos/vnaas.xproto b/xos/vnaas.xproto
new file mode 100755
index 0000000..e8dce64
--- /dev/null
+++ b/xos/vnaas.xproto
@@ -0,0 +1,58 @@
+option name = "vnaas";
+
+message EnterpriseLocation (XOSBase){
+     option verbose_name = "Enterprise Location";
+
+     required string name = 1 [help_text = "Name for this Enterprise Location", db_index = False, max_length = 256, null = False, blank = False];
+     required string cord_site_ip = 2 [help_text = "IP of the local site", db_index = False, max_length = 64, null = False, blank = False];
+     required int32 cord_site_port = 3 [help_text = "Port of the local site", db_index = False, null = False, blank = False];
+     required string cord_site_username = 4 [help_text = "Username of the local site", db_index = False, max_length = 64, null = False, blank = False];
+     required string cord_site_password  = 5 [help_text = "Password of the local site", db_index = False, max_length = 64, null = False, blank = False];
+     required string cord_site_type = 6 [default = "xos", choices = "(('onos', 'ONOS'), ('xos', 'XOS'))", db_index = False, max_length = 64, null = False, blank = False];
+
+}
+
+message OnosModel (XOSBase){
+     option verbose_name = "Open Network Operating System";
+
+     required string name = 1 [db_index = False, max_length = 256, null = False, blank = False];
+     required string onos_ip = 2 [help_text = "IP of the transport manager", db_index = False, max_length = 64, null = False, blank = False];
+     required int32 onos_port = 3 [help_text = "Port of the transport manager", db_index = False, null = False, blank = False];
+     required string onos_username = 4 [help_text = "Username of the transport manager", db_index = False, max_length = 64, null = False, blank = False];
+     required string onos_password  = 5 [help_text = "Password of the transport manager", db_index = False, max_length = 64, null = False, blank = False];
+     required string onos_type = 6 [default = "local", choices = "(('local', 'Local'), ('global', 'Global'))", db_index = False, max_length = 64, null = False, blank = False];
+
+}
+
+message UserNetworkInterface (XOSBase){
+     option verbose_name = "User Network Interface";
+
+     required string tenant = 1 [help_text = "Tenant name", db_index = False, max_length = 256, null = False, blank = False];
+     required string cpe_id = 2 [db_index = False, max_length = 1024, null = False, blank = False];
+     required string latlng = 3 [help_text = "Location, i.e. [37.773972, -122.431297]", db_index = False, max_length = 256, null = False, blank = False];
+     optional string name = 4 [help_text = "Name for this User Network Interface", db_index = False, max_length = 256, null = False, blank = False];
+}
+
+
+message BandwidthProfile (XOSBase){
+     option verbose_name = "Bandwidth Profile";
+
+     required string name = 1 [help_text = "Name for this Bandwidth Profile", db_index = False, max_length = 256, null = False, blank = False];
+     required int32 cbs = 2 [help_text = "Committed burst size", db_index = False, null = False, blank = False];
+     required int32 ebs = 3 [help_text = "Expected burst size", db_index = False, null = False, blank = False];
+     required int32 cir = 4 [help_text = "Committed information rate", db_index = False, null = False, blank = False];
+     required int32 eir = 5 [help_text = "Expected information rate", db_index = False, null = False, blank = False];
+
+}
+
+message ELine (XOSBase){
+     option verbose_name = "Ethernet Virtual Private Line";
+
+     required string name = 1 [help_text = "Name for this ELine", db_index = False, max_length = 256, null = False, blank = False];
+     required string connect_point_1_id = 2 [help_text = "Cpe_id of the first connection point", db_index = False, max_length = 256, null = False, blank = False];
+     required string connect_point_2_id = 3 [help_text = "Cpe_id of the second connection point", db_index = False, max_length = 64, null = False, blank = False];
+     required string vlanids = 4 [help_text = "Comma separated list of vlanIds", db_index = False, null = False, blank = False];
+     required string cord_site_name = 5 [help_text = "Name of the CORD site", db_index = False, max_length = 64, null = False, blank = False];
+     required string bwp  = 6 [help_text = "Bandwidth profile name", db_index = False, max_length = 256, null = False, blank = False];
+
+}
diff --git a/xos/vnaas.yaml b/xos/vnaas.yaml
new file mode 100644
index 0000000..3b1268a
--- /dev/null
+++ b/xos/vnaas.yaml
@@ -0,0 +1,251 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+# compile this with "m4 vnaas.m4 > vnaas.yaml"
+
+# include macros
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Note: Tosca derived_from isn't working the way I think it should, it's not
+#    inheriting from the parent template. Until we get that figured out, use
+#    m4 macros do our inheritance
+
+
+# Service
+
+
+# Subscriber
+
+
+
+
+# end m4 macros
+
+
+
+node_types:
+
+    tosca.nodes.BandwidthProfile:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The E-CORD bandwidth profile.
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            cbs:
+                type: integer
+                required: false
+            ebs:
+                type: integer
+                required: false
+            cir:
+                type: integer
+                required: false
+            eir:
+                type: integer
+                required: false
+            name:
+                type: string
+                required: true
+
+    tosca.nodes.UserNetworkInterface:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The ecord user netowrk interface
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            cpe_id:
+                type: string
+                required: false
+            tenant:
+                type: string
+                required: true
+            name:
+                type: string
+                required: true
+            latlng:
+                type: string
+                required: false
+
+    tosca.nodes.OnosModel:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The ecord ONOS model
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            name:
+                type: string
+                required: false
+            onos_ip:
+                type: string
+                required: false
+            onos_port:
+                type: integer
+                required: false
+            onos_username:
+                type: string
+                required: false
+            onos_password:
+                type: string
+                required: false
+            onos_type:
+                type: string
+                required: false
+
+    tosca.nodes.EnterpriseLocation:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The ecord enterprise location
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            name:
+                type: string
+                required: false
+            cord_site_ip:
+                type: string
+                required: false
+            cord_site_port:
+                type: integer
+                required: false
+            cord_site_username:
+                type: string
+                required: false
+            cord_site_password:
+                type: string
+                required: false
+            cord_site_type:
+                type: string
+                required: false
+
+    tosca.nodes.ELine:
+        derived_from: tosca.nodes.Root
+        description: >
+            CORD: The ecord Ethernet Virtual Private Line
+        capabilities:
+        properties:
+            no-delete:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to delete this object
+            no-create:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to create this object
+            no-update:
+                type: boolean
+                default: false
+                description: Do not allow Tosca to update this object
+            replaces:
+                type: string
+                required: false
+                descrption: Replaces/renames this object
+            name:
+                type: string
+                required: false
+            connect_point_1_id:
+                type: string
+                required: false
+            connect_point_2_id:
+                type: string
+                required: false
+            vlanids:
+                type: string
+                required: false
+            cord_site_name:
+                type: string
+                required: false
+            bwp:
+                type: string
+                required: false
\ No newline at end of file
